Option Call/Put buy based on RSI and 5min candle

@Tradehull_Imran

Hi, I am doing option trading call/put buy based on RSI and 5 min green/ red candle. I am using data column ‘Symbol’ which is storing all F&O stocks

So can you clarify me why the below errors coming and how to rectify it so that if less volume in options could also be able to buy.

Note: i want to use strike price having maximum vol /delta OTM position so what will be the syntax to pick it.

PAPER_MODE = False
MAX_TRADES = 5
MAX_LOTS = 2
TOTAL_CAPITAL = 9000
PARTIAL_TARGET1 = 1.47
TRADE_TYPE = “MIS”

STOP_ENTRY_TIME = datetime.time(14,45)
FORCE_EXIT_TIME = datetime.time(15.10)

IGNORE_SYMBOLS = {
“NIFTY”,“BANKNIFTY”,“FINNIFTY”,“MIDCPNIFTY”,“NIFTYNXT50”
}

positions = {}
traded_symbols = set()

def get_5m_candles(symbol):
data = tsl.get_historical_data(symbol, “NSE”, “5”)
df = pd.DataFrame(data)
return df if len(df) >= 20 else None

def get_ltp(symbol):
try:
if not isinstance(symbol, str):
print(f"Invalid symbol type for LTP: {symbol}")
return None

    res = tsl.get_ltp_data(names=symbol)

    if not res or symbol not in res:
        print(f"LTP fetch failed for {symbol}: {res}")
        return None

    ltp = res[symbol]
    if ltp is None or ltp <= 0:
        print(f"Invalid LTP value for {symbol}: {ltp}")
        return None

    return float(ltp)

except Exception as e:
    print(f"Exception at calling ltp for {symbol}: {e}")
    return None

CE, PE, _, _ = tsl.OTM_Strike_Selection(Underlying=symbol, Expiry=0, OTM_count=1)

        opt = CE if direction == "CE" else PE
        opt = str(opt).strip()   # CRITICAL FIX

        ltp = get_ltp(opt)
        if ltp is None:
            continue   

lot = tsl.get_lot_size(tradingsymbol=opt)

qty = MAX_LOTS * lot

if not PAPER_MODE:
            tsl.order_placement(
                tradingsymbol=opt, exchange="NFO",
                quantity=qty, price=0, trigger_price=0,
                order_type="MARKET", transaction_type="BUY",
                trade_type=TRADE_TYPE
            )

Exception at calling ltp as {‘status’: ‘failure’, ‘remarks’: {‘error_code’: None, ‘error_type’: None, ‘error_message’: None}, ‘data’: ‘’}
LTP fetch failed for BANKINDIA 27 JAN 165 CALL: {}
:next_track_button: Skipping BANKINDIA 27 JAN 165 CALL due to LTP failure
Exception at calling ltp as {‘status’: ‘failure’, ‘remarks’: {‘error_code’: None, ‘error_type’: None, ‘error_message’: None}, ‘data’: ‘’}
LTP fetch failed for WIPRO 27 JAN 245 PUT: {}
:next_track_button: Skipping WIPRO 27 JAN 245 PUT due to LTP failure
Exception at calling ltp as {‘status’: ‘failure’, ‘remarks’: {‘error_code’: None, ‘error_type’: None, ‘error_message’: None}, ‘data’: ‘’}
LTP fetch failed for RBLBANK 27 JAN 295 PUT: {}
:next_track_button: Skipping RBLBANK 27 JAN 295 PUT due to LTP failure
Exception at calling ltp as {‘status’: ‘failure’, ‘remarks’: {‘error_code’: None, ‘error_type’: None, ‘error_message’: None}, ‘data’: ‘’}
LTP fetch failed for 360ONE 27 JAN 1180 PUT: {}
:next_track_button: Skipping 360ONE 27 JAN 1180 PUT due to LTP failure

Also let me know your advance video where i can find option buying call/ put without using XLS storing information that video i had already watched . I want simple steps with easy syntax, please guide me.

Hi @Krushna_Rout ,

Looks like the login didn’t go through. Do regenerate the access token, confirm the correct client ID, and rerun the system.

If you want us to review the code, please share the complete code in a properly formatted way, paste it inside Preformatted Text for easier review.
image

