You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to optimize the sharpe ratio calculated based on daily arithmetric return rather than return based on trade. Though I believe I managed to do that successfully, it seems that I need to calculate that dynamically with next() inside the strategy. As per what I read in other discussion, it is not recommended as it can be very slow. Any other recommendation to handle this?
Thanks!
'''
Arithmetric return on each day
Default to close price change but will be set to 0 if there is no position
'''
def arith_return(p_values, n):
_a = pd.Series(p_values).pct_change()
_a.iloc[:(n-1)] = 0
return _a
'''
Cumulative arithmetric return for benchmark and
empty series to store cumulative arithmetric return
'''
def arith_cum_return(p_values, n):
_bm = pd.Series(p_values).pct_change().cumsum()
_blank = _bm.copy()
_blank.iloc[:] = 0
return _bm, _blank
'''
Buy when the difference between price and sma > threshold
Short when the difference < - threshold
'''
class SmaDiff(Strategy):
n_sma = 70 # look back windows for MA
th_diff = 0.125 # threshold for MA diff
def init(self):
self.sma = self.I(sma, self.data.Close, self.n_sma)
self.maDiff = self.I(ma_diff, self.data.Close, self.n_sma, plot=True)
self.pnl = self.I(arith_return, self.data.Close, self.n_sma, plot=False) # placeholder for arithmetric return
self.cum = self.I(arith_cum_return, self.data.Close , self.n_sma, plot=True) # placeholder for arithmetric cumulative return
def next(self):
'''
Trade with fixed amount
'''
_price = self.data.Close[-1]
_size = ORDER_SIZE // _price
'''
Calculate arithmetic return and cumulative return
'''
if self.position.size == 0:
self.pnl[-1] = 0
elif self.position.size < 0:
self.pnl[-1] = -self.pnl[-1]
'''
cum[0] is cumulative return for benchmark and
cum[1] is empty series to store calculated cumulative return for strategy based on return on that day
'''
self.cum[1][-1] = self.cum[1][-2] + self.pnl[-1]
if self.maDiff > self.th_diff:
if self.position.size == 0:
self.buy(size=_size)
elif self.maDiff < -self.th_diff:
if self.position.size == 0:
self.sell(size=_size)
else:
self.position.close()
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi,
I am trying to optimize the sharpe ratio calculated based on daily arithmetric return rather than return based on trade. Though I believe I managed to do that successfully, it seems that I need to calculate that dynamically with next() inside the strategy. As per what I read in other discussion, it is not recommended as it can be very slow. Any other recommendation to handle this?
Thanks!
'''
Arithmetric return on each day
Default to close price change but will be set to 0 if there is no position
'''
def arith_return(p_values, n):
_a = pd.Series(p_values).pct_change()
_a.iloc[:(n-1)] = 0
return _a
'''
Cumulative arithmetric return for benchmark and
empty series to store cumulative arithmetric return
'''
def arith_cum_return(p_values, n):
_bm = pd.Series(p_values).pct_change().cumsum()
_blank = _bm.copy()
_blank.iloc[:] = 0
return _bm, _blank
'''
Buy when the difference between price and sma > threshold
Short when the difference < - threshold
'''
class SmaDiff(Strategy):
n_sma = 70 # look back windows for MA
th_diff = 0.125 # threshold for MA diff
df contains the ohlc data
bt = Backtest(df, SmaDiff, cash=CAPITAL, trade_on_close=True)
stats = bt.run()
sharpe_ratio = lambda s: s._strategy.pnl.mean() / s._strategy.pnl.std() * (365 ** 0.5)
stats, heatmap = bt.optimize(
n_sma=range(20, 100, 8),
th_diff=np.linspace(0.0, 0.2, 8).tolist(),
maximize=sharpe_ratio,
return_heatmap=True)
Beta Was this translation helpful? Give feedback.
All reactions