Untitled
unknown
plain_text
a month ago
4.9 kB
4
Indexable
Never
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()
Leave a Comment