Learn Algo Trading with Python | Codes | Youtube Series

Hi @Kanha_Meher

use get_historical_data function,
get_intraday_data will be deprecated

Also manage the exception as below

    while True:
        # Wait until the start of the next minute
        now = datetime.now()
        sleep_time = 60 - now.second - now.microsecond / 1_000_000  # Sleep until next minute
        time.sleep(sleep_time)  # Sync with the next minute start

        # Start time of execution
        start_time = datetime.now()
        print(f"Running at: {start_time.strftime('%H:%M:%S')}")

        # Get Nifty intraday data


        try:
            nifty_chart = tsl.get_historical_data(tradingsymbol='NIFTY', exchange='INDEX', timeframe="1")
        except Exception as e:
            continue

        if nifty_chart is not None:
            nifty_chart['timestamp'] = pd.to_datetime(nifty_chart['timestamp'])
            nifty_lc_data = nifty_chart.iloc[0:-2]

            # Use parentheses to call the methods

1 Like
import pdb
import time
import datetime
import traceback
from Dhan_Tradehull_V2 import Tradehull
import pandas as pd
from pprint import pprint
import talib
import pandas_ta as pta
import pandas_ta as ta
import warnings

warnings.filterwarnings("ignore")



# ---------------for dhan login ----------------
client_code = "11047"
token_id = "eyJ0eXAiOiJK"


tsl = Tradehull(client_code,token_id)

traded = "no"
trade_info = {"options_name":None, "qty":None, "sl":None, "CE_PE":None}
reward_risk_ratio = 3