Hi,again find my details as under:
I am doing option trading call/put buy based on RSI and 5 min green/ red candle. I am using data column ‘Symbol’ which is storing all F&O stocks

So can you clarify me why the below errors coming and how to rectify it so that if less volume in options could also be able to buy.

Note: i want to use strike price having maximum vol /delta OTM position so what will be the syntax to pick it.

PAPER_MODE = False
MAX_TRADES = 5
MAX_LOTS = 2
TOTAL_CAPITAL = 9000
PARTIAL_TARGET1 = 1.47
TRADE_TYPE = “MIS”

STOP_ENTRY_TIME = datetime.time(14,45)
FORCE_EXIT_TIME = datetime.time(15.10)

IGNORE_SYMBOLS = {
“NIFTY”,“BANKNIFTY”,“FINNIFTY”,“MIDCPNIFTY”,“NIFTYNXT50”
}

positions = {}
traded_symbols = set()

def get_5m_candles(symbol):
data = tsl.get_historical_data(symbol, “NSE”, “5”)
df = pd.DataFrame(data)
return df if len(df) >= 20 else None

def get_ltp(symbol):
    try:
        symbol = normalize_symbol(symbol)
        if not symbol:
            return None

        res = tsl.get_ltp_data(names=[symbol])

        if not res or res.get("status") != "success":
            return None

        data = res.get("data", [])
        if not data or data[0].get("ltp") is None:
            return None

        return float(data[0]["ltp"])

    except Exception:
        return None

except Exception as e:
    print(f"Exception at calling ltp for {symbol}: {e}")
    return None
CE, PE, _, _ = tsl.OTM_Strike_Selection(Underlying=symbol, Expiry=0, OTM_count=1)

        opt = CE if direction == "CE" else PE
        opt = str(opt).strip()   # CRITICAL FIX

        ltp = get_ltp(opt)
        if ltp is None:
            continue   
lot = tsl.get_lot_size(tradingsymbol=opt)

qty = MAX_LOTS * lot

if not PAPER_MODE:
            tsl.order_placement(
                tradingsymbol=opt, exchange="NFO",
                quantity=qty, price=0, trigger_price=0,
                order_type="MARKET", transaction_type="BUY",
                trade_type=TRADE_TYPE
            )
