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 didn't see stop loss or trailing stop loss functionality anywhere so I tried implementing it myself. The stop loss was easy but the trailing stop loss took a little work. I figured I'd post here so that other people might benefit.. or maybe other people can tell me where I messed up!
Would love feedback on these.
Thanks,
Brett
import pandas as pd
import numpy as np
%matplotlib inline
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', None)
# Set trading fees
def trading_fees(q, p):
return abs(q)*p*0.003
# Simple moving average backtest
def sma_strat(tickers, sma_per=50, start='2018-01-01', name='sma', initial_capital=1000.0, stop_pct=None, trailing=None):
"""
Long securities that are above their n period.
"""
# download data
data = bt.get(tickers, start=start)
# calc sma
sma = data.rolling(sma_per).mean()
signals = sma.copy()
signals[data > sma] = True
signals[data <= sma] = False
signals[sma.isnull()] = False
if stop_pct is not None:
if trailing:
# Use a trailing stop loss
for ticker in data:
df = pd.DataFrame()
df['price'] = data[ticker]
df['signal_change'] = signals[ticker].ne(signals[ticker].shift())
df['trade_id'] = df['signal_change'].cumsum()
df['trailing_stop_loss'] = df.groupby('trade_id')['price'].cummax() * (1 - stop_pct)
signals.loc[df['price'] <= df['trailing_stop_loss'], ticker] = False
else:
# Use a stop loss
stop_loss = (data*(1-stop_pct)).where((signals.shift(1) == False) & (signals == True), np.nan)
stop_loss = stop_loss.ffill()
signals[data <= stop_loss] = False
tw = signals.copy()
tw[signals == True] = 1.0 / len(tickers)
tw[signals == False] = 0.0
# create strategy
s = bt.Strategy(name, [bt.algos.WeighTarget(tw),
bt.algos.Rebalance()])
# now we create the backtest
return bt.Backtest(s, data, integer_positions=False, initial_capital=initial_capital, commissions=trading_fees)
# Params
start = '2018-01-01'
initial_capital=1000.0
tickers = ['BTC-USD', 'ETH-USD']
sma = sma_strat(tickers, sma_per=50, start=start, name='sma', initial_capital=initial_capital)
sma_stop = sma_strat(tickers, sma_per=50, start=start, name='sma_stop', initial_capital=initial_capital, stop_pct=0.05)
sma_trailing_stop = sma_strat(tickers, sma_per=50, start=start, name='sma_trailing_stop', initial_capital=initial_capital, stop_pct=0.05, trailing=True)
# run all the backtests!
results = bt.run(sma, sma_stop, sma_trailing_stop)
results.plot(freq='m', logy=True);
results.display()
The text was updated successfully, but these errors were encountered:
Ive spent more time on this and the trailing stop loss is definitely busted. I've managed to build one using a loop but the one above has issues.
You should avoid using a for loop and try to find a vector-based solution since you're working in Pandas. Looping through each ticker in the universe is going to be extremely inefficient.
Let me know if you ever made any progress on this btw.
Hi all,
I didn't see stop loss or trailing stop loss functionality anywhere so I tried implementing it myself. The stop loss was easy but the trailing stop loss took a little work. I figured I'd post here so that other people might benefit.. or maybe other people can tell me where I messed up!
Would love feedback on these.
Thanks,
Brett
The text was updated successfully, but these errors were encountered: