In this chapter, we shall dive into the intricate details of a backtesting program crafted for a stock trading strategy.
This program, developed in Python, pivots on the analysis of stock trends utilizing the Guppy Multiple Moving Average (GMMA), often known as the Guppy Screener. Our journey through this chapter will unravel the methodology of tracking stock movements across various timeframes and executing trades anchored on distinct conditions signaled by the GMMA.
GMMA Explained:
The Role of EMAs in GMMA:
tokenall=[5633, 6401, 3861249, 4451329, 2760193, 20993, 325121, 2524673, 41729, 49409, 54273, 60417, 70401, 1510401, 1195009, 1214721, 94977, 108033, 2714625, 2911489, 2763265, 3812865, 160001, 160769, 163073, 177665, 5215745, 3876097, 197633, 3771393, 225537, 173057, 261889, 1207553, 3463169, 2796801, 315393, 3378433, 2513665, 1850625, 340481, 341249, 3789569, 345089, 2747905, 348929, 359937, 356865, 364545, 3699201, 1270529, 377857, 3677697, 3060993, 381697, 2883073, 387073, 387841, 1346049, 408065, 2393089, 415745, 3920129, 424961, 1723649, 2661633, 2933761, 3011329, 4574465, 3001089, 4632577, 492033, 2061825, 511233, 2939649, 2672641, 519937, 2815745, 2674433, 582913, 593665, 3924993, 2977281, 2748929, 633601, 2819073, 636673, 2730497, 3834113, 2906881, 3364353, 731905, 3375873, 3930881, 737793, 738561, 141569, 3078657, 779521, 780289, 1492737, 1522689, 1102337, 857857, 3431425, 3076609, 1837825, 871681, 952577, 878593, 884737, 4343041, 877057, 895745, 2953217, 3465729, 897537, 2873089, 2952193, 2752769, 920065, 951809, 3026177, 969473, 3050241, 112129, 134657, 3721473, 2800641, 3385857, 4454401, 1152769, 806401, 617473, 2905857, 3660545, 3906305, 758529, 975873]
ss=['ACC', 'ADANIENT', 'ADANIPORTS', 'ADANIPOWER', 'ALBK', 'ALOKTEXT', 'AMBUJACEM', 'ANDHRABANK', 'APOLLOTYRE', 'ARVIND', 'ASHOKLEY', 'ASIANPAINT', 'AUROPHARMA', 'AXISBANK', 'BANKBARODA', 'BANKINDIA', 'BATAINDIA', 'BHARATFORG', 'BHARTIARTL', 'BIOCON', 'CANBK', 'CENTRALBK', 'CENTURYTEX', 'CESC', 'CHAMBLFERT', 'CIPLA', 'COALINDIA', 'COLPAL', 'DABUR', 'DLF', 'DRREDDY', 'EXIDEIND', 'FEDERALBNK', 'GAIL', 'GMRINFRA', 'GODREJIND', 'GRASIM', 'GSPL', 'HAVELLS', 'HCLTECH', 'HDFC', 'HDFCBANK', 'HDIL', 'HEROMOTOCO', 'HEXAWARE', 'HINDALCO', 'HINDPETRO', 'HINDUNILVR', 'HINDZINC', 'IBREALEST', 'ICICIBANK', 'IDBI', 'IDEA', 'IDFC', 'IFCI', 'IGL', 'INDHOTEL', 'INDIACEM', 'INDUSINDBK', 'INFY', 'IOB', 'IOC', 'IRB', 'ITC', 'JINDALSTEL', 'JISLJALEQS', 'JPASSOCIAT', 'JPPOWER', 'JSWENERGY', 'JSWSTEEL', 'JUBLFOOD', 'KOTAKBANK', 'KTKBANK', 'LICHSGFIN', 'LT', 'LUPIN', 'M&M', 'MARUTI', 'MCDOWELL-N', 'MRF', 'NCC', 'NMDC', 'NTPC', 'OFSS', 'ONGC', 'OPTOCIRCUI', 'ORIENTBANK', 'PNB', 'POWERGRID', 'PTC', 'PUNJLLOYD', 'RAYMOND', 'RCOM', 'RECLTD', 'RELCAPITAL', 'RELIANCE', 'RELINFRA', 'RENUKA', 'SBIN', 'SCI', 'SINTEX', 'SOUTHBANK', 'SRTRANSFIN', 'SUNPHARMA', 'SUNTV', 'SUZLON', 'SYNDIBANK', 'TATACHEM', 'TATACOMM', 'TATAGLOBAL', 'TATAMOTORS', 'TATAMTRDVR', 'TATAPOWER', 'TATASTEEL', 'TCS', 'TECHM', 'TITAN', 'UCOBANK', 'ULTRACEMCO', 'UNIONBANK', 'UNITECH', 'VOLTAS', 'WELCORP', 'WIPRO', 'YESBANK', 'BHEL', 'BPCL', 'DISHTV', 'DIVISLAB', 'GVKPIL', 'NHPC', 'MPHASIS', 'SIEMENS', 'PEL', 'PETRONET', 'PFC', 'RPOWER', 'SAIL', 'ZEEL']
# inputs for backtesting
sdate ="2018-08-20 00:00:00"
todate ="2019-09-16 09:16:00"
#sdate ="2019-08-19"
#todate ="2019-10-01"
time_frame ="minute"
quu=50000
eexchange="NSE"
productt="MIS"
qu=int(quu)
# baktesting starting and ending date
sdate_backtest ="2018-08-14"
todate_backtest ="2019-10-02"
##############
print("SCANNING START")
ttoken=5633
ttradingsymbol="ACC"
strike_rate = 0
strike_rate_list = []
timeframe = []
timeframe_list = []
pnl = 0
pnl_list = []
def time_con(time,df):
z = 0
chg = []
chg_index = 0
timeframe = time
date = np.array([])
for i in range(len(df)):
date = np.hstack((date,str(df.loc[i,"date"])))
open_np = df.open.values
high_np = df.high.values
low_np = df.low.values
close_np = df.close.values
# volume_np = df.volume.values
# print(date)
for j in range(len(date)):
if date[j][11:16] == "09:15":
chg.append(j)
np_date=np.array([])
np_open = np.array([])
np_high = np.array([])
np_low = np.array([])
np_close = np.array([])
# np_volume = np.array([])
for i in range(len(date)-timeframe+1):
if i>=z:
chg_index+=1
if (chg_index < len(chg)):
for k in range(i,chg[chg_index],timeframe):
# print(date[k])
# print(k,k+timeframe)
np_date = np.hstack((np_date,date[k]))
np_open = np.hstack((np_open,open_np[k]))
np_high = np.hstack((np_high,np.amax(high_np[k:k+timeframe])))
# print(high_np[k:k+timeframe])
np_low = np.hstack((np_low,np.amin(low_np[k:k+timeframe])))
# print(low_np[k:k+timeframe])
np_close = np.hstack((np_close,close_np[k+timeframe-1]))
# np_volume = np.hstack((np_volume,np.sum(volume_np[k:k+timeframe])))
z = i+timeframe
z=chg[chg_index]
else:
con_df = pd.DataFrame({"date":np_date,"open":np_open,"high":np_high,"low":np_low,"close":np_close})
return con_df
for t in range(1,2):
dfw=kite.historical_data(ttoken,sdate_backtest,todate_backtest,time_frame,0)
dfw=pd.DataFrame(dfw)
df=pd.DataFrame(dfw[['date','open','high','low','close']])
df = time_con(t,df)
slow_ema = [3,5,7,9,11,13,15,17,19,21,23]
fast_ema = [25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,200]
def EMA(df, base, target, period, alpha=False):
con = pd.concat([df[:period][base].rolling(window=period).mean(), df[period:][base]])
if (alpha == True):
# (1 - alpha) * previous_val + alpha * current_val where alpha = 1 / period
df[target] = con.ewm(alpha=1 / period, adjust=False).mean()
else:
# ((current_val - previous_val) * coeff) + previous_val where coeff = 2 / (period + 1)
df[target] = con.ewm(span=period, adjust=False).mean()
df.fillna(0,inplace = True)
# return df
for j in slow_ema:
val = "ema"+"_"+str(j)
EMA(df,"close",val,j)
for k in fast_ema:
val = "ema"+"_"+str(k)
EMA(df,"close",val,k)
def super_guppy(interval,df,anchor=0):
anchor = 0
ShowBreak = True
ShowSwing = True
ShowCon = False
uOCCswing = False
Lookback = 6
emaFilter = False
mult = 0
buybreak = 0
sellbreak = 0
buy_barssince_var = 0
sell_barssince_var = 0
buybreak_barssince_var = 0
sellbreak_barssince_var = 0
barssince_lst = list()
barssince_var = 0
bar_count_var = 0
buy1 = list()
sell1 = list()
buy2 = list()
sell2 = list()
buybreak1 = list()
sellbreak1 = list()
def barssince(b,barssince_var):
barssince_lst = []
barssince_var = 0
new_var = len(b)
for i in b[::-1]:
if i == 1:
break
barssince_lst.append(i)
barssince_var = len(barssince_lst)
return barssince_var
barssince_lst.clear()
if interval < 1441 :
if (anchor==0 or interval <= 0 or interval >= anchor or anchor > 1441 ):
mult = 1
else:
if round(anchor/interval) > 1:
mult = round(anchor/interval)
else:
mult = 1
else:
mult = 1
#isIntraday Not
if interval > 1441:
if (anchor==0 or interval <= 0 or interval >= anchor or anchor < 52 ):
mult = mult
else:
if round(anchor/interval) > 1:
mult = round(anchor/interval)
else:
mult = 1
else:
mult = mult
mult = 1
for i in range(len(df)):
emaF1 = df.loc[i,'ema_3']
emaF2 = df.loc[i,'ema_5']
emaF3 = df.loc[i,'ema_7']
emaF4 = df.loc[i,'ema_9']
emaF5 = df.loc[i,'ema_11']
emaF6 = df.loc[i,'ema_13']
emaF7 = df.loc[i,'ema_15']
emaF8 = df.loc[i,'ema_17']
emaF9 = df.loc[i,'ema_19']
emaF10 = df.loc[i,'ema_21']
emaF11 = df.loc[i,'ema_23']
emaS1 = df.loc[i,'ema_25']
emaS2 = df.loc[i,'ema_28']
emaS3 = df.loc[i,'ema_31']
emaS4 = df.loc[i,'ema_34']
emaS5 = df.loc[i,'ema_37']
emaS6 = df.loc[i,'ema_40']
emaS7 = df.loc[i,'ema_43']
emaS8 = df.loc[i,'ema_46']
emaS9 = df.loc[i,'ema_49']
emaS10 = df.loc[i,'ema_52']
emaS11 = df.loc[i,'ema_55']
emaS12 = df.loc[i,'ema_58']
emaS13 = df.loc[i,'ema_61']
emaS14 = df.loc[i,'ema_64']
emaS15 = df.loc[i,'ema_67']
emaS16 = df.loc[i,'ema_70']
ema200 = df.loc[i,'ema_200']
emafast = (emaF1 + emaF2 + emaF3 + emaF4 + emaF5 + emaF6 + emaF7 + emaF8 + emaF9 + emaF10 + emaF11)/11
emaslow = (emaS1 + emaS2 + emaS3 + emaS4 + emaS5 + emaS6 + emaS7 + emaS8 + emaS9 + emaS10 + emaS11 + emaS12 + emaS13 + emaS14 + emaS15 + emaS16)/16
#Fast EMA Color Rules
colfastL = (emaF1>emaF2 and emaF2>emaF3 and emaF3>emaF4 and emaF4>emaF5 and emaF5>emaF6 and emaF6>emaF7 and emaF7>emaF8 and emaF8>emaF9 and emaF9>emaF10 and emaF10>emaF11)
colfastS = (emaF1emaS2 and emaS2>emaS3 and emaS3>emaS4 and emaS4>emaS5 and emaS5>emaS6 and emaS6>emaS7 and emaS7>emaS8) and (emaS8>emaS9 and emaS9>emaS10 and emaS10>emaS11 and emaS11>emaS12 and emaS12>emaS13 and emaS13>emaS14 and emaS14>emaS15 and emaS15>emaS16)
colslowS = (emaS1 emaslow and not colslowS and colfastL and (not ShowCon or colslowL) and (not emaFilter or emafast>ema200):
if int(buy1[-1]) > 0:
buy = buy1[-1] + 1
else:
buy = 1
else:
buy = 0
buy1.append(buy)
if emafast < emaslow and not colslowL and colfastS and (not ShowCon or colslowS) and (not emaFilter or emafast 0:
sell = sell1[-1] + 1
else:
sell = 1
else:
sell = 0
sell1.append(sell)
#buy
if buy>1 and colfastL and (uOCCswing and ((df.loc[i-1,'close']df.loc[i,'open']))):
buy3 = 1
else:
buy3 = buy
buy2.append(buy3)
#sell
if sell>1 and colfastS and (uOCCswing and ((df.loc[i-1,'close']df.loc[i,'open']))):
sell3 = 1
else:
sell3 = sell
sell2.append(sell3)
#buybreak
if emafast > emaslow and not colslowS and (not emaFilter or emafast>ema200):
if buybreak1[-1] > 0:
buybreak = buybreak1[-1] + 1
else:
buybreak = 1
else:
buybreak = 0
buybreak1.append(buybreak)
if emafast < emaslow and not colslowL and (not emaFilter or emafast 0:
sellbreak = sellbreak1[-1]+1
else:
sellbreak = 1
else:
sellbreak = 0
sellbreak1.append(sellbreak)
#arrow plotting
#buy_arrow
buy_barssince_var = barssince(buy2[:-1],barssince_var)
if (ShowSwing and buy3==1)and buy_barssince_var > 6:
buy_arrow = 1
else:
buy_arrow = 0
#sell arrow
sell_barssince_var = barssince(sell2[:-1],barssince_var)
if ShowSwing and (sell3==1 and sell_barssince_var > 6):
sell_arrow = 1
else:
sell_arrow = 0
#buybreak_arrow
buybreak_barssince_var = barssince(buybreak1[:-1],barssince_var)
sellbreak_barssince_var = barssince(sellbreak1[:-1],barssince_var)
if ShowBreak and buybreak==1 and (sellbreak_barssince_var>Lookback) and (buybreak_barssince_var>Lookback):
buybreak_arrow = 1
else:
buybreak_arrow = 0
#sellbreak_arrow
if ShowBreak and sellbreak==1 and (buybreak_barssince_var>Lookback) and (sellbreak_barssince_var>Lookback):
sellbreak_arrow = 1
else:
sellbreak_arrow = 0
if buy_arrow==1 and sell_arrow==0 and buybreak_arrow==0 and sellbreak_arrow==0:
arrow_color = 'green'
elif buy_arrow==0 and sell_arrow==1 and buybreak_arrow==0 and sellbreak_arrow==0:
arrow_color = 'red'
elif sell_arrow==0 and (buy_arrow==0 or buy_arrow==1) and buybreak_arrow==1 and sellbreak_arrow==0:
arrow_color = 'aqua'
elif buy_arrow==0 and (sell_arrow==1 or sell_arrow==0) and buybreak_arrow==0 and sellbreak_arrow==1:
arrow_color = 'blue'
else:
arrow_color = 'none'
df.loc[i,'arrow_color'] = arrow_color
df = df[['date','open','high','low','close','arrow_color']]
return df
df=super_guppy(15,df)
gup=df
def bidatrema(df,period):
df['hl']=abs(df['high']-df['low'])
df['hpc']=abs(df['high']-df['close'].shift())
df['lpc']=abs(df['low']-df['close'].shift())
df['tr']=df[['hl','hpc','lpc']].max(axis=1)
df['ATR']=pd.DataFrame.ewm(df["tr"], span=period,min_periods=period).mean()
df.drop(["hl","hpc","lpc","tr"],axis = 1 , inplace =True)
bidatrema(gup,14)
df['bid_value'] = 0
df['executed_value'] = 0
df['diff'] = 0
df['pnl'] = 0
qty = int ( qu/ (gup.iloc[-1,2]) )
var = False
var_2 = False
var_1 = False
for i in range(len(df)):
zz=df.loc[i,"date"]
za=str(zz)[11:13]
if za!="15":
if var==True:
df.loc[i,'diff'] = df.loc[i,'close'] - bid_value
df.loc[i,'pnl'] = ( bid_value /bid_value)*df.loc[i,'diff']
var=False
var1=False
var_2=True
if za!="15":
var_2=False
if var==False and var_2==False:
if df.loc[i,'arrow_color']=='green':
bid_value = (df.loc[i,'high']+df.loc[i,'ATR']*.25)+(df.loc[i,'ATR']*.1)
df.loc[i,'bid_value'] =bid_value
var=True
var1=False
if var==True and var1==False and var_2==False:
if df.loc[i,'high'] > bid_value and df.loc[i,'low'] < bid_value:
df.loc[i,'executed_value']=bid_value
var1=True
if var==True and var1==True and var_2==False:
if df.loc[i,'arrow_color']=='red':
df.loc[i,'diff'] = df.loc[i,'close'] - bid_value
df.loc[i,'pnl'] = ( bid_value /bid_value)*df.loc[i,'diff']
var=False
var1=False
list_1 = df['pnl']
pos_count = len(list(filter(lambda x: (x>0),list_1)))
neg_count = len(list(filter(lambda x: (x<0),list_1)))
total_trade = pos_count + neg_count
try :
strike_rate = pos_count/total_trade
except:
strike_rate = 0
pnl = df['pnl'].sum()
pnl_list.append(pnl)
timeframe_list.append(t)
strike_rate_list.append(strike_rate)
main_df = pd.DataFrame({'timeframe':timeframe_list,'pnl':pnl_list,'strike_rate':strike_rate_list})
main_df.to_csv('pnlbuy.csv')
print("complete")
Output –
SCANNING START
complete
For each executed buy trade, the program meticulously computes the PnL. This involves tracking the price movement post-execution and quantifying the trade’s success or failure.
display(main_df)
Output –
timeframe pnl strike_rate
0 1 -73.269911 0.214286
## fno
tokenall=[5633, 6401, 3861249, 4451329, 2760193, 20993, 325121, 2524673, 41729, 49409, 54273, 60417, 70401, 1510401, 1195009, 1214721, 94977, 108033, 2714625, 2911489, 2763265, 3812865, 160001, 160769, 163073, 177665, 5215745, 3876097, 197633, 3771393, 225537, 173057, 261889, 1207553, 3463169, 2796801, 315393, 3378433, 2513665, 1850625, 340481, 341249, 3789569, 345089, 2747905, 348929, 359937, 356865, 364545, 3699201, 1270529, 377857, 3677697, 3060993, 381697, 2883073, 387073, 387841, 1346049, 408065, 2393089, 415745, 3920129, 424961, 1723649, 2661633, 2933761, 3011329, 4574465, 3001089, 4632577, 492033, 2061825, 511233, 2939649, 2672641, 519937, 2815745, 2674433, 582913, 593665, 3924993, 2977281, 2748929, 633601, 2819073, 636673, 2730497, 3834113, 2906881, 3364353, 731905, 3375873, 3930881, 737793, 738561, 141569, 3078657, 779521, 780289, 1492737, 1522689, 1102337, 857857, 3431425, 3076609, 1837825, 871681, 952577, 878593, 884737, 4343041, 877057, 895745, 2953217, 3465729, 897537, 2873089, 2952193, 2752769, 920065, 951809, 3026177, 969473, 3050241, 112129, 134657, 3721473, 2800641, 3385857, 4454401, 1152769, 806401, 617473, 2905857, 3660545, 3906305, 758529, 975873]
ss=['ACC', 'ADANIENT', 'ADANIPORTS', 'ADANIPOWER', 'ALBK', 'ALOKTEXT', 'AMBUJACEM', 'ANDHRABANK', 'APOLLOTYRE', 'ARVIND', 'ASHOKLEY', 'ASIANPAINT', 'AUROPHARMA', 'AXISBANK', 'BANKBARODA', 'BANKINDIA', 'BATAINDIA', 'BHARATFORG', 'BHARTIARTL', 'BIOCON', 'CANBK', 'CENTRALBK', 'CENTURYTEX', 'CESC', 'CHAMBLFERT', 'CIPLA', 'COALINDIA', 'COLPAL', 'DABUR', 'DLF', 'DRREDDY', 'EXIDEIND', 'FEDERALBNK', 'GAIL', 'GMRINFRA', 'GODREJIND', 'GRASIM', 'GSPL', 'HAVELLS', 'HCLTECH', 'HDFC', 'HDFCBANK', 'HDIL', 'HEROMOTOCO', 'HEXAWARE', 'HINDALCO', 'HINDPETRO', 'HINDUNILVR', 'HINDZINC', 'IBREALEST', 'ICICIBANK', 'IDBI', 'IDEA', 'IDFC', 'IFCI', 'IGL', 'INDHOTEL', 'INDIACEM', 'INDUSINDBK', 'INFY', 'IOB', 'IOC', 'IRB', 'ITC', 'JINDALSTEL', 'JISLJALEQS', 'JPASSOCIAT', 'JPPOWER', 'JSWENERGY', 'JSWSTEEL', 'JUBLFOOD', 'KOTAKBANK', 'KTKBANK', 'LICHSGFIN', 'LT', 'LUPIN', 'M&M', 'MARUTI', 'MCDOWELL-N', 'MRF', 'NCC', 'NMDC', 'NTPC', 'OFSS', 'ONGC', 'OPTOCIRCUI', 'ORIENTBANK', 'PNB', 'POWERGRID', 'PTC', 'PUNJLLOYD', 'RAYMOND', 'RCOM', 'RECLTD', 'RELCAPITAL', 'RELIANCE', 'RELINFRA', 'RENUKA', 'SBIN', 'SCI', 'SINTEX', 'SOUTHBANK', 'SRTRANSFIN', 'SUNPHARMA', 'SUNTV', 'SUZLON', 'SYNDIBANK', 'TATACHEM', 'TATACOMM', 'TATAGLOBAL', 'TATAMOTORS', 'TATAMTRDVR', 'TATAPOWER', 'TATASTEEL', 'TCS', 'TECHM', 'TITAN', 'UCOBANK', 'ULTRACEMCO', 'UNIONBANK', 'UNITECH', 'VOLTAS', 'WELCORP', 'WIPRO', 'YESBANK', 'BHEL', 'BPCL', 'DISHTV', 'DIVISLAB', 'GVKPIL', 'NHPC', 'MPHASIS', 'SIEMENS', 'PEL', 'PETRONET', 'PFC', 'RPOWER', 'SAIL', 'ZEEL']
sdate ="2019-08-20 00:00:00"
todate ="2019-09-16 09:16:00"
#sdate ="2019-08-19"
#todate ="2019-10-01"
# inputs for backtesting
time_frame ="minute"
quu=50000
eexchange="NSE"
productt="MIS"
qu=int(quu)
# Backtesting Dates
sdate_backtest ="2019-08-14"
todate_backtest ="2019-10-02"
print("SCANNING START")
ttoken=5633
ttradingsymbol="ACC"
def time_con(time,df):
z = 0
chg = []
chg_index = 0
timeframe = time
date = np.array([])
for i in range(len(df)):
date = np.hstack((date,str(df.loc[i,"date"])))
open_np = df.open.values
high_np = df.high.values
low_np = df.low.values
close_np = df.close.values
# volume_np = df.volume.values
# print(date)
for j in range(len(date)):
if date[j][11:16] == "09:15":
chg.append(j)
np_date=np.array([])
np_open = np.array([])
np_high = np.array([])
np_low = np.array([])
np_close = np.array([])
# np_volume = np.array([])
for i in range(len(date)-timeframe+1):
if i>=z:
chg_index+=1
if (chg_index < len(chg)):
for k in range(i,chg[chg_index],timeframe):
# print(date[k])
# print(k,k+timeframe)
np_date = np.hstack((np_date,date[k]))
np_open = np.hstack((np_open,open_np[k]))
np_high = np.hstack((np_high,np.amax(high_np[k:k+timeframe])))
# print(high_np[k:k+timeframe])
np_low = np.hstack((np_low,np.amin(low_np[k:k+timeframe])))
# print(low_np[k:k+timeframe])
np_close = np.hstack((np_close,close_np[k+timeframe-1]))
# np_volume = np.hstack((np_volume,np.sum(volume_np[k:k+timeframe])))
z = i+timeframe
z=chg[chg_index]
else:
con_df = pd.DataFrame({"date":np_date,"open":np_open,"high":np_high,"low":np_low,"close":np_close})
return con_df
strike_rate = 0
strike_rate_list = []
timeframe = []
timeframe_list = []
pnl = 0
pnl_list = []
for t in range(1,2):
dfw=kite.historical_data(ttoken,sdate_backtest,todate_backtest,time_frame,0)
dfw=pd.DataFrame(dfw)
df=pd.DataFrame(dfw[['date','open','high','low','close']])
df= time_con(t,df)
slow_ema = [3,5,7,9,11,13,15,17,19,21,23]
fast_ema = [25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,200]
def EMA(df, base, target, period, alpha=False):
con = pd.concat([df[:period][base].rolling(window=period).mean(), df[period:][base]])
if (alpha == True):
# (1 - alpha) * previous_val + alpha * current_val where alpha = 1 / period
df[target] = con.ewm(alpha=1 / period, adjust=False).mean()
else:
# ((current_val - previous_val) * coeff) + previous_val where coeff = 2 / (period + 1)
df[target] = con.ewm(span=period, adjust=False).mean()
df.fillna(0,inplace = True)
# return df
for j in slow_ema:
val = "ema"+"_"+str(j)
EMA(df,"close",val,j)
for k in fast_ema:
val = "ema"+"_"+str(k)
EMA(df,"close",val,k)
def super_guppy(interval,df,anchor=0):
anchor = 0
ShowBreak = True
ShowSwing = True
ShowCon = False
uOCCswing = False
Lookback = 6
emaFilter = False
mult = 0
buybreak = 0
sellbreak = 0
buy_barssince_var = 0
sell_barssince_var = 0
buybreak_barssince_var = 0
sellbreak_barssince_var = 0
barssince_lst = list()
barssince_var = 0
bar_count_var = 0
buy1 = list()
sell1 = list()
buy2 = list()
sell2 = list()
buybreak1 = list()
sellbreak1 = list()
def barssince(b,barssince_var):
barssince_lst = []
barssince_var = 0
new_var = len(b)
for i in b[::-1]:
if i == 1:
break
barssince_lst.append(i)
barssince_var = len(barssince_lst)
return barssince_var
barssince_lst.clear()
if interval < 1441 :
if (anchor==0 or interval <= 0 or interval >= anchor or anchor > 1441 ):
mult = 1
else:
if round(anchor/interval) > 1:
mult = round(anchor/interval)
else:
mult = 1
else:
mult = 1
#isIntraday Not
if interval > 1441:
if (anchor==0 or interval <= 0 or interval >= anchor or anchor < 52 ):
mult = mult
else:
if round(anchor/interval) > 1:
mult = round(anchor/interval)
else:
mult = 1
else:
mult = mult
mult = 1
for i in range(len(df)):
emaF1 = df.loc[i,'ema_3']
emaF2 = df.loc[i,'ema_5']
emaF3 = df.loc[i,'ema_7']
emaF4 = df.loc[i,'ema_9']
emaF5 = df.loc[i,'ema_11']
emaF6 = df.loc[i,'ema_13']
emaF7 = df.loc[i,'ema_15']
emaF8 = df.loc[i,'ema_17']
emaF9 = df.loc[i,'ema_19']
emaF10 = df.loc[i,'ema_21']
emaF11 = df.loc[i,'ema_23']
emaS1 = df.loc[i,'ema_25']
emaS2 = df.loc[i,'ema_28']
emaS3 = df.loc[i,'ema_31']
emaS4 = df.loc[i,'ema_34']
emaS5 = df.loc[i,'ema_37']
emaS6 = df.loc[i,'ema_40']
emaS7 = df.loc[i,'ema_43']
emaS8 = df.loc[i,'ema_46']
emaS9 = df.loc[i,'ema_49']
emaS10 = df.loc[i,'ema_52']
emaS11 = df.loc[i,'ema_55']
emaS12 = df.loc[i,'ema_58']
emaS13 = df.loc[i,'ema_61']
emaS14 = df.loc[i,'ema_64']
emaS15 = df.loc[i,'ema_67']
emaS16 = df.loc[i,'ema_70']
ema200 = df.loc[i,'ema_200']
emafast = (emaF1 + emaF2 + emaF3 + emaF4 + emaF5 + emaF6 + emaF7 + emaF8 + emaF9 + emaF10 + emaF11)/11
emaslow = (emaS1 + emaS2 + emaS3 + emaS4 + emaS5 + emaS6 + emaS7 + emaS8 + emaS9 + emaS10 + emaS11 + emaS12 + emaS13 + emaS14 + emaS15 + emaS16)/16
#Fast EMA Color Rules
colfastL = (emaF1>emaF2 and emaF2>emaF3 and emaF3>emaF4 and emaF4>emaF5 and emaF5>emaF6 and emaF6>emaF7 and emaF7>emaF8 and emaF8>emaF9 and emaF9>emaF10 and emaF10>emaF11)
colfastS = (emaF1emaS2 and emaS2>emaS3 and emaS3>emaS4 and emaS4>emaS5 and emaS5>emaS6 and emaS6>emaS7 and emaS7>emaS8) and (emaS8>emaS9 and emaS9>emaS10 and emaS10>emaS11 and emaS11>emaS12 and emaS12>emaS13 and emaS13>emaS14 and emaS14>emaS15 and emaS15>emaS16)
colslowS = (emaS1 emaslow and not colslowS and colfastL and (not ShowCon or colslowL) and (not emaFilter or emafast>ema200):
if int(buy1[-1]) > 0:
buy = buy1[-1] + 1
else:
buy = 1
else:
buy = 0
buy1.append(buy)
if emafast < emaslow and not colslowL and colfastS and (not ShowCon or colslowS) and (not emaFilter or emafast 0:
sell = sell1[-1] + 1
else:
sell = 1
else:
sell = 0
sell1.append(sell)
#buy
if buy>1 and colfastL and (uOCCswing and ((df.loc[i-1,'close']df.loc[i,'open']))):
buy3 = 1
else:
buy3 = buy
buy2.append(buy3)
#sell
if sell>1 and colfastS and (uOCCswing and ((df.loc[i-1,'close']df.loc[i,'open']))):
sell3 = 1
else:
sell3 = sell
sell2.append(sell3)
#buybreak
if emafast > emaslow and not colslowS and (not emaFilter or emafast>ema200):
if buybreak1[-1] > 0:
buybreak = buybreak1[-1] + 1
else:
buybreak = 1
else:
buybreak = 0
buybreak1.append(buybreak)
if emafast < emaslow and not colslowL and (not emaFilter or emafast 0:
sellbreak = sellbreak1[-1]+1
else:
sellbreak = 1
else:
sellbreak = 0
sellbreak1.append(sellbreak)
#arrow plotting
#buy_arrow
buy_barssince_var = barssince(buy2[:-1],barssince_var)
if (ShowSwing and buy3==1)and buy_barssince_var > 6:
buy_arrow = 1
else:
buy_arrow = 0
#sell arrow
sell_barssince_var = barssince(sell2[:-1],barssince_var)
if ShowSwing and (sell3==1 and sell_barssince_var > 6):
sell_arrow = 1
else:
sell_arrow = 0
#buybreak_arrow
buybreak_barssince_var = barssince(buybreak1[:-1],barssince_var)
sellbreak_barssince_var = barssince(sellbreak1[:-1],barssince_var)
if ShowBreak and buybreak==1 and (sellbreak_barssince_var>Lookback) and (buybreak_barssince_var>Lookback):
buybreak_arrow = 1
else:
buybreak_arrow = 0
#sellbreak_arrow
if ShowBreak and sellbreak==1 and (buybreak_barssince_var>Lookback) and (sellbreak_barssince_var>Lookback):
sellbreak_arrow = 1
else:
sellbreak_arrow = 0
if buy_arrow==1 and sell_arrow==0 and buybreak_arrow==0 and sellbreak_arrow==0:
arrow_color = 'green'
elif buy_arrow==0 and sell_arrow==1 and buybreak_arrow==0 and sellbreak_arrow==0:
arrow_color = 'red'
elif sell_arrow==0 and (buy_arrow==0 or buy_arrow==1) and buybreak_arrow==1 and sellbreak_arrow==0:
arrow_color = 'aqua'
elif buy_arrow==0 and (sell_arrow==1 or sell_arrow==0) and buybreak_arrow==0 and sellbreak_arrow==1:
arrow_color = 'blue'
else:
arrow_color = 'none'
df.loc[i,'arrow_color'] = arrow_color
df = df[['date','open','high','low','close','arrow_color']]
return df
df=super_guppy(15,df)
gup=df
def bidatrema(df,period):
df['hl']=abs(df['high']-df['low'])
df['hpc']=abs(df['high']-df['close'].shift())
df['lpc']=abs(df['low']-df['close'].shift())
df['tr']=df[['hl','hpc','lpc']].max(axis=1)
df['ATR']=pd.DataFrame.ewm(df["tr"], span=period,min_periods=period).mean()
df.drop(["hl","hpc","lpc","tr"],axis = 1 , inplace =True)
bidatrema(gup,14)
df['bid_value'] = 0
df['executed_value'] = 0
df['diff'] = 0
df['pnl'] = 0
qty = int ( qu/ (gup.iloc[-1,2]) )
var = False
var_2 = False
var_1 = False
for i in range(len(df)):
zz=df.loc[i,"date"]
za=str(zz)[11:13]
if za=="15":
if var==True:
df.loc[i,'diff'] = bid_value - df.loc[i,'close']
df.loc[i,'pnl'] = ( bid_value /bid_value)*df.loc[i,'diff']
##
var=False
var1=False
var_2=True
if za!="15":
var_2=False
if var==False and var_2==False:
if df.loc[i,'arrow_color']=='red':
bid_value = (df.loc[i,'low']-df.loc[i,'ATR']*.25)-(df.loc[i,'ATR']*.1)
df.loc[i,'bid_value'] =bid_value
var=True
var1=False
if var==True and var1==False and var_2==False:
if df.loc[i,'high'] > bid_value and df.loc[i,'low'] < bid_value:
df.loc[i,'executed_value']=bid_value
var1=True
if var==True and var1==True and var_2==False:
if df.loc[i,'arrow_color']=='green':
df.loc[i,'diff'] = bid_value - df.loc[i,'close']
df.loc[i,'pnl'] = ( bid_value /bid_value)*df.loc[i,'diff']
var=False
var1=False
list_1 = df['pnl']
pos_count = len(list(filter(lambda x: (x>0),list_1)))
neg_count = len(list(filter(lambda x: (x<0),list_1)))
total_trade = pos_count + neg_count
try :
strike_rate = pos_count/total_trade
except:
strike_rate = 0
#print(strike_rate)
pnl = df['pnl'].sum()
pnl_list.append(pnl)
timeframe_list.append(t)
strike_rate_list.append(strike_rate)
main_df = pd.DataFrame({'timeframe':timeframe_list,'pnl':pnl_list,'strike_rate':strike_rate_list})
main_df.to_csv('pnlsell.csv')
print("complete")
Output –
SCANNING START
complete
display(main_df)
Output –
timeframe pnl strike_rate
0 1 -11.92732 0.333333