import pandas as pd
import numpy as np
import datetime
import time
from Dhan_Tradehull_V2 import Tradehull
import talib
import pdb
import numpy as np
import pandas as pd
Disable warnings
import warnings
warnings.filterwarnings(“ignore”)
------------------------- Setup and Login -------------------------
client_code = “115”
token_id = “eyJ0eXAiOiJKVicGFydG5lcklkIjoiIiwiZXhwIjoxNzM1NTMxMjYyLCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMjE5Mzg1NSJ9.uLGNNiYIPZS1maxnjFNuNB1DvqwpXsPv01bbOqsJ9JxPMFyLz1D_xBdtbRnq-SYUNqDVPwi41b_zqZl8y-XXwg”
tsl = Tradehull(client_code, token_id)
Constants
INDEX_NAME = ‘NIFTY NOV FUT’
TRADE_INFO = {“options_name”: None, “qty”: None, “sl”: None, “target”: None, “CE_PE”: None, “entry_price”: None}
MAX_LOTS = 1 # Restrict to one lot per trade
TRADE_TIME_LIMIT = datetime.time(15, 15) # Close all positions by 15:15
def calculate_bos_choch(df):
“”“Identify BOS (Break of Structure) and CHOCH (Change of Character) levels.”“”
# Calculate previous high and low
df[‘prev_high’] = df[‘high’].shift(1)
df[‘prev_low’] = df[‘low’].shift(1)
# Identify Break of Structure (BOS)
df['bos'] = np.where(
df['close'] > df['prev_high'], 'BOS_UP',
np.where(df['close'] < df['prev_low'], 'BOS_DOWN', None)
)
# Identify Change of Character (CHOCH)
df['choch'] = np.where(
(df['bos'] == 'BOS_UP') & (df['low'] < df['prev_low']), 'CHOCH_DOWN',
np.where((df['bos'] == 'BOS_DOWN') & (df['high'] > df['prev_high']), 'CHOCH_UP', None)
)
return df
def place_order(option_name, order_type, lot_size):
“”“Place an order and update trade information.”“”
order_id = tsl.order_placement(option_name, ‘NFO’, lot_size, 0, 0, ‘MARKET’, order_type, ‘MIS’)
TRADE_INFO[‘options_name’] = option_name
TRADE_INFO[‘qty’] = lot_size
TRADE_INFO[‘entry_price’] = tsl.get_executed_price(orderid=order_id)
return order_id
def close_all_positions():
“”“Close all open positions.”“”
if TRADE_INFO[‘options_name’]:
print(“Closing all open positions…”)
tsl.order_placement(TRADE_INFO[‘options_name’], ‘NFO’, TRADE_INFO[‘qty’], 0, 0, ‘MARKET’, ‘SELL’, ‘MIS’)
TRADE_INFO.update({“options_name”: None, “qty”: None, “sl”: None, “target”: None, “CE_PE”: None, “entry_price”: None})
else:
print(“No positions to close.”)
------------------------- Trading Logic -------------------------
while True:
current_time = datetime.datetime.now().time()
# Wait for market to open
if current_time < datetime.time(9, 20):
print("Waiting for market to start...", current_time)
time.sleep(60)
continue
# Exit all positions and stop trading at 15:15
if current_time >= TRADE_TIME_LIMIT:
close_all_positions()
print("Market is over. See you tomorrow.")
break
try:
# Fetch historical data
index_chart = tsl.get_historical_data(tradingsymbol=INDEX_NAME, exchange='NFO', timeframe="1")
if index_chart.empty:
time.sleep(60)
continue
print(index_chart)
# Add BOS and CHOCH indicators
index_chart = calculate_bos_choch(index_chart)
last_candle = index_chart.iloc[-1]
# Check for entries
if not TRADE_INFO['options_name']: # Only 1 active position allowed
if last_candle['bos'] == 'BOS_UP':
print("BOS_UP detected. Buying CALL.")
ce_name, _, _ = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry='19-12-2024')
lot_size = tsl.get_lot_size(ce_name)
entry_price = tsl.get_ltp_data(names=[ce_name])
stop_loss = last_candle['low']
target_price = entry_price + 3 * (entry_price - stop_loss)
place_order(ce_name, 'BUY', MAX_LOTS)
TRADE_INFO.update({
"options_name": ce_name,
"qty": MAX_LOTS,
"entry_price": entry_price,
"sl": stop_loss,
"target": target_price,
"CE_PE": "CE"
})
elif last_candle['bos'] == 'BOS_DOWN':
print("BOS_DOWN detected. Buying PUT.")
_, pe_name, _ = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry='19-12-2024')
lot_size = tsl.get_lot_size(pe_name)
entry_price = tsl.get_ltp_data(names=[pe_name])
stop_loss = last_candle['high']
target_price = entry_price - 3 * (stop_loss - entry_price)
place_order(pe_name, 'BUY', MAX_LOTS)
TRADE_INFO.update({
"options_name": pe_name,
"qty": MAX_LOTS,
"entry_price": entry_price,
"sl": stop_loss,
"target": target_price,
"CE_PE": "PE"
})
# Manage open trades
if TRADE_INFO['options_name']:
option_ltp = tsl.get_ltp_data(names=[TRADE_INFO['options_name']])
if TRADE_INFO['CE_PE'] == "CE":
if option_ltp <= TRADE_INFO['sl']:
print("SL Hit for CALL. Exiting.")
close_all_positions()
elif option_ltp >= TRADE_INFO['target']:
print("Target Hit for CALL. Exiting.")
close_all_positions()
elif TRADE_INFO['CE_PE'] == "PE":
if option_ltp >= TRADE_INFO['sl']:
print("SL Hit for PUT. Exiting.")
close_all_positions()
elif option_ltp <= TRADE_INFO['target']:
print("Target Hit for PUT. Exiting.")
close_all_positions()
time.sleep(10)
except Exception as e:
print("Error:", e)
time.sleep(60)