Coding A Python Function For Backtesting Inside Bar Strategies

Now that we have an overview of the strategy, let’s dissect the check_high_breakout_and_save function. 

This Python function is designed to scan historical stock price data and assess whether buy and sell trades are triggered, monitor trade targets and stop losses, calculate profits and losses, and manage trade exits.

				
					
# Define the function to check high breakout and save entry time
def check_high_breakout_and_save(symbol, time,high,low,buy_target,sell_target):
    
    buy_trigger=0
    sell_trigger=0
    
    buy_trigger_stoploss=0
    sell_trigger_stoploss=0
    buy_trigger_target=0
    sell_trigger_target=0
    
    buy_exit_time=0
    buy_exit_price=0
    sell_exit_time=0
    sell_exit_price=0
    
    buy_pl_points=0
    sell_pl_points=0
    
    datetime_string = str(row['date']) + " 9:20:00+05:30"

    # Convert the datetime string to a datetime object
    from_date = datetime.datetime.strptime(datetime_string, '%d-%m-%Y %H:%M:%S%z')

     
    to_date = from_date + datetime.timedelta(hours=5)
    
    data = kite.historical_data(instrument_token=get_insToken(symbol, "NSE"),
                                 from_date=from_date+ datetime.timedelta(days=1),
                                 to_date=to_date+ datetime.timedelta(days=1),
                                 interval='minute')   
    
#     print(data)
#     sys.exit()
    for candle in data:
        if(buy_trigger==0): 
            if candle['high'] > high:
                buy_trigger = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
        if(buy_trigger!=0): #Buy Trade has Triggered
            
            if buy_trigger_target == 0 and buy_trigger_stoploss == 0:

                if candle['high'] > buy_target:
                    buy_trigger_target = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break
                            
                if candle['low'] < low:
                    buy_trigger_stoploss = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break
    
    if buy_trigger != 0:
        if buy_trigger_target !=0:
            buy_pl_points=buy_target-high
        if buy_trigger_target ==0:
            if buy_trigger_stoploss !=0:
                buy_pl_points=low-high
            if buy_trigger_stoploss ==0:                
                buy_exit_time = data[-1]['date'].strftime('%Y-%m-%d %H:%M:%S')
                buy_exit_price =  data[-1]['open']                
                buy_pl_points=buy_exit_price-high
                
                
    for candle in data:            
        if(sell_trigger==0): 
            if candle['low'] < low:
                sell_trigger = candle['date'].strftime('%Y-%m-%d %H:%M:%S') 
        if(sell_trigger!=0): #Sell Trade has Triggered
            
            if sell_trigger_target==0 and sell_trigger_stoploss==0:
                if candle['low'] < sell_target:
                    sell_trigger_target = candle['date'].strftime('%Y-%m-%d %H:%M:%S') 
                    break          

                if candle['high'] > high:
                    sell_trigger_stoploss = candle['date'].strftime('%Y-%m-%d %H:%M:%S') 
                    break   
                
    if sell_trigger != 0:
        if sell_trigger_target !=0:
            sell_pl_points=low-sell_target
        if sell_trigger_target ==0:
            if sell_trigger_stoploss !=0:
                sell_pl_points=low-high
            if sell_trigger_stoploss ==0:                
                sell_exit_time = data[-1]['date'].strftime('%Y-%m-%d %H:%M:%S')
                sell_exit_price =  data[-1]['open']                
                sell_pl_points=low-sell_exit_price
                
    return buy_trigger,sell_trigger,buy_trigger_stoploss,sell_trigger_stoploss,buy_exit_time,buy_exit_price,sell_exit_time,sell_exit_price,buy_trigger_target,sell_trigger_target,buy_pl_points,sell_pl_points

				
			

Now let’s explain the entire code step by step –

  • symbol: The stock symbol (e.g., “RELIANCE”).
  • time: A time parameter (currently unused within the function).
  • high: The stock’s high price.
  • low: The stock’s low price.
  • buy_target: The buy target price.
  • sell_target: The sell target price.

