Learn Algo Trading with Python | Codes | Youtube Series

Hi @Kusum_Kapadia ,

Firstly do uninstall existing versions as below:

  • Press Win + I to open Settings.
  • Go to Apps > Installed apps (or Apps & Features).
  • Search for Python.
  • Click Uninstall for each Python version.
  • Follow the prompts to remove it.

Hi @amitbalagi ,

Do update codebase on your system

  • Open Command Prompt: Press Win, type cmd, and press Enter.
  • Install Dhan-Tradehull: Run pip install Dhan-Tradehull
  • Confirm the installation by running pip show Dhan-Tradehull

Guide to use the updated codebase:
Video reference : https://www.youtube.com/watch?v=P9iPYShakbA

Hi @Raju2 ,

In our latest codebase, the num_strikes parameter is not available for use.
You can retrieve the option chain using the following code:

option_chain = tsl.get_option_chain(Underlying=“NIFTY”, exchange=“INDEX”, expiry=0)
We will be adding num_strikes in further versions. You can use the below code if you wish to do it manually:


num_strikes = 10
strike_step = 50
CE_symbol_name, PE_symbol_name, atm_strike = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry=0)
oc_df = tsl.get_option_chain(Underlying="NIFTY", exchange="INDEX", expiry=0)
df = oc_df[(oc_df['Strike Price'] >= str(atm_strike - num_strikes * strike_step)) & (oc_df['Strike Price'] <= atm_strike + num_strikes * strike_step)].sort_values(by='Strike Price').reset_index(drop=True)

Hi @rahulcse56 ,

Steps to be followed to get INDIAVIX Ltp:

  • Open Command Prompt (cmd).
  • Type the following command and press Enter:
pip show Dhan-TradeHull
  • Locate the ‘Location’ field in the output. This shows the installation path of the package.
  • Navigate to the identified path and find the Dhan Tradehull file containing the get_ltp_data() function.
  • In get_ltp_data() function replace 7th line as:
exchange_index = {"BANKNIFTY": "NSE_IDX", "NIFTY":"NSE_IDX", "MIDCPNIFTY":"NSE_IDX", "FINNIFTY":"NSE_IDX", "SENSEX":"BSE_IDX", "BANKEX":"BSE_IDX", "INDIA VIX":"IDX_I"}

Note : This will be upgraded in further versions

1 Like

Hi @Qaisar ,

Solution link :

Dear sir

how to save in excel sheet of enter order price ,sl/ target price of algo.
please guide us.

I had already saw your post and updated dhan-tradehull. see below the pip show dhan-tradehull output for your reference.

PS C:\Users\amitb\Desktop\Python> pip show dhan-tradehull
Name: Dhan_Tradehull
Version: 3.0.2
Summary: A Dhan Codebase from TradeHull
Home-page: https://github.com/TradeHull/Dhan_Tradehull
Author: TradeHull
Author-email: contact.tradehull@gmail.com
License:
Location: c:\users\amitb\appdata\roaming\python\python310\site-packages
Requires: dhanhq, mibian, numpy, pandas, pytz, requests
Required-by:
PS C:\Users\amitb\Desktop\Python> 

Then I ran the same file from 2 different locations, in one i got the same error as before while in other problem was resolved.

import sys
import winsound

import dhan_user_functions
from Dhan_Tradehull_V2 import Tradehull
from datetime import datetime,timedelta
import time
import math
import requests
import pandas as pd
import threading
import datetime as dt
import talib
import logging

# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info(f"Now logging to Dhan Account.")
client_code = open("dhan_client_id.txt",'r').read()     #'clientID'
token_id    = open("dhan_access_token.txt",'r').read()              #'accessToken'
tsl         = Tradehull(client_code,token_id)
# tsl         = Tradehull(client_code,token_id)
logging.info(f"Successfully logged in to Dhan Account.")


name = 'NIFTY'
chart = tsl.get_historical_data(name, exchange='INDEX', timeframe='5')

# chart = tsl.get_historical_data(tradingsymbol = 'NIFTY',exchange = 'INDEX',timeframe="5")
# chart = chart.set_index(chart['timestamp'])

print("chart is \n", chart)

then the output from 1st location is as below:

