Unable to connect XLWings

Hi TradeHull, I am unable to run my code, Its giving below error. Also while checking in ChatGPT it says. Python verison issue.


image

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

Hi @Rizwan ,

Yes, downgrading will work.
The issue is not related to the application logic, but due to a known compatibility limitation between Python 3.12 and Excel integration libraries.
Once Python is downgraded to a stable version ( greater then 3.8 ), the application will run correctly.