Donchian Channel(DC) and Super Trend back testing with python(Part-1)

vamsi krishna
3 min readMar 13, 2021
Donchian Channel(DC) and Super Trend

About DC — https://en.wikipedia.org/wiki/Donchian_channel

About Super Trend — https://investobull.com/what-is-super-trend-indicator-and-how-to-use-it/

Here I am going to explain DC-super trend back testing with python.

Donchian Channel(DC) formula:

upper channel = highest high of last N-periods

lower channel = lowest low of last N-periods

middle channel =( (upper channel + lower channel)/2)

python code:

#donchan channel 20candles period
N = 20
df['upper_channel'] = np.nan
df['lower_channel'] = np.nan
df['middle_channel'] = np.nan
df['upper_channel'] = df['High'].rolling(N).max().shift(N-20)
df['lower_channel'] = df['Low'].rolling(N).min().shift(N-20)
df['middle_channel'] = ((df['upper_channel']+df['lower_channel'])/2)

super trend python code:

df = ATR_df.copy()#Calculation of SuperTrend
df['Upper Basic']=(df['High']+df['Low'])/2+(f*df['atr'])
df['Lower Basic']=(df['High']+df['Low'])/2-(f*df['atr'])
df['Upper Band']=df['Upper Basic']
df['Lower Band']=df['Lower Basic']
for i in range(n,len(df)):
if df['Close'][i-1]<=df['Upper Band'][i-1]:
df['Upper Band'][i]=min(df['Upper Basic'][i],df['Upper Band'][i-1])
else:
df['Upper Band'][i]=df['Upper Basic'][i]
for i in range(n,len(df)):
if df['Close'][i-1]>=df['Lower Band'][i-1]:
df['Lower Band'][i]=max(df['Lower Basic'][i],df['Lower Band'][i-1])
else:
df['Lower Band'][i]=df['Lower Basic'][i]
df['SuperTrend']=np.nan
for i in df['SuperTrend']:
if df['Close'][n-1]<=df['Upper Band'][n-1]:
df['SuperTrend'][n-1]=df['Upper Band'][n-1]
elif df['Close'][n-1]>df['Upper Band'][i]:
df['SuperTrend'][n-1]=df['Lower Band'][n-1]
for i in range(n,len(df)):
if df['SuperTrend'][i-1]==df['Upper Band'][i-1] and df['Close'][i]<=df['Upper Band'][i]:
df['SuperTrend'][i]=df['Upper Band'][i]
elif df['SuperTrend'][i-1]==df['Upper Band'][i-1] and df['Close'][i]>=df['Upper Band'][i]:
df['SuperTrend'][i]=df['Lower Band'][i]
elif df['SuperTrend'][i-1]==df['Lower Band'][i-1] and df['Close'][i]>=df['Lower Band'][i]:
df['SuperTrend'][i]=df['Lower Band'][i]
elif df['SuperTrend'][i-1]==df['Lower Band'][i-1] and df['Close'][i]<=df['Lower Band'][i]:
df['SuperTrend'][i]=df['Upper Band'][i]

buy long trade : upper channel <= high of the candle : buy at=upper channel
stop loss long : supertrend >= low low of the candle : sell at = supertrend

sold short : lower channel >= low of the candle : sell at = lowerchannel
stoploss short: supertrend <= high of the candle: buy at = supertrend

Trade = pd.DataFrame(columns=["Date","Trade Type","Bought At","Sold At","BuyTime","SellTime","Exit Type","Profit/Loss"])
n=0
LongSale=False
ShortSale=False
StopLoss = 0
StopLosses = []
for i in range(n, len(df)):
if (LongSale==False) & (ShortSale==False) & (df.loc[i,"Time"]>=datetime.datetime.strptime('10:00:00', '%H:%M:%S').time()) & (df2.loc[i,"Time"]<datetime.datetime.strptime('15:00:00', '%H:%M:%S').time()):
if (df['upper_channel'][i] <= df['High'][i]):
BuyAt = df.loc[i,"upper_channel"]
BuyTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
InitialStopLoss = StopLoss
LongSale=True
continue
elif (df['lower_channel'][i] >= df['Low'][i]):
SoldAt = df.loc[i,"lower_channel"]
SellTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
InitialStopLoss = StopLoss
ShortSale=True
continue
#If Time==15:15:00, we would need to square off our trade:
if (df.loc[i,"Time"]>=datetime.datetime.strptime('15:15:00', '%H:%M:%S').time()):
if (LongSale==True):
SoldAt = df.loc[i,"Close"]
SellTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
LongSale = False
StopLosses = []
Trade = Trade.append({"Date":df.loc[i,"Date"],
"Trade Type":"Long Sale",
"Bought At":BuyAt,
"Sold At":SoldAt,
"BuyTime":BuyTime,
"SellTime":SellTime,
"Exit Type":"15:15:00 Exit",
"Profit/Loss":(SoldAt-BuyAt)},
ignore_index=True)
continue
#If we have made a Short Sale, we will square it off:
elif (ShortSale==True):
BuyAt = df.loc[i,"Close"]
BuyTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
ShortSale = False
StopLosses = []
Trade = Trade.append({"Date":df.loc[i,"Date"],
"Trade Type":"Short Sale",
"Bought At":BuyAt,
"Sold At":SoldAt,
"BuyTime":BuyTime,
"SellTime":SellTime,
"Exit Type":"15:15:00 Exit",
"Profit/Loss":(SoldAt-BuyAt)},
ignore_index=True)
continue
#If we have made a Long Sale, and the current closing price hits StopLoss, Square it off
if (LongSale==True) & (df.loc[i,"Low"]<=df.loc[i,"SuperTrend"]):
SoldAt = df.loc[i,"SuperTrend"]
SellTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
LongSale = False
StopLosses = []
Trade = Trade.append({"Date":df.loc[i,"Date"],
"Trade Type":"Long Sale",
"Bought At":BuyAt,
"Sold At":SoldAt,
"BuyTime":BuyTime,
"SellTime":SellTime,
"Exit Type":"StopLoss Triggered",
"Profit/Loss":(SoldAt-BuyAt)},
ignore_index=True)
continue

#If we have made a Short Sale, and the current closing price hits StopLoss, Square it off
elif (ShortSale==True) & (df.loc[i,"High"]>=df.loc[i,"SuperTrend"]):
BuyAt = df.loc[i,"SuperTrend"]
BuyTime = df.loc[i,"Time"]
date = df.loc[i,"Date"]
ShortSale = False
StopLosses = []
Trade = Trade.append({"Date":df.loc[i,"Date"],
"Trade Type":"Short Sale",
"Bought At":BuyAt,
"Sold At":SoldAt,
"BuyTime":BuyTime,
"SellTime":SellTime,
"Exit Type":"StopLoss Triggered",
"Profit/Loss":(SoldAt-BuyAt)},
ignore_index=True)

Tuning parameters:

timeframe = 5minutes, 10 minutes, 15 minutes, etc…

factor(f) = 1.5 or 3

ATR period = 7 or 14 or 18

N — value = 20, 50, 100, …

--

--

vamsi krishna

I'm a Data Science enthusiast who loves to play with machine learning and deep learning.