"C:\Program Files\Python310\python.exe" C:\Users\amitb\Desktop\Python\dump.py 
Codebase Version 2.8 : Solved - Strike Selection Issue
-----Logged into Dhan-----
reading existing file all_instrument 2025-02-19.csv
2025-02-19 19:00:25,077 - INFO - Now logging to Dhan Account.
2025-02-19 19:00:25,078 - INFO - Dhan.py  started system
2025-02-19 19:00:25,078 - INFO - STARTED THE PROGRAM
Got the instrument file
2025-02-19 19:00:25,210 - ERROR - Error at getting start date as single positional indexer is out-of-bounds
Traceback (most recent call last):
  File "C:\Users\amitb\Desktop\Python\Dhan_Tradehull_V2.py", line 431, in get_start_date
    security_id 	= instrument_df[((instrument_df['SEM_TRADING_SYMBOL']==tradingsymbol)|(instrument_df['SEM_CUSTOM_SYMBOL']==tradingsymbol))&(instrument_df['SEM_EXM_EXCH_ID']==instrument_exchange[exchange])].iloc[-1]['SEM_SMST_SECURITY_ID']
  File "C:\Users\amitb\AppData\Roaming\Python\Python310\site-packages\pandas\core\indexing.py", line 1191, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "C:\Users\amitb\AppData\Roaming\Python\Python310\site-packages\pandas\core\indexing.py", line 1752, in _getitem_axis
    self._validate_integer(key, axis)
  File "C:\Users\amitb\AppData\Roaming\Python\Python310\site-packages\pandas\core\indexing.py", line 1685, in _validate_integer
    raise IndexError("single positional indexer is out-of-bounds")
IndexError: single positional indexer is out-of-bounds
2025-02-19 19:00:25,213 - INFO - Successfully logged in to Dhan Account.
2025-02-19 19:00:25,224 - ERROR - Exception in Getting OHLC data as Check the Tradingsymbol or Exchange
Traceback (most recent call last):
  File "C:\Users\amitb\Desktop\Python\Dhan_Tradehull_V2.py", line 476, in get_historical_data
    raise Exception("Check the Tradingsymbol or Exchange")
Exception: Check the Tradingsymbol or Exchange
Exception in Getting OHLC data as Check the Tradingsymbol or Exchange
chart is 
 None

Process finished with exit code 0

while from another location, the output is as below:

"C:\Program Files\Python310\python.exe" "C:\Users\amitb\Desktop\Python\2. API Traders Meetup & Workshop - Building Blocks\Session 1\dump.py" 
Codebase Version 2.8 : Solved - Strike Selection Issue
2025-02-19 19:03:30,281 - INFO - Now logging to Dhan Account.
2025-02-19 19:03:30,283 - INFO - Dhan.py  started system
2025-02-19 19:03:30,283 - INFO - STARTED THE PROGRAM
-----Logged into Dhan-----
reading existing file all_instrument 2025-02-19.csv
Got the instrument file
2025-02-19 19:03:32,017 - INFO - Successfully logged in to Dhan Account.
chart is 
              open      high  ...  volume                 timestamp
0    22809.900391  22835.50  ...     0.0 2025-02-17 09:15:00+05:30
1    22806.050000  22873.75  ...     0.0 2025-02-17 09:20:00+05:30
2    22842.000000  22874.75  ...     0.0 2025-02-17 09:25:00+05:30
3    22830.350000  22839.45  ...     0.0 2025-02-17 09:30:00+05:30
4    22805.650000  22824.35  ...     0.0 2025-02-17 09:35:00+05:30
..            ...       ...  ...     ...                       ...
221  22946.550000  22949.15  ...     0.0 2025-02-19 15:10:00+05:30
222  22940.050000  22940.20  ...     0.0 2025-02-19 15:15:00+05:30
223  22931.250000  22932.60  ...     0.0 2025-02-19 15:20:00+05:30
224  22926.450000  22933.25  ...     0.0 2025-02-19 15:25:00+05:30
225  22932.900000  22932.90  ...     0.0 2025-02-19 17:50:00+05:30

[226 rows x 6 columns]

Process finished with exit code 0

@Tradehull_Imran Sir there is no reply from the @Hardik and please help for the same and i have another concern can you tell me the limit of the api hit per sec because if i try to fetch the data of the 200 stocks i build my own screener and i used threading it giving me the error that limit reached error Exception in Getting OHLC data as {'status': 'failure', 'remarks': {'error_code': 'DH-904', 'error_type': 'Rate_Limit', 'error_message': 'Too many requests on server from single user breaching rate limits. Try throttling API calls.'}, 'data': {'errorType': 'Rate_Limit', 'errorCode': 'DH-904', 'errorMessage': 'Too many requests on server from single user breaching rate limits. Try throttling API calls.'}} Error fetching data for APOLLOHOSP: 'NoneType' object has no attribute 'empty'

