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