Learn Algo Trading with Python | Codes | Youtube Series

Hi @Arun_Rawat

The sell orders is incorrect, this is sending sell orders after every 10 seconds.

Do send the code as well. we need to block repeated orders

Hi @Aniket_Sawant

Dhan Tradehull codebase link : Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.

Also we will be releasing new codebase document in upcoming weeks.

2 Likes

Hi @Samis @Delta_Trading

The rate limits are as follows

For tick data, (LTP/OHLC/QUOTE) … quote api is being used and yes we can request data for 1000 scripts in 1 api call when calling quote data (LTP/OHLC/QUOTE)
Dhan-Tradehull codebase LTP function supports the same

You have given a good suggestion we will extend this functionality for OHLC and Quote as well


data = tsl.get_ltp_data(names=['CRUDEOIL', 'NIFTY'])


.
.


Now for Historical chart data
The OHLC that was being referred to in dhanhq document… is Open high low and close value for the current day only

{"open": 4521.45,"close": 4507.85,"high": 4530,"low": 4500}

for the chart level historical data for various timeframes [1/2/3/4/510/15/60]…
we need to call the Data Api… which has only 7000 allowed calls per day,
which is nearly 1 api call after 3.3 seconds.

2 Likes

@Tradehull_Imran Sir,

Please find the code.
import pdb
import time
import datetime
import traceback
import pandas as pd
from pprint import pprint
import talib
import pandas_ta as pta
import pandas_ta as ta
import warnings
from Dhan_Tradehull_V2 import Tradehull

warnings.filterwarnings(“ignore”)

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

client_code = “”
token_id = “”

tsl = Tradehull(client_code, token_id)
available_balance = tsl.get_balance()
leveraged_margin = available_balance * 2
max_trades = 3
per_trade_margin = leveraged_margin / max_trades
max_loss = available_balance / 100 * -1

traded = “no”
trade_info = {“options_name”: None, “qty”: None, “sl”: None, “CE_PE”: None}

while True:
live_pnl = tsl.get_live_pnl()
current_time = datetime.datetime.now().time() # time only

if current_time < datetime.time(9, 45, 0):
    print("Wait for the market to open", current_time)
    continue

if current_time > datetime.time(15, 15, 30) or (live_pnl < max_loss):
    tsl.kill_switch('ON')
    tsl.cancel_all_orders()
    print("Market is over or MAX LOSS reached, Bye for Now", current_time)
    break

print("Algo is working", current_time)

try:
    index_chart = tsl.get_historical_data(tradingsymbol='NIFTY JAN FUT', exchange='NFO', timeframe="5")
    time.sleep(3)
    index_ltp = tsl.get_ltp_data(names=['NIFTY JAN FUT'])['NIFTY JAN FUT']
except Exception as e:
    print(e)
    continue

# Apply Indicators
index_chart['rsi'] = talib.RSI(index_chart['close'], timeperiod=14)

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'])

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')

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

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']
bc2 = first_candle['close'] > first_candle['SUPERT_10_2.0']
bc3 = first_candle['close'] > first_candle['vwma']
bc4 = first_candle['rsi'] > 60 
bc5 = first_candle['rsi'] < 80
#(data['RSI'] > 60) & (data['RSI'] < 80)
bc6 = second_candle['volume'] > 50000
bc7 = traded == "no"
bc8 = index_ltp > first_candle['low']

print(f"BUY \t {current_time} \t {bc1} \t {bc2} \t {bc3} \t {bc4} \t {bc5} \t {bc7} \t {bc8} \t first_candle {str(first_candle['timestamp'].time())}")

# Sell Entry Conditions
sc1 = first_candle['close'] < first_candle['vwap']
sc2 = first_candle['close'] < first_candle['SUPERT_10_2.0']
sc3 = first_candle['close'] < first_candle['vwma']
sc4 = first_candle['rsi'] > 20
sc5 = first_candle['rsi'] < 40
sc6 = second_candle['volume'] > 50000
sc7 = traded == "no"
sc8 = index_ltp < first_candle['high']

