Untitled
unknown
plain_text
a year ago
4.9 kB
21
Indexable
import os
import vectorbtpro as vbt
from numba import njit
import numpy as np
import talib
# Define the symbols and date range
symbols = {'BTC-USD': 'Bitcoin', 'TSLA': 'Tesla'}
start_date = '2024-08-01'
end_date = '2024-08-20'
# Define the range of parameters for Supertrend
periods = list(range(5, 51)) # Periods from 5 to 50 with an increment of 1
multipliers = [round(x * 0.01, 2) for x in range(50, 301, 1)] # Multiplier from 0.5 to 3.0 with an increment of 0.01
# Define the Supertrend logic using Numba and VectorBT's IndicatorFactory
@njit
def get_final_bands_nb(close, upper, lower):
trend = np.full(close.shape, np.nan)
dir_ = np.full(close.shape, 1)
long = np.full(close.shape, np.nan)
short = np.full(close.shape, np.nan)
for i in range(1, close.shape[0]):
if close[i] > upper[i - 1]:
dir_[i] = 1
elif close[i] < lower[i - 1]:
dir_[i] = -1
else:
dir_[i] = dir_[i - 1]
if dir_[i] > 0 and lower[i] < lower[i - 1]:
lower[i] = lower[i - 1]
if dir_[i] < 0 and upper[i] > upper[i - 1]:
upper[i] = upper[i - 1]
if dir_[i] > 0:
trend[i] = long[i] = lower[i]
else:
trend[i] = short[i] = upper[i]
return trend, dir_, long, short
def get_basic_bands(med_price, atr, multiplier):
matr = multiplier * atr
upper = med_price + matr
lower = med_price - matr
return upper, lower
def faster_supertrend_talib(high, low, close, period=7, multiplier=3):
avg_price = talib.MEDPRICE(high, low)
atr = talib.ATR(high, low, close, period)
upper, lower = get_basic_bands(avg_price, atr, multiplier)
return get_final_bands_nb(close, upper, lower)
# Create the SuperTrend indicator using IndicatorFactory
SuperTrend = vbt.IF(
class_name='SuperTrend',
short_name='st',
input_names=['high', 'low', 'close'],
param_names=['period', 'multiplier'],
output_names=['supert', 'superd', 'superl', 'supers']
).with_apply_func(
faster_supertrend_talib,
takes_1d=True,
period=7,
multiplier=3
)
# Loop through each symbol
for symbol, name in symbols.items():
# Format the filename with start and end month/year
filename = f'{name}_{start_date}_to_{end_date}_daily.csv'
# Check if the file already exists
# if os.path.exists(filename):
# print(f"File {filename} already exists. Skipping download for symbol {symbol}.")
# else:
# # Download the data using YahooFinanceData
# yahoo_data = vbt.YFData.pull(symbol, tz="EDT", start=start_date, end=end_date)
# # Save the data to a CSV file
# yahoo_data.to_csv(filename)
# print(f"Downloaded and saved data to {filename}.")
# Load the data from the CSV file using vectorbtpro
data = vbt.Data.from_csv(filename)
# Run the SuperTrend indicator with all combinations of periods and multipliers
supertrend = SuperTrend.run(
data['High'], data['Low'], data['Close'],
period=periods, multiplier=multipliers,
param_product=True
)
# Generate signals based on Supertrend crossover
entries = supertrend.superd == 1
exits = supertrend.superd == -1
# Run backtests with advanced portfolio management features
portfolio = vbt.Portfolio.from_signals(
data['Close'],
entries,
exits,
init_cash=100_000,
fees=0.001, # Example trading fees
slippage=0.001, # Example slippage
freq='1D',
parallel=True # Enable parallel processing for faster backtesting
)
# Retrieve and display comprehensive performance metrics
metrics = {
'Total Return (%)': portfolio.total_return() * 100,
'Win Rate (%)': portfolio.win_rate() * 100,
'Sharpe Ratio': portfolio.sharpe_ratio(),
'Max Drawdown (%)': portfolio.max_drawdown() * 100,
'Net Profit ($)': portfolio.net_profit(),
'Net Profit (%)': portfolio.net_profit(return_pct=True) * 100,
}
metrics_df = vbt.DataFrame(metrics, index=[symbol])
print(f"\nMetrics for {name}:")
print(metrics_df)
# Save the results to a CSV file
metrics_df.to_csv(f'{name}_supertrend_backtest_results_pro.csv')
# Plot the results
portfolio.plot().show()
# Compare against Buy and Hold strategy
buy_and_hold = vbt.Portfolio.from_holding(data['Close'], init_cash=100_000, freq='1D')
# Calculate and print performance metrics for Buy and Hold
print(f"\nBuy and Hold Performance for {name}:")
print(buy_and_hold.stats())
# Optionally, plot the comparison
portfolio['returns'].vbt.plot(trace_kwargs=dict(name=f'{name} Strategy Returns')).show()
buy_and_hold['returns'].vbt.plot(trace_kwargs=dict(name=f'{name} Buy and Hold Returns')).show()
Editor is loading...
Leave a Comment