while True:

	current_time = datetime.datetime.now()

	index_chart  = tsl.get_historical_data(tradingsymbol='NIFTY JAN FUT', exchange='NFO', timeframe="5")
	time.sleep(5)
	index_ltp    = tsl.get_ltp_data(names = ['NIFTY JAN FUT'])['NIFTY JAN FUT']

	# if (index_chart.empty):
	# 	time.sleep(60)
	# 	continue


	# rsi    ------------------------ apply indicators
	index_chart['rsi'] = talib.RSI(index_chart['close'], timeperiod=14)

	# vwap
	index_chart.set_index(pd.DatetimeIndex(index_chart['timestamp']), inplace=True)
	index_chart['vwap'] = pta.vwap(index_chart['high'] , index_chart['low'], index_chart['close'] , index_chart['volume'])

	# Supertrend
	indi = ta.supertrend(index_chart['high'], index_chart['low'], index_chart['close'], 10, 2)
	index_chart = pd.concat([index_chart, indi], axis=1, join='inner')


	# vwma
	index_chart['pv'] = index_chart['close'] * index_chart['volume']
	index_chart['vwma'] = index_chart['pv'].rolling(20).mean() / index_chart['volume'].rolling(20).mean()

	# volume
	volume = 50000

	first_candle   = index_chart.iloc[-3]
	second_candle  = index_chart.iloc[-2]
	running_candle = index_chart.iloc[-1]


	# ---------------------------- BUY ENTRY CONDITIONS ----------------------------
	bc1 = first_candle['close'] > first_candle['vwap']                # First Candle close is above VWAP
	bc2 = first_candle['close'] > first_candle['SUPERT_10_2.0']       # First Candle close is above Supertrend 
	bc3 = first_candle['close'] > first_candle['vwma']                # First Candle close is above VWMA
	bc4 = first_candle['rsi'] < 80                                    # First candle RSI < 80	
	bc5 = second_candle['volume'] > 50000                             # Second candle Volume should be greater than 50,000 for Nifty and above 125,000 for Bank Nifty
	bc6 = traded == "no"
	bc7 = index_ltp > first_candle['low']
	print(f"BUY \t {current_time} \t {bc1} \t {bc2} \t {bc3} \t {bc4} \t {bc5} \t {bc6} \t {bc7} \t first_candle {str(first_candle['timestamp'].time())}")


	# ---------------------------- SELL ENTRY CONDITIONS ----------------------------
	sc1 = first_candle['close'] < first_candle['vwap']                # First Candle close is below VWAP
	sc2 = first_candle['close'] < first_candle['SUPERT_10_2.0']       # First Candle close is below Supertrend 
	sc3 = first_candle['close'] < first_candle['vwma']                # First Candle close is below VWMA
	sc4 = first_candle['rsi'] > 20                                    # First candle RSI < 80	
	sc5 = second_candle['volume'] > 50000                             # Second candle Volume should be greater than 50,000 for Nifty and above 125,000 for Bank Nifty
	sc6 = traded == "no"
	sc7 = index_ltp < first_candle['high']
	print(f"SELL \t {current_time} \t {sc1} \t {sc2} \t {sc3} \t {sc4} \t {sc5} \t {sc6} \t {sc7} \t first_candle {str(first_candle['timestamp'].time())} \n")



	if bc1 and bc2 and bc3 and bc4 and bc5 and bc6 and bc7:
		print("Buy Signal Formed")

		ce_name, pe_name, ce_strike, pe_strike = tsl.OTM_Strike_Selection('NIFTY','23-1-2025',2)
		ce_ltp                     = tsl.get_ltp_data(names = [ce_name])[ce_name]
		lot_size                   = tsl.get_lot_size(ce_name)*1
		entry_orderid              = tsl.order_placement(ce_name,'NFO', lot_size, 0, 0, 'MARKET', 'BUY', 'MIS')
		traded                     = "yes"
		trade_info['options_name'] = ce_name
		trade_info['qty']          = lot_size
		sl_percentage = 15 / 100  # 15%
		target_percentage = 30 / 100  # 30%
		trade_info['sl'] = ce_ltp * (1 - sl_percentage)
		trade_info['target'] = ce_ltp * (1 + target_percentage)
		trade_info['CE_PE'] = "CE"



	if sc1 and sc2 and sc3 and sc4 and sc5 and sc6 and sc7:
		print("Sell Signal Formed")

		ce_name, pe_name, ce_strike, pe_strike = tsl.OTM_Strike_Selection('NIFTY','23-1-2025',2)
		pe_ltp                     = tsl.get_ltp_data(names = [pe_name])[pe_name]
		lot_size                   = tsl.get_lot_size(pe_name)*1
		entry_orderid              = tsl.order_placement(pe_name,'NFO', lot_size, 0, 0, 'MARKET', 'BUY', 'MIS')
		traded                     = "yes"
		trade_info['options_name'] = pe_name
		trade_info['qty']          = lot_size
		sl_percentage = 15 / 100  # 15%
		target_percentage = 30 / 100  # 30%
		trade_info['sl'] = ce_ltp * (1 - sl_percentage)
		trade_info['target'] = ce_ltp * (1 + target_percentage)

		trade_info['CE_PE'] = "PE"


	# ---------------------------- check for exit SL/TG

	if traded == "yes":

		long_position  = trade_info['CE_PE'] == "CE"
		short_position = trade_info['CE_PE'] == "PE"


		if long_position:
			options_ltp     = tsl.get_ltp_data(names = [trade_info['options_name']])[trade_info['options_name']]
			sl_hit          = options_ltp < trade_info['sl']
			trailing_tg_hit = index_ltp < running_candle['SUPERT_10_2.0']   # this is a trailing target, by supertrend
			tg_hit          = options_ltp > trade_info['target']

			if sl_hit or trailing_tg_hit or tg_hit:
				print("Order Exited", trade_info)
				exit_orderid        = tsl.order_placement(trade_info['options_name'],'NFO', trade_info['qty'], 0, 0, 'MARKET', 'SELL', 'MIS')
				pdb.set_trace()


		if short_position:
			options_ltp     = tsl.get_ltp_data(names = [trade_info['options_name']])[trade_info['options_name']]
			sl_hit          = options_ltp > trade_info['sl']
			trailing_tg_hit = index_ltp > running_candle['SUPERT_10_2.0']   # this is a trailing target, by supertrend
			tg_hit          = options_ltp < trade_info['target']

			if sl_hit or trailing_tg_hit or tg_hit:
				print("Order Exited", trade_info)
				exit_orderid        = tsl.order_placement(trade_info['options_name'],'NFO', trade_info['qty'], 0, 0, 'MARKET', 'SELL', 'MIS')
				pdb.set_trace()

Sir, in this code it shows this error

" Exception at calling ltp as {‘status’: ‘failure’, ‘remarks’: {‘error_code’: None, ‘error_type’: None, ‘error_message’: None}, ‘data’: {‘data’: {‘805’: ‘Too many requests. Further requests may result in the user being blocked.’}, ‘status’: ‘failed’}}
Traceback (most recent call last):
File “d:/Python/My Strategy/two candle theory.py”, line 134, in
options_ltp = tsl.get_ltp_data(names = [trade_info[‘options_name’]])[trade_info[‘options_name’]]
KeyError: ‘NIFTY 23 JAN 23200 CALL’
"
And then the code is stops, Please give me fix sir, why it is not tracking, Target and SL?
Thanks.

@Tradehull_Imran
there is prise difference in closin what to do


@Tradehull_Imran Still getting PnL error.

got exception in pnl as 'SENSEX-Jan2025-76200-CE'
Exception for instrument name SENSEX-JAN2025-76200-CE as Check the Tradingsymbol
Exception for instrument name FINNIFTY-JAN2025-22500-CE as Check the Tradingsymbol
Exception for instrument name BANKNIFTY-JAN2025-48400-CE as Check the Tradingsymbol