Initialization: Several variables are initialized to keep track of buy and sell triggers, stop losses, targets, exit times, and price points for both buy and sell positions.

Date and Time Setup: The function creates a datetime object representing the starting date and time for data retrieval. The from_date variable is set to this value. The to_date variable is calculated by adding 5 hours to from_date, representing a 5-hour trading window. Historical stock data is then fetched for this time frame.

In case of Intraday Trades, 

The variable is calculated by adding 5 hours. It means the strategy is to be stopped at 14:20. As disccused in earlier chapters, it will close the trade if the trade has triggered and has not hit target or stop loss.

In case of Positional Trades, 

The variable should be calculated adding 2 days. Although the strategy of Positional was initially developed for 5 days time frame but the returns do not vary much between 2 days and 5 days exit. As it is breakout/breakdown strategy, the ones that are consolidating hit its stoploss earlier. And, the ones those doesn’t, they move up or down significantly and keep consolidating in the new found zone. 

The amount of profit is higher in Positional Trades but the number of loss trades is also higher balancing everything out.

Buy Trade Analysis:

				
					    for candle in data:
        if (buy_trigger == 0):
            if candle['high'] > high:
                buy_trigger = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
        
        if (buy_trigger != 0):  # Buy Trade has Triggered
            if buy_trigger_target == 0 and buy_trigger_stoploss == 0:
                if candle['high'] > buy_target:
                    buy_trigger_target = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break

                if candle['low'] < low:
                    buy_trigger_stoploss = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break

				
			

This section examines potential buy trade conditions:

  • It iterates through each minute of historical data.
  • Checks if a buy trigger has already occurred. If not, it checks whether the stock’s high price exceeds the predefined high. If so, a buy trigger is set.
  • Once the buy trigger is set, the function monitors whether the buy target or stop loss is hit by examining the high and low prices in the data.
  • If either the target or stop loss is hit, the function records the respective trigger time and exits the loop.

Calculating Buy Trade Profits/Losses:

				
					    if buy_trigger != 0:
        if buy_trigger_target != 0:
            buy_pl_points = buy_target - high
        if buy_trigger_target == 0:
            if buy_trigger_stoploss != 0:
                buy_pl_points = low - high
            if buy_trigger_stoploss == 0:
                buy_exit_time = data[-1]['date'].strftime('%Y-%m-%d %H:%M:%S')
                buy_exit_price = data[-1]['open']
                buy_pl_points = buy_exit_price - high

				
			

This part calculates the profit or loss for the buy trade:

  • It checks if the buy trigger occurred.
  • If the buy trigger target was hit, it calculates the profit as the difference between the target and the predefined high.
  • If the target wasn’t hit but the stop loss was hit, it calculates the loss as the difference between low and high.
  • If neither target nor stop loss was hit, it calculates the profit/loss based on the exit price (open price of the last data point) and high.

Sell Trade Analysis and Profit/Loss Calculation:

Similar logic is applied to the sell trade:

				
					    for candle in data:
        if (sell_trigger == 0):
            if candle['low'] < low:
                sell_trigger = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
        
        if (sell_trigger != 0):  # Sell Trade has Triggered
            if sell_trigger_target == 0 and sell_trigger_stoploss == 0:
                if candle['low'] < sell_target:
                    sell_trigger_target = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break

                if candle['high'] > high:
                    sell_trigger_stoploss = candle['date'].strftime('%Y-%m-%d %H:%M:%S')
                    break

				
			
Here, it looks for potential sell triggers and calculates profit or loss for the sell trade in a manner similar to the buy trade.

Application in Backtesting

This function is designed to be applied iteratively to rows of data containing historical information about stock price movements. These rows should include the date, symbol, high, low, today’s opening price, buy target, and sell target.
Post a comment

Leave a Comment

Your email address will not be published. Required fields are marked *

×Close