@Tradehull_Imran
ye dhan kya data de rha h ki chart ka data fetch kar rhe h api ke through
usme or aj ke char me jamin asman ka antar h esa nhi h ki ek hi char me h bhot chart me h GNFC , CONCOR , DELHIVERY , INDHOTEL or bhi bhot h @Hardik iska jawab do bhi ye to bhot bekar chiz h ye GFC ke chart ka bej rha hun or please jara actul chart ka difference ja ke dekho

open high low close volume timestamp
750 547.50 547.50 536.70 545.15 22229.0 2025-02-20 09:15:00+05:30
751 547.45 547.45 542.80 545.15 3286.0 2025-02-20 09:16:00+05:30
752 544.55 545.55 544.00 544.15 1838.0 2025-02-20 09:17:00+05:30

Hello @Dev_Goswami

Can you please share the request for this and also Security ID for which you are trying to fetch the data. If there were issues in data for companies highlighted by you, then even charts would have shown the same data as the source of both remains the same.

Also, do check if you have actually updated security ID list for today.

Currently, we only have daily timeframe data available for backtesting. But we are working on this to help you with minute timeframe of larger time period.

1 Like

Arre, there’s no need for the Security ID now since data is being fetched using the symbol after the update. chart = tsl.get_historical_data(tradingsymbol="GNFC", exchange='NSE', timeframe="1") df_filtered = chart[chart["timestamp"] >= "2025-02-20 09:15:00+05:30"] df_filtered

open high low close volume timestamp
750 547.50 547.50 536.70 545.15 22229.0 2025-02-20 09:15:00+05:30
751 547.45 547.45 542.80 545.15 3286.0 2025-02-20 09:16:00+05:30
752 544.55 545.55 544.00 544.15 1838.0 2025-02-20 09:17:00+05:30
now go and check the today GNFC chart and same issue with these company as well CONCOR , DELHIVERY , INDHOTEL @Tradehull_Imran

Hello @Tradehull_Imran @Hardik
order_id = tsl.order_placement(tradingsymbol=‘NIFTY 20 FEB 26000 CALL’, exchange=‘NFO’, quantity=75, price=0, trigger_price=0, order_type=‘MARKET’, transaction_type=‘BUY’, trade_type=‘MIS’, disclosed_quantity=0, after_market_order=False, amo_time=‘OPEN’)

trade_type=‘MIS’ :- ABLE TO PLACE INTRDAYORDER
trade_type=‘CNC’ :- GETTING DH-906
trade_type=‘NRML’ :- Got exception in place_order as 'NRML

I can see we place Intraday options trade

*but do we have support for options delivery trades ???

example NIFTY 20 FEB 26000 CALL and trade_type CNC or NRML ???

Hi @Deodas_kumar ,

Refer the below code:

import xlwings as xw
wb               = xw.Book('Live Trade Data.xlsx')
live_Trading     = wb.sheets['Live_Trading'] # 'Live_Trading' is the excel sheet name.
orderbook        = {}

# add other parameters to orderbook to send to excel sheet
orderbook['name']           = name 
orderbook['date']           = str(current_time.date())
orderbook['entry_time']     = str(current_time.time())[:8]
orderbook['buy_sell']       = "BUY"
orderbook['qty']            = 1 
# In the below code, we are converting to dataframe and sending to excel sheet
orderbook_df                       = pd.DataFrame(orderbook).T
live_Trading.range('A1').value     = orderbook_df

refer the complete code as below:

import pdb
import time
import datetime
import traceback
from Dhan_Tradehull import Tradehull
import pandas as pd
from pprint import pprint
import talib
import pandas_ta as ta
import xlwings as xw
import winsound



client_code = "1102790337"
token_id    = "bhgvsaoieqhjvhg"
tsl         = Tradehull(client_code,token_id)

# Uncomment below code to do pre market scanning
# pre_market_watchlist        = ['ASIANPAINT', 'BAJAJ-AUTO', 'BERGEPAINT', 'BEL', 'BOSCHLTD', 'BRITANNIA', 'COALINDIA', 'COLPAL', 'DABUR', 'DIVISLAB', 'EICHERMOT', 'GODREJCP', 'HCLTECH', 'HDFCBANK', 'HAVELLS', 'HEROMOTOCO', 'HAL', 'HINDUNILVR', 'ITC', 'IRCTC', 'INFY', 'LTIM', 'MARICO', 'MARUTI', 'NESTLEIND', 'PIDILITIND', 'TCS', 'TECHM', 'WIPRO']
# watchlist                   = []