Its spamming the logs. Can you please check and let us know when we would the fix will be available?

@RahulDeshpande - Any update on python based back testing video series. Any tentative timelines to release on YouTube.

@Tradehull_Imran
sir how can i get 200MA of 5 min candles

Soon! We are in the last phases of the editing - the quantum of information @Tradehull_Imran sir has poured in for you all - the videos are going to be long, and filled with information!

I will update in here - once it goes live.

8 Likes

hi, @Tradehull_Imran

The code you have given me not giving me any output but same code I ask chat gpt to edit and rectify now its started working… thank you…

now its working I will test this for 7 days
after that I want to upgrade this code with smc concept
condtition
wait till IDM happens on 1hr time frame then jaise hi idm ho uske baad agar 1hr supertrend green hoga to buy order place hojaae

code -
import time
import datetime
import pandas as pd
import pandas_ta as ta
from Dhan_Tradehull_V2 import Tradehull
import warnings

warnings.filterwarnings(“ignore”)

---------------for dhan login ----------------

client_code = “11111111111”
token_id = “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzM5MjY5OTEyLCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMjk1NTI5MCJ9.5aG1-NOtFA3Bhsta9LZAdFsvljkz7sI_mXMDJ82QtumR67DLvUrFyJM8zUN3QO9_VpXaJK-leRqmMQIfxN6qCA”

Initialize Tradehull API

tsl = Tradehull(client_code, token_id)

List of stocks to monitor

stocks = [“MARICO”, “ENDURANCE”, “IPCALAB”, “POLYMED”, “FINPIPE”, “MOTHERSON”, “LUPIN”, “VIJAYA”, “ZYDUSLIFE”, “GILLETTE”]

Variables to track trades for each stock

trade_info = {stock: {“traded”: “no”, “qty”: None, “entry_price”: None} for stock in stocks}

while True:
current_time = datetime.datetime.now()
next_candle_time = (current_time + datetime.timedelta(hours=1)).replace(minute=0, second=0, microsecond=0)

for stock in stocks:
    print(f"{current_time}: Fetching data for {stock}")

    # Fetch 1-hour historical data
    try:
        stock_chart = tsl.get_historical_data(tradingsymbol=stock, exchange='NSE', timeframe="1")
        if stock_chart is None or len(stock_chart) < 3:
            print(f"{current_time}: Historical data not available or incomplete for {stock}. Retrying...")
            time.sleep(60)
            continue
    except Exception as e:
        print(f"{current_time}: Error fetching historical data for {stock}: {e}")
        time.sleep(60)
        continue

    # Fetch latest price
    try:
        stock_ltp = tsl.get_ltp_data(names=[stock]).get(stock, None)
        if stock_ltp is None:
            print(f"{current_time}: LTP data not fetched for {stock}. Retrying...")
            time.sleep(60)
            continue
    except Exception as e:
        print(f"{current_time}: Error fetching LTP for {stock}: {e}")
        time.sleep(60)
        continue

    # Apply Supertrend indicator
    try:
        supertrend = ta.supertrend(stock_chart['high'], stock_chart['low'], stock_chart['close'], 10, 3)
        stock_chart = pd.concat([stock_chart, supertrend], axis=1, join='inner')
    except Exception as e:
        print(f"{current_time}: Error calculating Supertrend for {stock}: {e}")
        continue

    # Evaluate Buy/Exit Conditions
    previous_completed_candle = stock_chart.iloc[-3]
    completed_candle = stock_chart.iloc[-2]
    running_candle = stock_chart.iloc[-1]

    buy_condition1 = (previous_completed_candle['SUPERTd_10_3.0'] == -1) and (completed_candle['SUPERTd_10_3.0'] == 1)
    buy_condition2 = trade_info[stock]['traded'] == "no"
    exit_condition = (running_candle['SUPERT_10_3.0'] > running_candle['close']) and (trade_info[stock]['traded'] == "yes")

    if buy_condition1 and buy_condition2:
        print(f"{current_time}: Buy Signal Detected for {stock}")

        qty = 1  # Example: fixed quantity to buy
        entry_orderid = tsl.order_placement(stock, 'NSE', qty, 0, 0, 'MARKET', 'BUY', 'CNC')

        trade_info[stock]['traded'] = "yes"
        trade_info[stock]['qty'] = qty
        trade_info[stock]['entry_price'] = tsl.get_executed_price(orderid=entry_orderid)

    if exit_condition:
        print(f"{current_time}: Exit Signal Detected for {stock}")

        exit_orderid = tsl.order_placement(
            stock, 'NSE', trade_info[stock]['qty'], 0, 0, 'MARKET', 'SELL', 'CNC')

        trade_info[stock] = {"traded": "no", "qty": None, "entry_price": None}

