Rolling straddle

Do i need to enter exit condition and re-entry condition in case ATM strike changes in rolling short straddle or below code automatically square off trade if traded ATM is not ATM anymore.

I am going to take trade basis the ce_name and pe_name. Kindly suggest

ce_name, pe_name, strike = tsl.ATM_Strike_Selection(Underlying=‘SENSEX’, Expiry=0)

Hi @Sobhit

Do share the complete code as well,
ps :use </> box in the message box to post the code in it.

here it is full code.
<import pdb
import time
import datetime
import traceback
from Dhan_Tradehull import Tradehull
import pandas as pd
from pprint import pprint
import talib
import pandas_ta as ta
import xlwings as xw

Initialize Excel book and sheets

book = xw.Book(“Straddle.xlsx”)
Straddle_chart = book.sheets[‘Straddle Chart’]
config_sheet = book.sheets[‘Config’]
running_orders_sheet = book.sheets[‘Running Orders’]
completed_orders_sheet = book.sheets[‘Completed Orders’]
Straddle_chart.range(‘A1’).value = [‘Current Time’]
Straddle_chart.range(‘B1’).value = [‘Combined LTP’]
Straddle_chart.range(‘C1’).value = [‘Strike’]
Straddle_chart.range(‘D1’).value = [‘ROC’]

Initialize client and connection

client_code = “110088905xx”
token_id = “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzM5MDk5MTc3LCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMDg4OTA1NSJ9.bX2eeT5ZMHh689KIp_3dUzRzbohivQvgAkrbjZonf2tTq6c4soTcMqnlP6gR4wOIVY1ctBSu_tL4_T51kcFyTA”
tsl = Tradehull(client_code, token_id)

watchlist = [‘NIFTY’] # Changed from ‘SENSEX’ to ‘NIFTY’
candle_storage =
all_dataframes =

for name in watchlist:
# ------------------------------------- GET DATA -------------------------------------
ce_name, pe_name, strike = tsl.ATM_Strike_Selection(Underlying=‘NIFTY’, Expiry=0)
all_ltp = tsl.get_ltp_data(names=[ce_name, pe_name])
try:
ce_historical_data = tsl.get_historical_data(tradingsymbol=ce_name, exchange=‘NFO’, timeframe=“5”)
pe_historical_data = tsl.get_historical_data(tradingsymbol=pe_name, exchange=‘NFO’, timeframe=“5”)
except Exception as e:
print(f"Error fetching historical data: {str(e)}")
continue

    # Combine CE and PE close prices
combined_historical = pd.DataFrame()
combined_historical['price'] = ce_historical_data['close'] + pe_historical_data['close']

    # Calculate initial ROC
if len(combined_historical) >= 9:
    combined_historical['ROC'] = round(((combined_historical['price'] - combined_historical['price'].shift(9)) / 
                                             combined_historical['price'].shift(9)) * 100, 2)

current_time = datetime.datetime.now().time()

    # Fetch current LTP data with error handling
try:
    ce_ltp = all_ltp[ce_name]
    pe_ltp = all_ltp[pe_name]
    combined_ltp = ce_ltp + pe_ltp
except Exception as e:
    print(f"Error fetching LTP data: {str(e)}")
    continue

candle_storage.append({'Current time': current_time, 'combined_ltp': combined_ltp, 'strike': strike})

    # Create DataFrame from candle storage
df_to_send = pd.DataFrame(candle_storage)
df_to_send['Current time'] = df_to_send['Current time'].astype(str)

    # Prepare time-based data
current_date = datetime.datetime.now().date()
dfi = pd.DataFrame(candle_storage)
dfi['Current time'] = pd.to_datetime(current_date.strftime('%Y-%m-%d') + ' ' + dfi['Current time'].astype(str))
dfi.set_index('Current time', inplace=True)

    # Create combined dataset for ROC calculation
latest_data = pd.DataFrame({'price': [combined_ltp], 'timestamp': [pd.Timestamp.now()]}).set_index('timestamp')

