backtest_w_python
Table of Contents
Deathcross
# coding: utf-8 import numpy as np import pandas as pd import talib as ta df = pd.read_csv('Téléchargements/btceur-2h.csv') #df = pd.read_csv('https://raw.githubusercontent.com/brulint/backtesting/main/btceur-2h.csv') # strategy fast = ta.EMA(df['close'], timeperiod = 20) slow = ta.SMA(df['close'], timeperiod = 200) position = fast > slow # returns returns_hodl = np.log(df.close / df.close.shift()) returns_strat = returns_hodl * (position.shift() == 1) returns_netto = returns_strat - 0.0025 * (position != position.shift()) print('Returns: ', np.exp(returns_netto.sum())) # graphs from bokeh.plotting import figure,show from bokeh.layouts import column,row from bokeh.models import DatetimeTickFormatter df['date'] = pd.to_datetime(df['time'], unit='s') xformatter = DatetimeTickFormatter(hours="%H:%M", days="%d/%m", months="%m/%Y", years="%Y") p0 = figure(height=325, width=800) p0.xaxis[0].formatter = xformatter p0.line(df['date'], df['close']) p1 = figure(height=125, width=800, x_range=p0.x_range) p1.xaxis[0].formatter = xformatter p1.line(df['date'], returns_hodl) p2 = figure(height=325, width=800, x_range=p0.x_range) p2.xaxis[0].formatter = xformatter p2.line(df['date'], df['close']) p2.line(df['date'], slow, color='red') p2.line(df['date'], fast, color='green') p3 = figure(height=125, width=800, x_range=p0.x_range) p3.xaxis[0].formatter = xformatter p3.line(df['date'], position) p4 = figure(height=325, width=800, x_range=p0.x_range) p4.xaxis[0].formatter = xformatter p4.line(df['date'], df['close']) p4.triangle(df['date'], df['close'].where((position == 1) & (position.shift() == 0)), color='green', size=7) p4.inverted_triangle(df['date'], df['close'].where((position == 0) & (position.shift() == 1)), color='red', size=7) p5 = figure(height=150, width=800, x_range=p0.x_range) p5.xaxis[0].formatter = xformatter p5.line(df['date'], returns_hodl, color='lightgray') p5.line(df['date'], returns_strat) p6 = figure(height=325, width=800, x_range=p0.x_range) p6.xaxis[0].formatter = xformatter p6.line(df['date'], np.exp(returns_hodl.cumsum()), color='lightgray') p6.line(df['date'], np.exp(returns_strat.cumsum())) p6.line(df['date'], np.exp(returns_netto.cumsum()), color='red') layout = column(p0, p1, p2, p3, p4, p5, p6) show(layout)
Light version
# coding: utf-8 import numpy as np import pandas as pd import talib as ta Donwload data # https://support.kraken.com/hc/en-us/articles/360047124832 names = ['time', 'open', 'high', 'low', 'close', 'volume', 'count'] df = pd.read_csv('XBTEUR_1440.csv', names=names) df = df[int(-10.5*365):] # Only the X last years df['close'] = df.close.replace(to_replace=0, method='ffill') # Strategy begin RSI = ta.RSI(df.close, timeperiod=14) SIG_in = (RSI.shift() < 25) & (RSI > 25) SIG_out = (RSI.shift() > 75) & (RSI < 75) # Strategy end POS = SIG_in.astype(int) - SIG_out.astype(int) POS = POS.replace(to_replace=0, method='ffill') > 0 r_hodl = np.log(df.close / df.close.shift()) r_strat = r_hodl * (POS.shift() == 1) r_netto = r_strat - 0.0025 * (POS != POS.shift()) print('Return: ',np.exp(r_netto.sum())) from bokeh.plotting import figure,show df['time'] = pd.to_datetime(df.time, unit='s') fig = figure(height=300, x_axis_type="datetime") fig.line(df.time, np.exp(r_hodl.cumsum()), color='lightgray') fig.line(df.time, np.exp(r_strat.cumsum()), color='blue') fig.line(df.time, np.exp(r_netto.cumsum()), color='red') show(fig)
Trend following RSI
# coding: utf-8 import numpy as np import pandas as pd import talib as ta df = pd.read_csv('Téléchargements/btceur-2h.csv') #df = pd.read_csv('https://raw.githubusercontent.com/brulint/backtesting/main/btceur-2h.csv') # strategy RSI = ta.RSI(df.close, timeperiod = 14) signal_buy = RSI > 70 signal_sell = RSI < 30 # position signal = signal_buy.astype(int) - signal_sell.astype(int) position = signal.where(signal != 0).ffill() > 0 # returns returns_hodl = np.log(df.close / df.close.shift()) returns_strat = returns_hodl * (position.shift() == 1) returns_netto = returns_strat - 0.0025 * (position != position.shift()) # graphs from bokeh.plotting import figure,show from bokeh.layouts import column,row from bokeh.models import DatetimeTickFormatter df['date'] = pd.to_datetime(df['time'], unit='s') xformatter = DatetimeTickFormatter(hours="%H:%M", days="%d/%m", months="%m/%Y", years="%Y") p1 = figure(height=325, width=800) p1.xaxis[0].formatter = xformatter p1.line(df['date'], df['close']) p11 = figure(height=125, width=800, x_range=p1.x_range) p11.xaxis[0].formatter = xformatter p11.line(df.date, RSI) p11.line(df.date, 70, color='green') p11.line(df.date, 50, color='red') p11.line(df.date, 30, color='green') p2 = figure(height=325, width=800, x_range=p1.x_range) p2.xaxis[0].formatter = xformatter p2.line(df['date'], df['close'], color='gray') p2.triangle(df['date'], df['close'].where((position == 1) & (position.shift() == 0)), color='green', size=7) p2.inverted_triangle(df['date'], df['close'].where((position == 0) & (position.shift() == 1)), color='red', size=7) p3 = figure(height=125, width=800, x_range=p1.x_range) p3.xaxis[0].formatter = xformatter p3.line(df.date, signal) p31 = figure(height=125, width=800, x_range=p1.x_range) p31.xaxis[0].formatter = xformatter p31.line(df['date'], position) p4 = figure(height=150, width=800, x_range=p1.x_range) p4.xaxis[0].formatter = xformatter p4.line(df['date'], returns_hodl, color='lightgray') p4.line(df['date'], returns_strat) p5 = figure(height=325, width=800, x_range=p1.x_range) p5.xaxis[0].formatter = xformatter p5.line(df['date'], np.exp(returns_hodl.cumsum()), color='lightgray') p5.line(df['date'], np.exp(returns_strat.cumsum())) p5.line(df['date'], np.exp(returns_netto.cumsum()), color='red') layout = column(p1, p11, p3, p31, p2, p4, p5) show(layout)
Advanced trend following RSI
# coding: utf-8 import numpy as np import pandas as pd import talib as ta df = pd.read_csv('Téléchargements/btceur-2h.csv') #df = pd.read_csv('https://raw.githubusercontent.com/brulint/backtesting/main/btceur-2h.csv') # strategy RSI = ta.RSI(df.close, timeperiod = 14) signal_long_buy = RSI > 80 signal_long_sell = RSI < 50 signal_short_sell = RSI < 20 signal_short_buy = RSI > 50 # position signal_long = signal_long_buy.astype(int) - signal_long_sell.astype(int) signal_short = signal_short_sell.astype(int) - signal_short_buy.astype(int) position_long = signal_long.where(signal_long != 0).ffill() > 0 position_short = signal_short.where(signal_short != 0).ffill() > 0 position = position_long.astype(int) - position_short.astype(int) # returns returns_hodl = np.log(df.close / df.close.shift()) returns_strat = returns_hodl * position.shift() returns_netto = returns_strat - 0.0025 * (position != position.shift()) # graphic from bokeh.plotting import figure,show from bokeh.layouts import column,row from bokeh.models import DatetimeTickFormatter df['date'] = pd.to_datetime(df.time, unit='s') xformatter = DatetimeTickFormatter(hours="%H:%M", days="%d/%m", months="%m/%Y", years="%Y") p1 = figure(height=325, width=800) p1.xaxis[0].formatter = xformatter p1.line(df.date, df.close) p11 = figure(height=125, width=800, x_range=p1.x_range) p11.xaxis[0].formatter = xformatter p11.line(df.date, RSI) p11.line(df.date, 70, color='green') p11.line(df.date, 50, color='red') p11.line(df.date, 30, color='green') p2 = figure(height=125, width=800, x_range=p1.x_range) p2.xaxis[0].formatter = xformatter p2.line(df.date, position) p3 = figure(height=325, width=800, x_range=p1.x_range) p3.xaxis[0].formatter = xformatter p3.line(df.date, df.close, color='gray') position_long_in = df.close.where((position == 1) & (position.shift() != 1)) position_long_out = df.close.where((position != 1) & (position.shift() == 1)) position_short_in = df.close.where((position == -1) & (position.shift() != -1)) position_short_out = df.close.where((position != -1) & (position.shift() == -1)) p3.triangle(df.date, position_long_in, color='cyan', size=7) p3.inverted_triangle(df.date, position_long_out, color='blue', size=7) p3.inverted_triangle(df.date, position_short_in, color='orange', size=7) p3.triangle(df.date, position_short_out, color='red', size=7) p3.line(df.date, np.where(position == 1, df.close, np.nan), color='green') p3.line(df.date, np.where(position == -1, df.close, np.nan), color='red') p4 = figure(height=150, width=800, x_range=p1.x_range) p4.xaxis[0].formatter = xformatter p4.line(df['date'], returns_hodl, color='lightgray') p4.line(df['date'], returns_strat) p5 = figure(height=325, width=800, x_range=p1.x_range) p5.xaxis[0].formatter = xformatter p5.line(df['date'], np.exp(returns_hodl.cumsum()), color='lightgray') p5.line(df['date'], np.exp(returns_strat.cumsum())) p5.line(df['date'], np.exp(returns_netto.cumsum()), color='red') layout = column(p1, p11, p2, p3, p4, p5) show(layout)
backtest_w_python.txt · Last modified: 2025/03/27 17:02 by bruno