# Wait until the next 1-hour candle forms
while datetime.datetime.now() < next_candle_time:
    time.sleep(30)
1 Like

Hi @babji3

The ltp was not received as rate limit was exceeded.

  1. do use this upgraded codebase file : Dhan_Tradehull_V2.py - Google Drive

  2. Also let me know if you are running 2 algo parallelly

  3. Also manage the exceptions in ltp data as per below code


				try:
					options_ltp     = tsl.get_ltp_data(names = [trade_info['options_name']])[trade_info['options_name']]

					if len(my_dict) == 0:
						continue

				except Exception as e:
					print(e)
					continue


Hi @Spasarkar04

Do mention the candle datetime you are referring to which is not matching with dataframe
Tagging @Hardik for same.

1 Like

Hi @Rajashekhar_Rangappa

Missed on updating the file . will send the updated file after tomorrow’s testing.

Hi @Spasarkar04

use below code

import talib

chart = tsl.get_historical_data(tradingsymbol = 'NIFTY',exchange = 'INDEX',timeframe="5")
chart['ma200'] = talib.MA(chart['close'], timeperiod=200, matype=0)


1 Like

Please publish these codes for mac users as well.

1 Like

@Got the instrument file
Error processing GMRINFRA: No expiry date found for GMRINFRA
getting this error in premarket scaner and algo
this name is not in watchlist

pre_market_watchlist = [‘INFY’, ‘M&M’, ‘HINDALCO’, ‘TATASTEEL’, ‘NTPC’, ‘MARUTI’, ‘TATAMOTORS’, ‘ONGC’, ‘BPCL’, ‘WIPRO’, ‘SHRIRAMFIN’, ‘ADANIPORTS’, ‘JSWSTEEL’, ‘COALINDIA’, ‘ULTRACEMCO’, ‘BAJAJ-AUTO’, ‘LT’, ‘POWERGRID’, ‘ADANIENT’, ‘SBIN’, ‘HCLTECH’, ‘TCS’, ‘EICHERMOT’, ‘BAJAJFINSV’, ‘TECHM’, ‘LTIM’, ‘HINDUNILVR’, ‘BHARTIARTL’, ‘AXISBANK’, ‘GRASIM’, ‘HEROMOTOCO’, ‘DRREDDY’, ‘ICICIBANK’, ‘HDFCBANK’, ‘BAJFINANCE’, ‘SBILIFE’, ‘RELIANCE’, ‘KOTAKBANK’, ‘ITC’, ‘TITAN’, ‘SUNPHARMA’, ‘INDUSINDBK’, ‘APOLLOHOSP’, ‘BRITANNIA’, ‘NESTLEIND’, ‘HDFCLIFE’, ‘DIVISLAB’, ‘CIPLA’, ‘ASIANPAINT’, ‘TATACONSUM’]

1 Like

Hi @Akshay_Bawane @Bhaanusood @ddeogharkar @Delta_Trading @Ganesh_Surwase @hello_123 @jacgohil @Kanha_Meher @Lokesh_Patidar @Naga_Rajesh_K

I am expecting a delay of 2 weeks on the first version of Open Source Backtesting.
We are almost done with 60% of development and testing for OSB 1.0.0.
This will be our first Result and session on Backtesting.
Hoping for something positive :crossed_fingers:

18 Likes

Tagging @naresh @phani_m @rohit2312 @sammed_patil @Shivam_Dixit @SOURAV_PROSAD @SUKANTA_MONDAL1 @suniljadhav @Vasili_Prasad @Venus_Dahiya

1 Like

Tagging @vinay_kumaar @Aijaz_Ahmad @Arun_Rawat @Falesh_Mehta @Kishore007 @NIMESH_GULIANA @Priti_Sisodiya @Priyesh_Sharma @rahulcse56 @Ravi_Sharma

2 Likes

Tagging @Sameer_Shaikh @Subhajitpanja @Vijay_Chauhan @Vinod_Kumar1 @virender_singh @AmitKAswani @anurag24 @Atul_Mahajan @Ethiraj @Himansshu_Joshi

2 Likes

Tagging @kristrades99 @kumarmohit @MEHUL_KANDORIYA @nikhil_shinde @Qaisar @Shantesh9 @thunderstorm @Vicky_Rathee @vinayak_kadtan @Zee2Zahid

1 Like

Tagging @Rajashekhar_Rangappa @avinashkumar07412 @TAPAS_KUMAR_DUTTA @thammisetty_srinivas

3 Likes