Exception for instrument name {'exchange': 'NFO', 'tradingsymbol': 'DRREDDY 27 JAN 1170 PUT'} as 'dict' object has no attribute 'upper'
Exception for instrument name {'exchange': 'NFO', 'tradingsymbol': 'PERSISTENT 27 JAN 6000 PUT'} as 'dict' object has no attribute 'upper'
Exception at calling ltp as {'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''}
Exception for instrument name {'exchange': 'NFO', 'tradingsymbol': 'UNITDSPR 27 JAN 1270 PUT'} as 'dict' object has no attribute 'upper'
Exception at calling ltp as {'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''}


Also let me know your advance video where i can find option buying call/ put without using XLS storing information that video i had already watched . I want simple steps with easy syntax, please guide me.

Sir, Waiting for your reply

Hi @Krushna_Rout ,

  1. Make sure you have subscribed to Data API’s.
  2. Kindly revoke the existing token and generate new token and use the new token.
  3. Also make sure the client id passed is correct.

Excel is not required mandatorily, we can instead use hardcoded, values.

Also use below code for “i want to use strike price having maximum vol /delta OTM position so what will be the syntax to pick it.”

expiry_no    = tsl.get_expiry_list('NIFTY', 'INDEX').index(tsl.get_expiry_list('NIFTY', 'NFO')[1])
atm, oc      = tsl.get_option_chain(Underlying="NIFTY", exchange="INDEX", expiry=expiry_no, num_strikes=50)

selling_strike           = str(int(oc[oc['CE Delta'].between(0.10, 0.16)].sort_values('CE OI').iloc[-1]['Strike Price']))
hedging_strike           = str(int(oc[oc['CE Delta'].between(0.07, 0.09)].sort_values('CE OI').iloc[-1]['Strike Price']))

ce_name, pe_name, strike = tsl.ATM_Strike_Selection(Underlying=name, Expiry=expiry_no)
nap                       = ce_name.split(" ")  # name parts
selling_name             = f"{name} {nap[1]} {nap[2]} {selling_strike} CALL"
hedging_name             = f"{name} {nap[1]} {nap[2]} {hedging_strike} CALL"

lot_size                 = tsl.get_lot_size(selling_name)

hedging_orderid  = tsl.order_placement(tradingsymbol=hedging_name, exchange='NFO', quantity=lot_size, price=0, trigger_price=0,order_type='MARKET', transaction_type='BUY', trade_type='MARGIN')
time.sleep(2)
selling_orderid  = tsl.order_placement(tradingsymbol=selling_name, exchange='NFO', quantity=lot_size, price=0, trigger_price=0,order_type='MARKET', transaction_type='SELL', trade_type='MARGIN')
Hi,Is this studied any of your advance servier video? please let me know.(as per above code replied)

Please find my be programmed code and error:

# ================= CONFIG =================
MAX_TRADES = 10
MAX_LOTS = 2

STOP_ENTRY_TIME = datetime.time(15, 0)
FORCE_EXIT_TIME = datetime.time(15, 25)

positions = {}
traded_symbols = set()


# ================= TELEGRAM =================
def tg(msg):
    try:
        requests.post(
            f"https://api.telegram.org/bot{TG_TOKEN}/sendMessage",
            data={"chat_id": TG_CHAT_ID, "text": msg},
            timeout=5
        )
    except:
        pass
		
# ================= UTIL =================
def is_entry_window():
    t = datetime.datetime.now().time()
    return datetime.time(9, 20) <= t <= STOP_ENTRY_TIME


def rsi_14(close):
    delta = close.diff()
    gain = delta.clip(lower=0)
    loss = -delta.clip(upper=0)
    rs = gain.rolling(14).mean() / loss.rolling(14).mean()
    return 100 - (100 / (1 + rs))


def atr_14(df):
    tr = np.maximum(
        df["high"] - df["low"],
        np.maximum(
            abs(df["high"] - df["close"].shift()),
            abs(df["low"] - df["close"].shift())
        )
    )
    return tr.rolling(14).mean().iloc[-1]


def get_5m(symbol):
    data = tsl.get_historical_data(symbol, "NSE", "5")
    return pd.DataFrame(data)


def get_ltp(sym):
    try:
        return float(tsl.get_ltp_data(names=[sym])[sym])
    except:
        return None

# ================= SAFE OTM (FIXED) =================
def safe_otm_strike(symbol, direction):
    """
    DHAN-SAFE OTM RESOLUTION (NO LOGIC CHANGE)
    """
    try:
        res = tsl.OTM_Strike_Selection(
            Underlying=symbol,
            Expiry=0,      # current month only (STOCK F&O)
            OTM_count=1
        )

        if not res or len(res) != 4:
            return None, None

        ce_name, pe_name, _, _ = res
        opt = ce_name if direction == "CE" else pe_name

        if not opt:
            return None, None

        ltp = get_ltp(opt)
        if ltp and ltp > 0:
            return opt, ltp

        return None, None

    except Exception as e:
        print(f"❌ OTM resolve failed for {symbol}: {e}")
        return None, None

# ================= MAIN LOOP =================
while True:
    try:
        print("\n---------------- LOOP RUNNING ----------------")
        now = datetime.datetime.now()
        df = pd.read_csv(fno_list)
		
        # ================= ENTRY =================
        for _, row in df.iterrows():
            if not is_entry_window() or len(positions) >= MAX_TRADES:
                break

            sym = row[[df"Symbol"]] # column of fno_list storing all f&O stock name
            print(f"\nChecking {sym}")

            candles = get_5m(sym)
            last = candles.iloc[-1]
            rsi = rsi_14(candles["close"]).iloc[-1]
            color = "GREEN" if last["close"] > last["open"] else "RED"

            print(f"RSI={round(rsi,1)} Candle={color}")

            if color == "GREEN" and rsi > 60:
                direction = "CE"
            elif color == "RED" and rsi < 60:
                direction = "PE"
            else:
                print("❌ RSI/Candle condition failed")
                continue

            opt, ltp = safe_otm_strike(sym, direction)
            if not opt:
                print(f"❌ OTM not tradable for {sym}")
                continue

            lot = tsl.get_lot_size(opt)
            qty = lot * MAX_LOTS

            atr = atr_14(candles)
            base_sl = round(ltp - atr, 1)
            target = round(ltp * 1.40, 1)

            # ===== BUY (DHAN SYNTAX) =====
            tsl.order_placement(
                tradingsymbol=opt,
                exchange="NFO",
                quantity=qty,
                price=0,
                trigger_price=0,
                order_type="MARKET",
                transaction_type="BUY",
                trade_type="MIS"
            )

            # ===== STOP LOSS =====
            sl_order = tsl.order_placement(
                tradingsymbol=opt,
                exchange="NFO",
                quantity=qty,
                price=0,
                trigger_price=base_sl,
                order_type="STOPMARKET",
                transaction_type="SELL",
                trade_type="MIS"
            )

            positions[opt] = {
                "qty": qty,
                "half": qty // 2,
                "sl": sl_order,
                "target": target,
                "atr": atr
            }

            traded_symbols.add(sym)
            tg(f"BUY {opt}\nQty:{qty}\nSL:{base_sl}\nTarget:{target}")

        # ================= EXIT MANAGEMENT =================
        for opt, p in list(positions.items()):
            ltp = get_ltp(opt)
            if not ltp:
                continue

            # ===== PARTIAL EXIT =====
            if ltp >= p["target"] and "partial" not in p:
                tsl.cancel_order(p["sl"])

                tsl.order_placement(
                    tradingsymbol=opt,
                    exchange="NFO",
                    quantity=p["half"],
                    price=0,
                    trigger_price=0,
                    order_type="MARKET",
                    transaction_type="SELL",
                    trade_type="MIS"
                )

                tsl.order_placement(
                    tradingsymbol=opt,
                    exchange="NFO",
                    quantity=p["half"],
                    price=0,
                    trigger_price=round(ltp - p["atr"] / 2, 1),
                    order_type="STOPMARKET",
                    transaction_type="SELL",
                    trade_type="MIS"
                )

                p["partial"] = True
                tg(f"🎯 Partial exit done: {opt}")

        print("Active positions:", positions.keys())
        time.sleep(60)

    except Exception as e:
        print("ERROR:", e)
        traceback.print_exc()
        time.sleep(60)

Checking VOLTAS
RSI=30.5 Candle=RED
Exception at getting Expiry list as {'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''}
Unable to find the correct Expiry for VOLTAS
❌ OTM resolve failed for VOLTAS: cannot unpack non-iterable NoneType object
❌ OTM not tradable for VOLTAS

Checking ASHOKLEY
RSI=33.1 Candle=RED
Exception at getting Expiry list as {'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''}
Unable to find the correct Expiry for ASHOKLEY
❌ OTM resolve failed for ASHOKLEY: cannot unpack non-iterable NoneType object
❌ OTM not tradable for ASHOKLEY

Checking JINDALSTEL
RSI=5.3 Candle=RED
Exception at getting Expiry list as {'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''}
Unable to find the correct Expiry for JINDALSTEL
❌ OTM resolve failed for JINDALSTEL: cannot unpack non-iterable NoneType object

I had tried many hit and trial ITM,OTM syntax with nearby and next month expiry still getting Exception at getting Expiry list  and OTM not tradable .
So Please guide me with proper code and also let me know if any advance syntax for oprion call/put entry exit,sl, order placement .

ce_name, pe_name, _, _ = tsl.OTM_Strike_Selection(Underlying=symbol, Expiry=0,OTM_count=1)
ce_name, pe_name, _, _ = tsl.OTM_Strike_Selection(Underlying=symbol, Expiry=1,OTM_count=1)
ce_name, pe_name, Strike= tsl.ATM_Strike_Selection(Underlying=symbol, Expiry=0)

Hi Imran sir,

This is my full code, please guide for above error while i don’t have any DATA subscription issues since it will be expired in next month or credential issues.

Hi @Krushna_Rout ,

  1. Make sure you have subscribed to Data API’s.
  2. Kindly revoke the existing token and generate new token and use the new token.
  3. Also make sure the client id passed is correct.

Sir, I am having Data Api subscription ,having correct clint code and token id. still i am getting same error and also one more users in this community also getting same error. please verify it one more time and guide me.

Regards

Hi @Krushna_Rout ,

{'status': 'failure', 'remarks': {'error_code': None, 'error_type': None, 'error_message': None}, 'data': ''} this error is mostly occurs when login is not successful or token id expires in between.