User Tools

Site Tools


backtest_w_python

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
backtest_w_python [2025/02/27 18:48] – created brunobacktest_w_python [2025/03/27 17:02] (current) – [Sinon] bruno
Line 1: Line 1:
- +==== Deathcross ====
-Un vieux code de 2022 (si pas plus). Chrypowatch n'existe plus, c'est dire :-)+
  
 <code python> <code python>
 # coding: utf-8 # coding: utf-8
-import requests 
 import numpy as np import numpy as np
 import pandas as pd import pandas as pd
-  +import talib as ta
-import talib +
-  +
-url = 'https://api.cryptowat.ch/markets/kraken/btceur/ohlc' +
-ohlc = requests.get(url).json()['result'][str(12*60*60)] +
-columns = ['time','open','high','low','close','volume','count'+
-df = pd.DataFrame(ohlc, columns=columns).astype(float) +
-df = df.iloc[-1000:]+
  
-df['RSI'talib.RSI(df['close'], timeperiod=14) +df = pd.read_csv('Téléchargements/btceur-2h.csv') 
-#df['RSI'] = df.RSI.fillna(value=df.RSI.loc[14]) +#df = pd.read_csv('https://raw.githubusercontent.com/brulint/backtesting/main/btceur-2h.csv')
-df['long'] = talib.SMA(df.close, timeperiod=200+
-#df['long'df.long.fillna(value=df.long.loc[200]) +
-df['short'] = talib.SMA(df.close,timeperiod=14) +
-#df['short'] = df.short.fillna(value=df.short.loc[14]) +
-df['trend'] = df.long < df.short +
-# signal +
-df['sig_in'] = (df.RSI > 60) & df.trend +
-df['sig_out'] = (df.RSI < 40)# | 1-df.trend +
-#df['sig_in'] = (df.RSI.shift() < 70) & (df.RSI > 70) +
-#df['sig_out'] = (df.RSI.shift() > 30) & (df.RSI < 30) +
-#df['sig_in'] = (df.RSI.shift() < 25) & (df.RSI > 25) +
-#df['stoploss'] = df.low.rolling(5).min().where(df.sig_in==1).ffill() +
-#df['sig_out'] = ((df.RSI.shift() > 75) & (df.RSI < 75)) | ((df.RSI.shift()>25) & (df.RSI<25)) | (df.close < df.stoploss)+
  
-#df['signal'df.sig_in.where(df.sig_in).fillna(1-df.sig_out.where(df.sig_out)).ffill() +strategy 
-#df['sig_out'].loc[0] True +fast ta.EMA(df['close'], timeperiod 20) 
-#df['signal'] = (1-df.sig_out.where(df.sig_out)).fillna(df.sig_in.where(df.sig_in)).ffill()# * df.trend +slow = ta.SMA(df['close'], timeperiod 200)
  
-df['sig_0'] = df.sig_in.astype(intdf.sig_out.astype(int+position = fast > slow 
-df['sig_1'] = df.sig_0.where(df.sig_0!=0).ffill() + 
-df['signal'] = df.sig_1 > +# returns 
-Rendements+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) 
 +</code> 
 + 
 +=== Light version === 
 + 
 +<code python> 
 +# 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') df['close'] = df.close.replace(to_replace=0, method='ffill')
-df['r_0'= df.close / df.close.shift() + 
-df['r_strat'np.where(df.signal.shift(), df.r_0, 1+# Strategy begin 
-df['r_fee'] = np.where(df.signal.shift() df.signal == 11-0.00251+RSI = ta.RSI(df.close, timeperiod=14) 
-# tronquage datafame +SIG_in = (RSI.shift() < 25) & (RSI > 25) 
-#df = df.iloc[-700:] +SIG_out = (RSI.shift() > 75) & (RSI < 75) 
-Rendement cumulé +# Strategy end 
-df['R_net'= (df.r_strat * df.r_fee).cumprod() + 
-Graphiques+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.timenp.exp(r_netto.cumsum())color='red'
 +show(fig) 
 + 
 +</code> 
 + 
 +==== Trend following RSI ==== 
 + 
 +<code python> 
 + 
 +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.plotting import figure,show
 from bokeh.layouts import column,row from bokeh.layouts import column,row
-p1 = figure(height=300,width=800) +from bokeh.models import DatetimeTickFormatter 
-p1.line(df.time,df.close) + 
-#p1.line(df.time,df.long,color='green') +df['date'] = pd.to_datetime(df['time']unit='s') 
-#p1.line(df.time,df.short,color='red'+xformatter = DatetimeTickFormatter(hours="%H:%M"days="%d/%m"months="%m/%Y", years="%Y"
-p2  figure(height=100,width=800,x_range=p1.x_range) + 
-p2.line(df.time,df.RSI+p1 = figure(height=325, width=800
-#p3_0 = figure(height=100,width=800,x_range=p1.x_range) +p1.xaxis[0].formatter = xformatter 
-#p3_0.line(df.time,df.trend+p1.line(df['date'], df['close']
-p3_1 = figure(height=100,width=800,x_range=p1.x_range+ 
-p3_1.line(df.time,df.sig_in,color='green'+p11 = figure(height=125, width=800, x_range=p1.x_range) 
-p3_2 = figure(height=100,width=800,x_range=p1.x_range) +p11.xaxis[0].formatter = xformatter 
-p3_2.line(df.time,df.sig_out,color='red') +p11.line(df.dateRSI
-p3_3 figure(height=100,width=800,x_range=p1.x_range+p11.line(df.date70color='green'
-p3_3.line(df.time,df.sig_0+p11.line(df.date50, color='red'
-p3_3_2 = figure(height=100,width=800,x_range=p1.x_range)  +p11.line(df.date, 30, color='green'
-p3_3_2.line(df.time,df.sig_1+ 
-p3_4 = figure(height=100,width=800,x_range=p1.x_range) +p2 = figure(height=325, width=800, x_range=p1.x_range) 
-p3_4.line(df.time,df.signal+p2.xaxis[0].formatter = xformatter 
-p4 = figure(height=150,width=800,x_range=p1.x_range) +p2.line(df['date'], df['close'], color='gray') 
-p4.line(df.time,df.r_0,color='lightgray'+p2.triangle(df['date'], df['close'].where((position == 1) & (position.shift() == 0))color='green'size=7
-p4.line(df.time,df.r_strat) +p2.inverted_triangle(df['date'], df['close'].where((position == 0& (position.shift() == 1)), color='red', size=7) 
-p4.line(df.time,df.r_fee,color='red') + 
-p5 = figure(height=300,width=800,x_range=p1.x_range) +p3 = figure(height=125, width=800, x_range=p1.x_range) 
-p5.line(df.time,df.r_0.cumprod(),color='lightgray'+p3.xaxis[0].formatter = xformatter 
-p5.line(df.time,df.r_strat.cumprod()) +p3.line(df.datesignal
-p5.line(df.time,df.R_net,color='red'+ 
-layout = column(p1,p2,p3_1,p3_2,p3_3,p3_3_2,p3_4,p4,p5)+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, p11p3p31p2, p4, p5)
 show(layout) show(layout)
 +
 </code> </code>
 +
 +
 +==== Advanced trend following RSI ====
 +<code python>
 +# 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)
 +
 +</code>
 +
 +
 +
 +
 +
backtest_w_python.1740682083.txt.gz · Last modified: 2025/02/27 18:48 by bruno