print(f"SELL \t {current_time} \t {sc1} \t {sc2} \t {sc3} \t {sc4} \t {sc5} \t {sc7} \t {sc8} \t first_candle {str(first_candle['timestamp'].time())} \n")

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

    CE_symbol_name, PE_symbol_name, strike_price = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry=0)
    # CE_symbol_name, PE_symbol_name, strike_price = tsl.ATM_Strike_Selection(Underlying='ACC', Expiry=0)
    if (CE_symbol_name is None) or (PE_symbol_name is None):
        continue



    lot_size = tsl.get_lot_size(CE_symbol_name) * 1
    entry_orderid = tsl.order_placement(CE_symbol_name, 'NFO', lot_size, 0, 0, 'MARKET', 'BUY', 'MIS')
    traded = "yes"
    trade_info.update({"options_name": CE_symbol_name, "qty": lot_size, "sl": first_candle['low'], "CE_PE": "CE"})

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

    CE_symbol_name, PE_symbol_name, strike = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry=0)
    if (CE_symbol_name is None) or (PE_symbol_name is None):
        continue


    lot_size = tsl.get_lot_size(PE_symbol_name) * 1
    entry_orderid = tsl.order_placement(PE_symbol_name, 'NFO', lot_size, 0, 0, 'MARKET', 'BUY', 'MIS')
    traded = "yes"
    trade_info.update({"options_name": PE_symbol_name, "qty": lot_size, "sl": first_candle['high'], "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:
        sl_hit = index_ltp < trade_info['sl']
        tg_hit = index_ltp < running_candle['SUPERT_10_2.0']

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

    if short_position:
        sl_hit = index_ltp > trade_info['sl']
        tg_hit = index_ltp > running_candle['SUPERT_10_2.0']

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

Hi @Rajashekhar_Rangappa
Yes I have raised this issue to Dhan Team.

1 Like

Hi @Rajashekhar_Rangappa @Arun_Rawat

There seems to be an issue in pnl function…
We are working on its fix, don’t use pnl function till then as it may give incorrect data.

2 Likes

Hi @CHETAN_99

Use this tested framework code,

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    = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzM2ODYwMTMxLCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMjc5MDMzNyJ9.Leop6waGeVfmBOtczNEcjRWmC8pUGWQf54YPINGDi_PZjk1IvW-DDdaYXsgM_s8McOT44q4MjEQxGXU0lduK0A"
tsl         = Tradehull(client_code,token_id)


# 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")







1 Like

Hi @Siddh_Shah

Solution link : Learn Algo Trading with Python | Codes | Youtube Series - #983 by Tradehull_Imran

1 Like

Hello @Tradehull_Imran Sir
aaj subah se ye error aa rha hai :point_down: (same code is yesterday runing fine but today i am facing this essue) please help

Exception in Getting OHLC data as Check the Tradingsymbol or Exchangepaste code here
index_chart_5 = tsl.get_historical_data(tradingsymbol='NIFTY JAN FUT', exchange='NFO', timeframe="5")

Sir, I am getting the Error by Running this code addressed to Mr.Chetan.
How to resolve it sir.

C:\Users\RP\Desktop\DHAN Algorhythemic Trading\Codes from MadeForTrade Forum>py “IA to Chetan MumWrkShop.py”
-----Logged into Dhan-----
This BOT Is Picking New File From Dhan
Got the instrument file
Traceback (most recent call last):
File “IA to Chetan MumWrkShop.py”, line 61, in
wb = xw.Book(‘Live Trade Data.xlsx’)
File “C:\Users\RP\AppData\Local\Programs\Python\Python38\lib\site-packages\xlwings\main.py”, line 929, in init
impl = app.books.open(
File “C:\Users\RP\AppData\Local\Programs\Python\Python38\lib\site-packages\xlwings\main.py”, line 5153, in open
raise FileNotFoundError(“No such file: ‘%s’” % fullname)
FileNotFoundError: No such file: ‘Live Trade Data.xlsx’

Hi @Tradehull_Imran , I have kept the sleep time as time.sleep(1), still I am getting below error
Scanning APOLLOHOSP…
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.’}}
Insufficient data for APOLLOHOSP. Skipping…
Traceback (most recent call last):
File “Breakout Algo on Stock Options.py”, line 37, in
time.sleep(0.2)
KeyboardInterrupt

Can you please suggest what appropriate sleep time I should keep? I was running two algos at the same time with the same watchlist.

Hello Imran, can you help me to create a new code with strategy ?

thank you. Do let us know once the new document is ready.

1 Like

I am not able to get Historical price for Future Contract (BANK Nifty JAN 25) via Tradehull API. Exception in Getting OHLC data as For Future or Commodity, DAY - Timeframe not supported by API, SO choose another timeframe Please help on fixing this error. [image]

Thank you Rahul Bhai for arranging upcoming event at bangalore :pray:

is trade hull version 2 is the order placement updated for bracket orders?

Hi @vinay_kumaar ,

It seems the code is working fine. Do try again and let us know if you face any issue

Hi @Vasili_Prasad ,

We need to create “Live Trade Data.xlsx” excel sheet as the error suggests:

FileNotFoundError: No such file: ‘Live Trade Data.xlsx’

Hello @Tradehull_Imran Sir
code Runing fine (P C file missing problem)

1 Like

Hi @ddeogharkar ,

Below are the possible solutions:

  1. We can use 2 Dhan account with different API’s.

  2. Since the watchlist is same, make a data receiver file that will retrieve the data for both the algo’s. The data should be sent in excel/ database/ pickle file and both the algo’s will refer to the same excel/ database/ pickle file for fetching data .

  3. Also you can double the sleep time in Dhan_Tradehull_V2.

2 Likes