all_data = pd.concat([combined_historical['price'], latest_data['price']]).to_frame()

    # Calculate final ROC using pandas_ta
all_data['ROC'] = ta.roc(all_data['price'], length=9)
latest_roc = all_data['ROC'].iloc[-1]

    # Check for invalid ROC value
if pd.isna(latest_roc):
    print("Invalid ROC value, skipping this loop iteration.")
    continue

latest_roc1 = round(latest_roc, 2)

    # Update Excel sheet with latest data
data_to_write = [[str(current_time), combined_ltp, strike, latest_roc1]]

single_order = {‘options_name’: None, ‘date’: None, ‘entry_time’: None, ‘ce_entry_price’: None, ‘pe_entry_price’: None, ‘buy_sell’: None,
‘qty’: None, ‘exit_time’: None, ‘exit_price’: None, ‘pnl’: None, ‘remark’: None,
‘traded’: None, “ce_entry_ordrid”: None, “pe_entry_ordrid”: None, ‘entry_datetime’: None, ‘re_entry_count’: 0}
orderbook = {}
completed_orders = [{‘options_name’: None, ‘date’: None, ‘entry_time’: None, ‘ce_entry_price’: None, ‘pe_entry_price’: None, ‘buy_sell’: None,
‘qty’: None, ‘exit_time’: None, ‘exit_price’: None, ‘pnl’: None, ‘remark’: None,
‘traded’: None, “ce_entry_ordrid”: None, “pe_entry_ordrid”: None, ‘entry_datetime’: None, ‘re_entry_count’: 0}]

for name in watchlist:
orderbook[name] = single_order.copy()

while True:
print(“Starting while loop\n\n”)

current_time = datetime.datetime.now().time()

if current_time < datetime.time(8, 15):
    print(f"Wait for market to start", current_time)
    time.sleep(1)
    continue

if current_time > datetime.time(23, 30):
    order_details = tsl.cancel_all_orders()
    print(f"Market over Closing all trades!! Bye Bye See you Tomorrow", current_time)
    break

# Move data collection and Excel update inside the main loop
last_row = 2
while Straddle_chart.range(f'A{last_row}').value is not None:
    last_row += 1
    if last_row > 30000:  # Safety limit
       last_row = 2  # Reset to top if sheet is full
       break

Straddle_chart.range(f'A{last_row}:D{last_row}').value = data_to_write

for name in watchlist:
    try:
        # Convert orderbook to DataFrame and update running orders sheet
        orderbook_df = pd.DataFrame(orderbook).T
        orderbook_df = orderbook_df.drop(columns=['entry_datetime'])
        running_orders_sheet.clear()  # Clear existing content
        running_orders_sheet.range('A1').options(index=True).value = orderbook_df
        running_orders_sheet.autofit()  # Autofit columns
        
        # Convert completed orders to DataFrame and update completed orders sheet  
        completed_orders_df = pd.DataFrame(completed_orders)
        if not completed_orders_df.empty:
            completed_orders_df = completed_orders_df.drop(columns=['entry_datetime'])
            completed_orders_sheet.clear()  # Clear existing content
            completed_orders_sheet.range('A1').options(index=True).value = completed_orders_df
            completed_orders_sheet.autofit()  # Autofit columns
        
        # Force sync to ensure updates are written
        running_orders_sheet.api.Calculate()
        completed_orders_sheet.api.Calculate()
    except Exception as e:
        print("Error in updating running orders sheet", e)
        
# Conditions for entry and exit
    try:
        First_cc = all_data.iloc[0]
        cc = all_data.iloc[-1]
        tc1 = cc['price'] < First_cc['price']
        tc2 = latest_roc < 0
        tc3 = orderbook[name]['traded'] is None
    except Exception as e:
        print("Error accessing data:", e)
        

    ec1 = latest_roc1 > 0  # ROC crossed above 0
    ec2 = current_time >= datetime.time(15, 15)  # Exit at 3:15 PM
    ec3 = orderbook[name]['traded'] == "yes"  # Check if trade is active

