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 
				
			
		