# for name in pre_market_watchlist:

# 	print("Pre market scanning ", name)
# 	day_chart = tsl.get_historical_data(tradingsymbol = name,exchange = 'NSE',timeframe="DAY")
# 	day_chart['upperband'], day_chart['middleband'], day_chart['lowerband'] = talib.BBANDS(day_chart['close'], timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)


# 	last_day_candle = day_chart.iloc[-1]

# 	upper_breakout = last_day_candle['high'] > last_day_candle['upperband']
# 	lower_breakout = last_day_candle['low'] < last_day_candle['lowerband']

# 	if upper_breakout or lower_breakout:
# 		watchlist.append(name)
# 		print(f"\t selected {name} for trading")
# 		pdb.set_trace()


# print(watchlist)
# # pdb.set_trace()





watchlist = ['BEL', 'BOSCHLTD', 'COLPAL', 'HCLTECH', 'HDFCBANK', 'HAVELLS', 'HAL', 'ITC', 'IRCTC', 'INFY', 'LTIM', 'MARICO', 'MARUTI', 'NESTLEIND', 'PIDILITIND', 'TCS', 'TECHM', 'WIPRO']




single_order     = {'name':None, 'date':None , 'entry_time': None, 'entry_price': None, 'buy_sell': None, 'qty': None, 'sl': None, 'exit_time': None, 'exit_price': None, 'pnl': None, 'remark': None, 'traded':None}
orderbook        = {}
wb               = xw.Book('Live Trade Data.xlsx')
live_Trading     = wb.sheets['Live_Trading']
completed_orders_sheet = wb.sheets['completed_orders']
reentry          = "yes" #"yes/no"
completed_orders = []


bot_token        = "8059847390:AAECSnQK-yOaGJ-clJchb1cx8CDhx2VQq-M"
receiver_chat_id = "1918451082"


live_Trading.range("A2:Z100").value = None
completed_orders_sheet.range("A2:Z100").value = None

for name in watchlist:
	orderbook[name] = single_order.copy()