# ------------------------------------- ENTRY (Selling straddle) -------------------------------------   
if tc1 and tc2 and tc3:  # Ensure tc1, tc2 are valid booleans
    print("Entry condition met. Placing order...Short Straddle")
    try:
        ce_lot_size = tsl.get_lot_size(tradingsymbol=ce_name)
        pe_lot_size = tsl.get_lot_size(tradingsymbol=pe_name)

        # Set the quantity to 1 lot for both CE and PE
        ce_qty = ce_lot_size * 1
        pe_qty = pe_lot_size * 1

        print(f"Attempting to place CE order: Symbol={ce_name}, Qty={ce_qty}")
        ce_entry_ordrid = tsl.order_placement(tradingsymbol=ce_name, exchange='NFO', quantity=ce_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS',after_market_order=True)
        print(f"CE Order Response: {ce_entry_ordrid}")
        
        print(f"Attempting to place PE order: Symbol={pe_name}, Qty={pe_qty}")
        pe_entry_ordrid = tsl.order_placement(tradingsymbol=pe_name, exchange='NFO', quantity=pe_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS',after_market_order=True)
        print(f"PE Order Response: {pe_entry_ordrid}")
        orderbook[name]['ce_entry_ordrid'] = ce_entry_ordrid
        orderbook[name]['pe_entry_ordrid'] = pe_entry_ordrid
        orderbook[name]['entry_time'] = str(datetime.datetime.now().time())
        orderbook[name]['entry_datetime'] = datetime.datetime.now()
        orderbook[name]['traded'] = "yes"
    except Exception as e:
        print(f"Error placing orders: {str(e)}")
        print(f"Traceback: {traceback.format_exc()}")

# ------------------------------------- Exit Condition -------------------------------------
if (ec1 or ec2) and ec3:
    print("Exit condition met. Closing straddle position...")
    try:
        # Store exit details
        orderbook[name]['ce_name'] = ce_name
        orderbook[name]['pe_name'] = pe_name
        orderbook[name]['buy_sell'] = "BUY" 
        orderbook[name]['date'] = str(datetime.datetime.now().date())
        orderbook[name]['exit_time'] = str(datetime.datetime.now().time())
        orderbook[name]['exit_datetime'] = datetime.datetime.now()

        # Place sell orders to close straddle position
        ce_exit_ordrid = tsl.order_placement(tradingsymbol=orderbook[name]['ce_name'], exchange='NFO', quantity=orderbook[name]['ce_qty'], price=0, trigger_price=0, order_type='MARKET', transaction_type='BUY', trade_type='MIS')
        pe_exit_ordrid = tsl.order_placement(tradingsymbol=orderbook[name]['pe_name'], exchange='NFO', quantity=orderbook[name]['pe_qty'], price=0, trigger_price=0, order_type='MARKET', transaction_type='BUY', trade_type='MIS')
        

        # Store exit order IDs
        orderbook[name]['ce_exit_ordrid'] = ce_exit_ordrid
        orderbook[name]['pe_exit_ordrid'] = pe_exit_ordrid
        orderbook[name]['traded'] = None  # Reset traded status
        # Get exit prices with timeout and error handling
        ce_exit_price = tsl.get_executed_price(orderid=ce_exit_ordrid)
        pe_exit_price = tsl.get_executed_price(orderid=pe_exit_ordrid)

        if ce_exit_price is None or pe_exit_price is None:
            print("Failed to get exit prices, will retry next iteration")
            continue

        # Calculate PNL
        orderbook[name]['ce_pnl'] = (ce_exit_price - orderbook[name]['ce_entry_price']) * orderbook[name]['ce_qty']
        orderbook[name]['pe_pnl'] = (pe_exit_price - orderbook[name]['pe_entry_price']) * orderbook[name]['pe_qty']
        orderbook[name]['total_pnl'] = orderbook[name]['ce_pnl'] + orderbook[name]['pe_pnl']

        print(f"Straddle PnL: CE={orderbook[name]['ce_pnl']:.2f}, PE={orderbook[name]['pe_pnl']:.2f}, Total={orderbook[name]['total_pnl']:.2f}")
        
        print(f"Straddle position closed: CE Order ID = {ce_exit_ordrid}, PE Order ID = {pe_exit_ordrid}")
       
        # Re-entry condition check
        if tc1 and tc2 and tc3:
            print("Re-entry conditions met after exit. Attempting to re-enter straddle position...")
            try:
                # Place CE and PE buy orders for re-entry
                print(f"Attempting to place CE re-entry order: Symbol={ce_name}, Qty={ce_qty}")
                ce_entry_ordrid = tsl.order_placement(tradingsymbol=ce_name, exchange='NFO', quantity=ce_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS')
                print(f"CE Re-entry Order Response: {ce_entry_ordrid}")
                
                print(f"Attempting to place PE re-entry order: Symbol={pe_name}, Qty={pe_qty}")
                pe_entry_ordrid = tsl.order_placement(tradingsymbol=pe_name, exchange='NFO', quantity=pe_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS')
                print(f"PE Re-entry Order Response: {pe_entry_ordrid}")

                # Update orderbook with new entry details
                orderbook[name]['ce_entry_ordrid'] = ce_entry_ordrid
                orderbook[name]['pe_entry_ordrid'] = pe_entry_ordrid
                orderbook[name]['entry_time'] = str(datetime.datetime.now().time())
                orderbook[name]['entry_datetime'] = datetime.datetime.now()
                orderbook[name]['traded'] = "yes"
                orderbook[name]['re_entry_count'] = orderbook[name]['re_entry_count'] + 1

                print("Successfully re-entered straddle position")
            except Exception as e:
                print(f"Error during re-entry: {str(e)}")
                print(f"Traceback: {traceback.format_exc()}")
    except Exception as e:
        print(f"Error closing straddle position: {str(e)}")
        print(f"Traceback: {traceback.format_exc()}")
time.sleep(60)  # Wait for 1 minute before next update

Hi @Sobhit ,

Kindly click on </> and paste your complete code within it as the below image:
image

1 Like
import pdb
import time
import datetime
import traceback
from Dhan_Tradehull import Tradehull
import pandas as pd
from pprint import pprint
import talib
import pandas_ta as ta
import xlwings as xw

# Initialize Excel book and sheets
book = xw.Book("Straddle.xlsx")
Straddle_chart = book.sheets['Straddle Chart']
config_sheet = book.sheets['Config']
running_orders_sheet = book.sheets['Running Orders']
completed_orders_sheet = book.sheets['Completed Orders']
Straddle_chart.range('A1').value = ['Current Time']
Straddle_chart.range('B1').value = ['Combined LTP']
Straddle_chart.range('C1').value = ['Strike']
Straddle_chart.range('D1').value = ['ROC']

# Initialize client and connection
client_code = "1100889000"
token_id = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzM5MDk5MTc3LCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMDg4OTA1NSJ9.bX2eeT5ZMHh689KIp_3dUzRzbohivQvgAkrbjZonf2tTq6c4soTcMqnlP6gR4wOIVY1ctBSu_tL4_T51kcFyTA"
tsl = Tradehull(client_code, token_id)

watchlist = ['SENSEX']  # Changed from 'NIFTY' to 'SENSEX'
candle_storage = []
all_dataframes = []

single_order = {'options_name': None, 'date': None, 'entry_time': None, 'ce_entry_price': None, 'pe_entry_price': None, 'buy_sell': None,
                'qty': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None,
                'traded': None, "ce_entry_ordrid": None, "pe_entry_ordrid": None, 'entry_datetime': None, 're_entry_count': 0}
orderbook = {}
completed_orders = [{'options_name': None, 'date': None, 'entry_time': None, 'ce_entry_price': None, 'pe_entry_price': None, 'buy_sell': None,
                     'qty': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None,
                     'traded': None, "ce_entry_ordrid": None, "pe_entry_ordrid": None, 'entry_datetime': None, 're_entry_count': 0}]

for name in watchlist:
    orderbook[name] = single_order.copy()

while True:
    print("Starting while loop\n\n")
    
    current_time = datetime.datetime.now().time()

    # Market timing checks
    if current_time < datetime.time(8, 15):
        print(f"Wait for market to start", current_time)
        time.sleep(60)
        continue
    if current_time > datetime.time(23, 30):
        order_details = tsl.cancel_all_orders()
        print(f"Market over Closing all trades!! Bye Bye See you Tomorrow", current_time)
        break

    for name in watchlist:
        # ------------------------------------- GET DATA -------------------------------------
        ce_name, pe_name, strike = tsl.ATM_Strike_Selection(Underlying='SENSEX', Expiry=0)
        all_ltp = tsl.get_ltp_data(names=[ce_name, pe_name])
        try:
            ce_historical_data = tsl.get_historical_data(tradingsymbol=ce_name, exchange='BFO', timeframe="5")
            pe_historical_data = tsl.get_historical_data(tradingsymbol=pe_name, exchange='BFO', timeframe="5")
        except Exception as e:
            print(f"Error fetching historical data: {str(e)}")
            continue

        # Combine CE and PE close prices
        combined_historical = pd.DataFrame()
        combined_historical['price'] = ce_historical_data['close'] + pe_historical_data['close']

        # Calculate initial ROC
        if len(combined_historical) >= 9:
            combined_historical['ROC'] = round(((combined_historical['price'] - combined_historical['price'].shift(9)) / 
                                                 combined_historical['price'].shift(9)) * 100, 2)

        current_time = datetime.datetime.now().time()

        # Fetch current LTP data with error handling
        try:
            ce_ltp = all_ltp[ce_name]
            pe_ltp = all_ltp[pe_name]
            combined_ltp = ce_ltp + pe_ltp
        except Exception as e:
            print(f"Error fetching LTP data: {str(e)}")
            continue

        candle_storage.append({'Current time': current_time, 'combined_ltp': combined_ltp, 'strike': strike})

        # Create DataFrame from candle storage
        df_to_send = pd.DataFrame(candle_storage)
        df_to_send['Current time'] = df_to_send['Current time'].astype(str)

        # Prepare time-based data
        current_date = datetime.datetime.now().date()
        dfi = pd.DataFrame(candle_storage)
        dfi['Current time'] = pd.to_datetime(current_date.strftime('%Y-%m-%d') + ' ' + dfi['Current time'].astype(str))
        dfi.set_index('Current time', inplace=True)

        # Create combined dataset for ROC calculation
        latest_data = pd.DataFrame({'price': [combined_ltp], 'timestamp': [pd.Timestamp.now()]}).set_index('timestamp')

        all_data = pd.concat([combined_historical['price'], latest_data['price']]).to_frame()

        # Calculate final ROC using pandas_ta
        all_data['ROC'] = ta.roc(all_data['price'], length=9)
        latest_roc = all_data['ROC'].iloc[-1]

        # Check for invalid ROC value
        if pd.isna(latest_roc):
            print("Invalid ROC value, skipping this loop iteration.")
            continue

        latest_roc1 = round(latest_roc, 2)

        # Update Excel sheet with latest data
        data_to_write = [[str(current_time), combined_ltp, strike, latest_roc1]]

        last_row = 2
        while Straddle_chart.range(f'A{last_row}').value is not None:
            last_row += 1
        if last_row > 30000:  # Safety limit
            last_row = 2  # Reset to top if sheet is full
            break

        Straddle_chart.range(f'A{last_row}:D{last_row}').value = data_to_write

        # ------------------------------------- UPDATE SHEET -------------------------------------
        try:
            # Convert orderbook to DataFrame and update running orders sheet
            orderbook_df = pd.DataFrame(orderbook).T
            orderbook_df = orderbook_df.drop(columns=['entry_datetime'])
            running_orders_sheet.clear()  # Clear existing content
            running_orders_sheet.range('A1').options(index=True).value = orderbook_df
        except Exception as e:
            print("Error in updating running orders sheet", e)

        # Convert completed orders to DataFrame and update completed orders sheet  
        try:
            completed_orders_df = pd.DataFrame(completed_orders)
            if not completed_orders_df.empty:
                completed_orders_df = completed_orders_df.drop(columns=['entry_datetime'])
                completed_orders_sheet.clear()  # Clear existing content
                completed_orders_sheet.range('A1').options(index=True).value = completed_orders_df

            # Autofit after data is written
            running_orders_sheet.autofit()
            completed_orders_sheet.autofit()
        except Exception as e:
            print("Error in updating completed orders sheet", e)

        # ------------------------------------- ADD ROW TO EXCEL -------------------------------------

        # Conditions for entry and exit
        try:
            First_cc = all_data.iloc[0]
            cc = all_data.iloc[-1]
            tc1 = cc['price'] < First_cc['price']  # Compare the price values directly
            tc2 = latest_roc1 < 0
            tc3 = orderbook[name]['traded'] is None
        except Exception as e:
            print("Error accessing data:", e)

        ec1 = latest_roc1 > 0  # ROC crossed above 0
        ec2 = orderbook[name]['traded'] == "yes"  # Check if trade is active
        ec3 = current_time >= datetime.time(15, 15)  # Exit at 3:15 PM

        # ------------------------------------- ENTRY (Selling straddle) -------------------------------------   
        if tc1 and tc2 and tc3:  # Ensure tc1, tc2 are valid booleans
            print("Entry condition met. Placing order...Short Straddle")
            try:
                ce_lot_size = tsl.get_lot_size(tradingsymbol=ce_name)
                pe_lot_size = tsl.get_lot_size(tradingsymbol=pe_name)

                # Set the quantity to 1 lot for both CE and PE
                ce_qty = ce_lot_size * 1
                pe_qty = pe_lot_size * 1

                print(f"Attempting to place CE order: Symbol={ce_name}, Qty={ce_qty}")
                ce_entry_ordrid = tsl.order_placement(tradingsymbol=ce_name, exchange='BFO', quantity=ce_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS', after_market_order=True)
                print(f"CE Order Response: {ce_entry_ordrid}")

                print(f"Attempting to place PE order: Symbol={pe_name}, Qty={pe_qty}")
                pe_entry_ordrid = tsl.order_placement(tradingsymbol=pe_name, exchange='BFO', quantity=pe_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS', after_market_order=True)
                print(f"PE Order Response: {pe_entry_ordrid}")
                orderbook[name]['ce_entry_ordrid'] = ce_entry_ordrid
                orderbook[name]['pe_entry_ordrid'] = pe_entry_ordrid
                orderbook[name]['entry_time'] = str(datetime.datetime.now().time())
                orderbook[name]['entry_datetime'] = datetime.datetime.now()
                orderbook[name]['traded'] = "yes"
            except Exception as e:
                print(f"Error placing orders: {str(e)}")
                print(f"Traceback: {traceback.format_exc()}")

        # ------------------------------------- Exit Condition -------------------------------------
        if (ec1 or ec3) and ec2:
            print("Exit condition met. Closing straddle position...")
            try:
                # Store exit details
                orderbook[name]['ce_name'] = ce_name
                orderbook[name]['pe_name'] = pe_name
                orderbook[name]['buy_sell'] = "BUY" 
                orderbook[name]['date'] = str(datetime.datetime.now().date())
                orderbook[name]['exit_time'] = str(datetime.datetime.now().time())
                orderbook[name]['exit_datetime'] = datetime.datetime.now()

                # Place sell orders to close straddle position
                ce_exit_ordrid = tsl.order_placement(tradingsymbol=orderbook[name]['ce_name'], exchange='BFO', quantity=orderbook[name]['ce_qty'], price=0, trigger_price=0, order_type='MARKET', transaction_type='BUY', trade_type='MIS')
                pe_exit_ordrid = tsl.order_placement(tradingsymbol=orderbook[name]['pe_name'], exchange='BFO', quantity=orderbook[name]['pe_qty'], price=0, trigger_price=0, order_type='MARKET', transaction_type='BUY', trade_type='MIS')

                # Store exit order IDs
                orderbook[name]['ce_exit_ordrid'] = ce_exit_ordrid
                orderbook[name]['pe_exit_ordrid'] = pe_exit_ordrid
                orderbook[name]['traded'] = None  # Reset traded status
            except Exception as e:
                print("Error in placing exit orders", e)

            # Get exit prices with timeout and error handling
            try:
                ce_exit_price = tsl.get_executed_price(orderid=ce_exit_ordrid)
                pe_exit_price = tsl.get_executed_price(orderid=pe_exit_ordrid)

                if ce_exit_price is None or pe_exit_price is None:
                    print("Failed to get exit prices, will retry next iteration")
                    continue

                # Calculate PNL
                orderbook[name]['ce_pnl'] = (ce_exit_price - orderbook[name]['ce_entry_price']) * orderbook[name]['ce_qty']
                orderbook[name]['pe_pnl'] = (pe_exit_price - orderbook[name]['pe_entry_price']) * orderbook[name]['pe_qty']
                orderbook[name]['total_pnl'] = orderbook[name]['ce_pnl'] + orderbook[name]['pe_pnl']

                print(f"Straddle PnL: CE={orderbook[name]['ce_pnl']:.2f}, PE={orderbook[name]['pe_pnl']:.2f}, Total={orderbook[name]['total_pnl']:.2f}")

                print(f"Straddle position closed: CE Order ID = {ce_exit_ordrid}, PE Order ID = {pe_exit_ordrid}")
            
                # Re-entry condition check
                if tc1 and tc2 and tc3:
                    print("Re-entry conditions met after exit. Attempting to re-enter straddle position...")
                    try:
                        # Place CE and PE buy orders for re-entry
                        print(f"Attempting to place CE re-entry order: Symbol={ce_name}, Qty={ce_qty}")
                        ce_entry_ordrid = tsl.order_placement(tradingsymbol=ce_name, exchange='BFO', quantity=ce_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS')
                        print(f"CE Re-entry Order Response: {ce_entry_ordrid}")

                        print(f"Attempting to place PE re-entry order: Symbol={pe_name}, Qty={pe_qty}")
                        pe_entry_ordrid = tsl.order_placement(tradingsymbol=pe_name, exchange='BFO', quantity=pe_qty, price=0, trigger_price=0, order_type='MARKET', transaction_type='SELL', trade_type='MIS')
                        print(f"PE Re-entry Order Response: {pe_entry_ordrid}")

                        # Update orderbook with new entry details
                        orderbook[name]['ce_entry_ordrid'] = ce_entry_ordrid
                        orderbook[name]['pe_entry_ordrid'] = pe_entry_ordrid
                        orderbook[name]['entry_time'] = str(datetime.datetime.now().time())
                        orderbook[name]['entry_datetime'] = datetime.datetime.now()
                        orderbook[name]['traded'] = "yes"
                    except Exception as e:
                        print(f"Error during re-entry: {str(e)}")
                        print(f"Traceback: {traceback.format_exc()}")
            except Exception as e:
                print(f"Error closing straddle position: {str(e)}")
                print(f"Traceback: {traceback.format_exc()}")

    time.sleep(60)  # Delay between iterations (for checking conditions every minute)

Also, please check if my code for calculating ROC is correct as its value does not match with what i can see on broker;s chart

Hi @Sobhit ,

We have gone through the code, the code doesn’t exit or re-enter automatically when the ATM is changed.

Hi Priya, so what is required to be done to automatically square off position once ATM strike gets changed and re-enter new strike? Do i need to add exit and re-entry condition?

Hi @Sobhit ,

Yes Sobhit, you need to add other conditions to exit and re-enter new strike

is ROC calculation is correct in my code for the parameter as length 9?

Hi @Sobhit ,

Do follow this thread for the solution.