Hi TradeHull, I am unable to run my code, Its giving below error. Also while checking in ChatGPT it says. Python verison issue.
Kindly suggest, If I down grade will it work.Also I am pasting my complete code below for your reference.
Blockquote
import tradehull
import talib
import datetime
import time
import pandas as pd
import pandas_ta as ta
import xlwings as xw
import pickle
from collections import deque
from paper_patch import apply_paper_trading
===============================
INITIALIZATION
===============================
TH = tradehull.Tradehull(“”, “”, “yes”)
kite = TH.kite
apply_paper_trading(kite)
print(“\n\n”)
watchlist = [“NIFTY 50”]
single_order_status = {
‘name’: None, ‘date’: str(datetime.date.today())
, ‘entry_time’: None,
‘qty’: None, ‘sl’: None, ‘tg’: None,
‘exit_time’: None, ‘pnl’: None,
‘traded’: None, ‘combined_premium’: None,‘atm_ce’: None,
‘atm_pe’: None,
‘otm_ce’: None,
‘otm_pe’: None
}
orderbook = {name: single_order_status.copy() for name in watchlist}
===============================
EXCEL
===============================
workbook = xw.Book(‘Live Algo_Sell_V2.xlsx’)
Configuration = workbook.sheets[‘Configuration’]
live_orderbook = workbook.sheets[‘live_orderbook’]
===============================
CONFIG
===============================
reentry = “yes”
MAX_TRADES_PER_DAY = 2
DAILY_MAX_LOSS = 10000
AVG_5D_RANGE = 350
trade_count = 0
daily_pnl = 0
combined_premium_window = deque(maxlen=3) # 15 min window
day_high = -1
day_low = 10**9
def compute_underlying_context(name: str):
df = TH.get_short_length_hist_data(
name=name, exchange=“NSE”, interval=“5minute”, oi=True
)
if df is None or df.empty or len(df) < 30:
return None
df["rsi"] = talib.RSI(df["close"], 10)
df["atr"] = talib.ATR(df["high"], df["low"], df["close"], 14)
df["previous_rsi"] = df["rsi"].shift(1)
df["nifty_vol_ma"] = df["volume"].rolling(8).mean()
sqn_lib.sqn(df=df, period=14)
df["market_type"] = df["sqn"].apply(sqn_lib.market_type)
df.dropna(inplace=True)
completed_candle = df.iloc[-1]
try:
vix = TH.get_data_for_single_script("NSE", "INDIA VIX", "ltp") or 20
except Exception:
vix = 20
df["swing_high"] = dynamic_swing_highs(df, vix)
df["swing_low"] = dynamic_swing_lows(df, vix)
swing_highs_df = df[df["swing_high"]]
swing_lows_df = df[df["swing_low"]]
recent_resistance = (
swing_highs_df["high"].iloc[-1] if not swing_highs_df.empty else None
)
recent_support = (
swing_lows_df["low"].iloc[-1] if not swing_lows_df.empty else None
)
try:
df_15 = TH.get_short_length_hist_data(
name=name, exchange="NSE", interval="15minute", oi=False
)
df_15["ema20"] = talib.EMA(df_15["close"], 20)
trend_up = df_15["close"].iloc[-1] > df_15["ema20"].iloc[-1]
except Exception:
trend_up = True
return completed_candle, (recent_resistance, recent_support, df), trend_up
===============================
MAIN LOOP
===============================
while True:
current_time = datetime.datetime.now().time()
if current_time < datetime.time(9, 45):
print("⏳ Waiting for valid trading window")
continue
if current_time > datetime.time(21, 30):
print("⏹ Entry window closed")
break
if trade_count >= MAX_TRADES_PER_DAY:
print("📛 Max trades reached")
break
for name in watchlist:
live_orderbook.range('A1').value = pd.DataFrame(orderbook).T
# ===============================
# MARKET DATA
# ===============================
ltp = TH.get_data_for_single_script("NSE", name, "ltp")
day_high = max(day_high, ltp)
day_low = min(day_low, ltp)
day_range = day_high - day_low
if day_range > 1.2 * AVG_5D_RANGE:
print("🚫 Trend day detected")
continue
# ===============================
# CONTEXT FETCH (REQUIRED)
# ===============================
context = compute_underlying_context(name)
if context is None:
print("⌛ Context not ready")
continue
completed_candle, (recent_resistance, recent_support, df_ctx), trend_up = context
# ===============================
# ENTRY FILTERS (CONTEXT-BASED)
# ===============================
# 1️⃣ Market regime filter (MOST IMPORTANT)
if completed_candle["market_type"] not in ["RANGE", "WEAK_TREND"]:
print("🚫 Market not suitable (SQN)")
continue
# 2️⃣ RSI stability filter
if not (45 <= completed_candle["rsi"] <= 55):
print("🚫 RSI outside neutral zone")
continue
if abs(completed_candle["rsi"] - completed_candle["previous_rsi"]) > 5:
print("🚫 RSI momentum expanding")
continue
# 3️⃣ ATR compression filter
atr_ma = df_ctx["atr"].rolling(20).mean().iloc[-1]
if completed_candle["atr"] > atr_ma:
print("🚫 ATR expanding")
continue
# 4️⃣ Volume contraction filter
if completed_candle["volume"] > completed_candle["nifty_vol_ma"] * 1.2:
print("🚫 Volume expansion")
continue
# 5️⃣ Support / Resistance distance filter
ltp = TH.get_data_for_single_script("NSE", name, "ltp")
if recent_support and abs(ltp - recent_support) < completed_candle["atr"]:
print("🚫 Near support")
continue
if recent_resistance and abs(ltp - recent_resistance) < completed_candle["atr"]:
print("🚫 Near resistance")
continue
# ===============================
# OPTION PRICING (REQUIRED)
# ===============================
atm_ce, _, _ = TH.get_atm(ltp, name, 0, "CE")
atm_pe, _, _ = TH.get_atm(ltp, name, 0, "PE")
atm_ce_ltp = TH.get_data_for_single_script("NFO", atm_ce, "ltp")
atm_pe_ltp = TH.get_data_for_single_script("NFO", atm_pe, "ltp")
combined_premium = atm_ce_ltp + atm_pe_ltp
# ===============================
# ENTRY
# ===============================
if orderbook[name]['traded'] is None:
distance = int(combined_premium / 75) + 1
otm_ce = TH.get_otm(ltp, name, 0, distance, "CE")
otm_pe = TH.get_otm(ltp, name, 0, distance, "PE")
qty = TH.get_lot_size(otm_ce)
kite.place_order(exchange="NFO", tradingsymbol=otm_ce,
transaction_type="BUY", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=otm_pe,
transaction_type="BUY", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=atm_ce,
transaction_type="SELL", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=atm_pe,
transaction_type="SELL", quantity=qty,
product="MIS", order_type="MARKET")
orderbook[name].update({
'name': name,
'entry_time': str(datetime.datetime.now().time()),
'qty': qty,
'combined_premium': combined_premium,
'sl': combined_premium * 1.22,
'tg': combined_premium * 0.82,
'traded': "yes",
'atm_ce': atm_ce,
'atm_pe': atm_pe,
'otm_ce': otm_ce,
'otm_pe': otm_pe
})
from paper_patch import send_telegram
entry_msg = (
"🟢 *NEW TRADE ENTERED_Sell_* \n\n"
f"📌 Instrument : {name}\n"
f"⏰ Time : {datetime.datetime.now().strftime('%H:%M:%S')}\n"
f"💰 Premium : {combined_premium:.2f}\n"
f"🛑 SL : {orderbook[name]['sl']:.2f}\n"
f"🎯 TG : {orderbook[name]['tg']:.2f}\n"
f"📦 Qty : {orderbook[name]['qty']}\n"
f"📊 RSI (5m) : {completed_candle['rsi']:.2f}\n"
f"📈 Day Range : {day_range:.2f}\n"
"\n⚙️ Mode: PAPER TRADING"
)
send_telegram(entry_msg)
trade_count += 1
print("✅ Trade entered")
# ===============================
# EXIT
# ===============================
if orderbook[name]['traded'] == "yes":
atm_ce = orderbook[name]['atm_ce']
atm_pe = orderbook[name]['atm_pe']
otm_ce = orderbook[name]['otm_ce']
otm_pe = orderbook[name]['otm_pe']
qty = orderbook[name]['qty']
running_ce = TH.get_data_for_single_script("NFO", atm_ce, "ltp")
running_pe = TH.get_data_for_single_script("NFO", atm_pe, "ltp")
running_cp = running_ce + running_pe
sl_hit = running_cp >= orderbook[name]['sl']
tg_hit = running_cp <= orderbook[name]['tg']
if sl_hit or tg_hit:
kite.place_order(exchange="NFO", tradingsymbol=atm_ce,
transaction_type="BUY", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=atm_pe,
transaction_type="BUY", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=otm_ce,
transaction_type="SELL", quantity=qty,
product="MIS", order_type="MARKET")
kite.place_order(exchange="NFO", tradingsymbol=otm_pe,
transaction_type="SELL", quantity=qty,
product="MIS", order_type="MARKET")
pnl = (orderbook[name]['combined_premium'] - running_cp) * qty
daily_pnl += pnl
orderbook[name]['exit_time'] = str(datetime.datetime.now().time())
orderbook[name]['pnl'] = pnl
print(f"🚪 Exit | PnL: {pnl:.2f}")
exit_reason = "STOP LOSS 🛑" if sl_hit else "TARGET HIT 🎯"
exit_msg = (
"🔴 *TRADE EXITED* \n\n"
f"📌 Instrument : {name}\n"
f"⏰ Exit Time : {datetime.datetime.now().strftime('%H:%M:%S')}\n"
f"📍 Reason : {exit_reason}\n"
f"💰 Entry CP : {orderbook[name]['combined_premium']:.2f}\n"
f"💰 Exit CP : {running_cp:.2f}\n"
f"📦 Qty : {orderbook[name]['qty']}\n"
f"📈 PnL : {pnl:.2f}\n"
f"📉 Daily PnL : {daily_pnl:.2f}\n"
)
send_telegram(exit_msg)
live_orderbook.range('A1').value = pd.DataFrame(orderbook).T
time.sleep(1) # allow Excel to capture exit
orderbook[name] = single_order_status.copy()
if daily_pnl <= -DAILY_MAX_LOSS:
print("🛑 Daily max loss hit")
TH.market_over_close_all_order()
break
# ===============================
# BOT SHUTDOWN CONDITIONS
# ===============================
if (
current_time > datetime.time(21, 30)
or trade_count >= MAX_TRADES_PER_DAY
or daily_pnl <= -DAILY_MAX_LOSS
):
shutdown_msg = (
"🛑 *BOT STOPPED* \n\n"
f"⏰ Time : {datetime.datetime.now().strftime('%H:%M:%S')}\n"
f"📊 Trades : {trade_count}\n"
f"📉 Daily PnL : {daily_pnl:.2f}\n"
"📌 Reason : Trading conditions exhausted\n\n"
"🤖 Status : SAFE SHUTDOWN"
)
send_telegram(shutdown_msg)
print("🛑 Bot stopped safely")
break
time.sleep(5)
===============================
SAVE STATE
===============================
with open(“orderbook_pickle”, “ab”) as f:
pickle.dump(orderbook, f)
Blockquote