while True:

	print("starting while Loop \n\n")

	current_time = datetime.datetime.now().time()
	if current_time < datetime.time(13, 55):
		print(f"Wait for market to start", current_time)
		time.sleep(1)
		continue

	if current_time > datetime.time(15, 15):
		order_details = tsl.cancel_all_orders()
		print(f"Market over Closing all trades !! Bye Bye See you Tomorrow", current_time)
		pdb.set_trace()
		break


	all_ltp = tsl.get_ltp_data(names = watchlist)
	for name in watchlist:


		orderbook_df                       = pd.DataFrame(orderbook).T
		live_Trading.range('A1').value     = orderbook_df

		completed_orders_df                =  pd.DataFrame(completed_orders)
		completed_orders_sheet.range('A1').value = completed_orders_df


		current_time          = datetime.datetime.now()
		print(f"Scanning        {name} {current_time}")




		try:
			chart                 = tsl.get_historical_data(tradingsymbol = name,exchange = 'NSE',timeframe="5")
			chart['rsi']          = talib.RSI(chart['close'], timeperiod=14)
			cc  = chart.iloc[-2]

			# buy entry conditions
			bc1 = cc['rsi'] > 45
			bc2 = orderbook[name]['traded'] is None
		except Exception as e:
			print(e)
			continue



		if bc1 and bc2:
			print("buy ", name, "\t")

			margin_avialable = tsl.get_balance()
			margin_required  = cc['close']/4.5

			if margin_avialable < margin_required:
				print(f"Less margin, not taking order : margin_avialable is {margin_avialable} and margin_required is {margin_required} for {name}")
				continue


			orderbook[name]['name']           = name
			orderbook[name]['date']           = str(current_time.date())
			orderbook[name]['entry_time']     = str(current_time.time())[:8]
			orderbook[name]['buy_sell']       = "BUY"
			orderbook[name]['qty']            = 1


			try:
				entry_orderid                     = tsl.order_placement(tradingsymbol=name ,exchange='NSE', quantity=orderbook[name]['qty'], price=0, trigger_price=0,    order_type='MARKET',     transaction_type='BUY',   trade_type='MIS')
				orderbook[name]['entry_orderid']  = entry_orderid
				orderbook[name]['entry_price']    = tsl.get_executed_price(orderid=orderbook[name]['entry_orderid'])

				orderbook[name]['tg']             = round(orderbook[name]['entry_price']*1.002, 1)   # 1.01
				orderbook[name]['sl']             = round(orderbook[name]['entry_price']*0.998, 1)    # 99
				sl_orderid                        = tsl.order_placement(tradingsymbol=name ,exchange='NSE', quantity=orderbook[name]['qty'], price=0, trigger_price=orderbook[name]['sl'], order_type='STOPMARKET', transaction_type ='SELL', trade_type='MIS')
				orderbook[name]['sl_orderid']     = sl_orderid
				orderbook[name]['traded']         = "yes"

				message = "\n".join(f"'{key}': {repr(value)}" for key, value in orderbook[name].items())
				message = f"Entry_done {name} \n\n {message}"
				tsl.send_telegram_alert(message=message,receiver_chat_id=receiver_chat_id,bot_token=bot_token)



			except Exception as e:
				print(e)
				pdb.set_trace(header= "error in entry order")





		if orderbook[name]['traded'] == "yes":
			bought = orderbook[name]['buy_sell'] == "BUY"

			if bought:

				try:
					ltp       = all_ltp[name]
					sl_hit    = tsl.get_order_status(orderid=orderbook[name]['sl_orderid']) == "TRADED"
					tg_hit    = ltp > orderbook[name]['tg']
				except Exception as e:
					print(e)
					pdb.set_trace(header = "error in sl order cheking")



				if sl_hit:

					try:
						orderbook[name]['exit_time']  = str(current_time.time())[:8]
						orderbook[name]['exit_price'] = tsl.get_executed_price(orderid=orderbook[name]['sl_orderid'])
						orderbook[name]['pnl']        = round((orderbook[name]['exit_price'] - orderbook[name]['entry_price'])*orderbook[name]['qty'],1)
						orderbook[name]['remark']     = "Bought_SL_hit"

						message = "\n".join(f"'{key}': {repr(value)}" for key, value in orderbook[name].items())
						message = f"SL_HIT {name} \n\n {message}"
						tsl.send_telegram_alert(message=message,receiver_chat_id=receiver_chat_id,bot_token=bot_token)



						if reentry == "yes":
							completed_orders.append(orderbook[name])
							orderbook[name] = None
					except Exception as e:
						print(e)
						pdb.set_trace(header = "error in sl_hit")



				if tg_hit:

					try:
						tsl.cancel_order(OrderID=orderbook[name]['sl_orderid'])
						time.sleep(2)
						square_off_buy_order          = tsl.order_placement(tradingsymbol=orderbook[name]['name'] ,exchange='NSE', quantity=orderbook[name]['qty'], price=0, trigger_price=0,    order_type='MARKET',     transaction_type='SELL',   trade_type='MIS')

						orderbook[name]['exit_time']  = str(current_time.time())[:8]
						orderbook[name]['exit_price'] = tsl.get_executed_price(orderid=square_off_buy_order)
						orderbook[name]['pnl']        = (orderbook[name]['exit_price'] - orderbook[name]['entry_price'])*orderbook[name]['qty']
						orderbook[name]['remark']     = "Bought_TG_hit"

						message = "\n".join(f"'{key}': {repr(value)}" for key, value in orderbook[name].items())
						message = f"TG_HIT {name} \n\n {message}"
						tsl.send_telegram_alert(message=message,receiver_chat_id=receiver_chat_id,bot_token=bot_token)


						if reentry == "yes":
							completed_orders.append(orderbook[name])
							orderbook[name] = None

						winsound.Beep(1500, 10000)

					except Exception as e:
						print(e)
						pdb.set_trace(header = "error in tg_hit")

Hi @amitbalagi ,

Okay

Hi @Dev_Goswami ,

It seems the data is matching accurately with the charts. Attaching the screenshot below do check.

Hi @Dev_Goswami ,

Here’s the screenshot of rate limits:

Do check this link:
Introduction - DhanHQ Ver 2.0 / API Document

Hi @Manish1 ,

Can you share screenshot of the terminal when you try to place for ‘CNC’ order.

Hi @anandc

Refer the below link for the code:

1 Like

Hi @Subhajitpanja .

Refer the below link for the code:

Thank you @Tradehull_Imran sir
but I like to follow your video instructions only to write code.

I asked that one for a mate (here) who was seeking for it

1 Like