Closed webbuilderhero closed 1 year ago
Hi, thx for the suggestion. I can definitely understand that it is still a bit difficult to understand everything. I am working on it, but there is still a long way.
Basically, for 80% of what you write should go in core/indicator, where the vector calculations are performed. You can have a look at VBTSUPERTREND, it was coded directly by vbt author. The indicator uses normally only numpy functions to be faster. So it performs on each symbol separately. But of course, you could do a fit of post processing with pandas, if you want.
To download historical data, go in core/data_manager. all_symbols=constants.NYSE index="^GSPC" It will save two files in core: actions (so here the NYSE prices) and index (^GSPC). I see here, the first small issue. Vbt does not seem to implement the column "Adj Close". Let's use "Close" instead.
My bot is also design to perform automatic orders depending on clear signal. Not to plot curve, that you need to read manually.
I will try to implement your strategy. I cannot promess, in which month to be honest. I am in the middle of a total reworking of the core of the code, it will take me a while.
I wrote it, but I cannot see how to decide which order. Also the wavelet is not used? Actually the return calculation and so on is taken care by vbt. You just need to define the entries and exits. I suppose it related to equity_curve != NaN ?
I have a simple strat boilerplate im using for quant im wondering if you can port it over to your framework so I can use my strats on your bot. I am having a hard time grasping everything going on with your setup. import pandas as pd import yfinance as yf import numpy as np import matplotlib.pyplot as plt from scipy.signal import morlet
Download historical data for S&P 500 from Yahoo Finance
df = yf.download('^GSPC', start='2010-01-01', end='2023-06-23')
Use adjusted close prices
df['close'] = df['Adj Close']
Apply discrete Morlet wavelet transform
def wavelet_transform(signal, window_size): wavelet = morlet(window_size, 5) transformed_signal = np.convolve(signal, wavelet, mode='same') return transformed_signal
df['wavelet'] = wavelet_transform(df['close'], window_size=51)
Calculate differences to identify up and down movements
df['price_diff'] = df['close'].diff()
Separate into monotonic states
df['up'] = df['price_diff'].clip(lower=0) df['down'] = df['price_diff'].clip(upper=0) * -1
Initialize columns for normalized up and down movements
df['up_norm'] = 0.0 df['down_norm'] = 0.0
Compute ranks using the entire price data
df['up_norm'] = df['up'].rank(pct=True) df['down_norm'] = df['down'].rank(pct=True)
Calculate log returns
df['log_returns'] = np.log(df['close']).diff()
Define position sizing model
positionSizingModel = 'percentage' # Choose the position sizing model ('percentage', 'fixed_ratio', 'secure_f', 'margin_based')
Position sizing parameters
accountEquity = 100000 # Account equity riskPercentage = 1.5 # Risk percentage per trade stopLossPips = 250 # Stop loss in pips percentageVolatility = 2.5 # Percentage volatility model fixedRatio = 0.02 # Fixed ratio model secureF = 0.01 # Secure (f) model marginBasedSize = 0.01 # Margin-based size model
Calculate position size
contractSize = 5000
accountSize = accountEquity * riskPercentage / 100.0
if positionSizingModel == 'percentage': positionSize = accountSize percentageVolatility / (stopLossPips contractSize) elif positionSizingModel == 'fixed_ratio': positionSize = accountEquity fixedRatio / (stopLossPips contractSize) elif positionSizingModel == 'secure_f': positionSize = accountEquity secureF / (stopLossPips contractSize) elif positionSizingModel == 'margin_based': margin = accountEquity * marginBasedSize positionSize = margin / stopLossPips
print("Position Size:", positionSize)
Define trading logic
df['position_size'] = np.where(df['up_norm'] > 0.95, positionSize, np.where(df['down_norm'] > 0.95, -positionSize, np.nan)) df['position_size'] = df['position_size'].fillna(method='ffill')
Compute returns
df['returns'] = df['log_returns'] * df['position_size']
Calculate equity curve
df['equity_curve'] = (df['returns'] + 1).cumprod() * accountEquity
Plot equity curve with 'Close' price
fig, ax1 = plt.subplots(figsize=(10, 5))
ax1.plot(df.index, df['equity_curve'], color='blue', label='Equity Curve') ax1.set_xlabel('Date') ax1.set_ylabel('Equity', color='blue') ax1.set_title('Equity Curve and Close Price') ax1.tick_params('y', colors='blue')
ax2 = ax1.twinx() ax2.plot(df.index, df['close'], color='red', label='Close Price') ax2.set_ylabel('Close Price', color='red') ax2.tick_params('y', colors='red')
fig.tight_layout()
Add legend
lines_1, labels_1 = ax1.get_legend_handles_labels() lines_2, labels_2 = ax2.get_legend_handles_labels() lines = lines_1 + lines_2 labels = labels_1 + labels_2 plt.legend(lines, labels)
plt.show()