Learn Algo Trading with Python | Codes | Youtube Series

Hi @Subhajitpanja,

Kindly delete the old existing file once manually and then restart the program.

Let me know still if you face any issues.

Hi @Rajashekhar_Rangappa ,

the code seems to be correct.

Hi @Rajashekhar_Rangappa ,

This will be covered in the upcoming sessions.

Hi @Ganesh,

refer the below sample code :

entry_orderid                     = tsl.order_placement(tradingsymbol=name ,exchange='NSE', quantity=orderbook[name]['qty'], price=0, trigger_price=0,    order_type='LIMIT',     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]['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"

Hi @Tradehull_Imran sir

stock = 'SUNDARAM'
# ltp was 2.08
new_stop_loss = 2.04
sell_price =  2.02

modified_id = trade_hull.modify_order(
	order_id=10125021240964, # Stop_loss_order_id
	order_type='STOPLIMIT',
	quantity=1,
	price=sell_price,
	trigger_price=new_stop_loss
)

order_status_modified = trade_hull.get_order_status(modified_id)
print(f"Order status: {order_status_modified}")
print(f"Modified order id: {modified_id}")

Error

-----Logged into Dhan-----
reading existing file all_instrument 2025-02-12.csv
Got the instrument file
Got exception in modify_order as {'status': 'failure', 'remarks': {'error_code': 'DH-906', 'error_type': 'Order_Error', 'error_message': 'Missing required fields, bad values for parameters etc.'}, 'data': {'errorType': 'Order_Error', 'errorCode': 'DH-906', 'errorMessage': 'Missing required fields, bad values for parameters etc.'}}
Error at getting order status as Check the order id, Error as None

on Dhan the status showed Triggered and was pending execution.

second issue -

Response for Rejection RMS:6125021238384:Rate Not Within Ckt Limit 1.73 To 2.60

how do we avoid this reason of rejection?
In case the options the stop loss needs to be put at 20% or higher, will it still show rejection like this?

@Tradehull_Imran Sir,

what about this issue…?

@Tradehull_Imran sir,
I have tried both way
keeping dependency folder deleting only old file

and deleting entire dependency folder itself result is same

no excel file generated left side source section
right side you can see in console
Reading from excel file

def trail_stop_loss(self, trade_dict, trigger, sell, paper_trade=True):

	time.sleep(5)

	india_tz = pytz.timezone('Asia/Kolkata')
	end_time = datetime.time(15, 15)

	if not paper_trade:
		for stock, details in trade_dict.items():
			entry_order_id = details['Entry_order_id']
			average_buy_price = self.get_executed_price(entry_order_id)
			trade_dict[stock]['Average_buy_price'] = average_buy_price
			trade_dict[stock]['Position_status'] = 'Open'

	print(f"\nStock selected for trading and their details:\n{trade_dict}")
	self.logger.info(f"\nStock selected for trading and their details:\n{trade_dict}")

	while True:
		current_time_india = datetime.datetime.now(india_tz).time()

		if not paper_trade:
			if current_time_india >= end_time:
				print("\nTime is 3:15 PM or later. Cancelling all orders.")
				self.logger.info("\nTime is 3:15 PM or later. Cancelling all orders.")
				self.cancel_all_orders()
				break

			status_list = []
			for stock, details in trade_dict.items():
				stop_loss_order_id = details['Stop_loss_order_id']
				order_status = self.get_order_status(order_id=stop_loss_order_id)
				status_list.append(order_status)

			allowed_statuses = {'PENDING', 'TRANSIT', 'PART_TRADED', 'TRIGGERED'}
			if not any(status in allowed_statuses for status in status_list):
				print("\nBreaking the loop as no orders are PENDING, TRANSIT, TRIGGERED or PART_TRADED.")
				self.logger.info("\nBreaking the loop as no orders are PENDING, TRANSIT, TRIGGERED or PART_TRADED.")
				break

		for stock, details in trade_dict.items():
			call_or_put = details['Option']
			quantity = details['Quantity']
			stop_loss_trigger = details['Stop_Loss_trigger']
			Initial_sell_price = details['Initial_sell_price']
			sell_price = details['Sell_price']
			average_buy_price = details['Average_buy_price']
			entry_order_id = details['Entry_order_id']
			stop_loss_order_id = details['Stop_loss_order_id']
			postision_status = details['Position_status']

			ltp = self.get_ltp_data(names=[call_or_put])[call_or_put]

			if not paper_trade:
				stop_loss_order_status = self.get_order_status(order_id=stop_loss_order_id)
				if stop_loss_order_status != 'TRADED' and (ltp <= sell_price or ltp <= Initial_sell_price) and \
					postision_status == 'Open':
					try:
						self.cancel_order(entry_order_id)
						trade_dict[stock]['Position_status'] = 'Closed'
						print(f"\nCancelled the entry orders for {stock} & its option {call_or_put}")
						self.logger.info(
							f"\nCancelled the entry orders for {stock} and its option {call_or_put}")						
					except Exception as e:
						pass
						print(f"\nError cancelling entry order for {stock} and its option {call_or_put}: {e}")
						self.logger.exception(
							f"\nError cancelling entry order for {stock} and its option {call_or_put}: {e}")
					try:
						self.cancel_order(stop_loss_order_id)
						print(f"\nCancelled the stop loss orders for {stock} & its option {call_or_put}")
						self.logger.info(
							f"\nCancelled the stop loss orders for {stock} and its option {call_or_put}")
					except Exception as e:
						pass
						print(f"\nError cancelling stop loss order for {stock} and its option {call_or_put}: {e}")
						self.logger.exception(
							f"\nError cancelling stop loss order for {stock} and its option {call_or_put}: {e}")

			profit_percentage = ((ltp - average_buy_price) / average_buy_price) * 100

			# Determine the new stop loss based on profit percentage
			if profit_percentage >= 75:
				new_trigger = ltp * 0.97  # 3% stop loss trigger
				new_sell_price = ltp * 0.95  # 5% stop loss
			elif profit_percentage >= 50:
				new_trigger = ltp * 0.93  # 7% stop loss trigger
				new_sell_price = ltp * 0.90  # 10% stop loss
			else:
				new_trigger = ltp * trigger  # 17% stop loss trigger
				new_sell_price = ltp * sell  # 20% stop loss

			if new_trigger > stop_loss_trigger and new_sell_price > sell_price:

				if not paper_trade:
					try:
						modified_id = self.modify_order(
							order_id=stop_loss_order_id,
							order_type='STOPLIMIT',
							quantity=quantity,
							price=sell_price,
							trigger_price=new_trigger
						)
						trade_dict[stock]['Stop_loss_order_id'] = modified_id
					except Exception as e:
						print(f"\nError modifying order for {stock} and its option {call_or_put}: {e}")
						self.logger.exception(
							f"\nError modifying order for {stock} and its option {call_or_put}: {e}"
						)

				trade_dict[stock]['Stop_Loss_trigger'] = new_trigger
				trade_dict[stock]['Sell_price'] = new_sell_price
				print(f"\nUpdated stop loss for {stock} and its option {call_or_put} to {new_trigger}")
				self.logger.info(f"\nUpdated stop loss for {stock} and its option {call_or_put} to {new_trigger}")

		time.sleep(2)

	print(f"\nTrailing stop loss loop ended.")
	self.logger.info(f"\nTrailing stop loss loop ended.")
	if paper_trade:
		print(f"\nSummary of the paper trades:\n{trade_dict}")
		self.logger.info(f"\nSummary of the paper trades:\n{trade_dict}")
	else:
		print(f"\nSummary of trades:\n{trade_dict}")
		self.logger.info(f"\nSummary of trades:\n{trade_dict}")

Hello Sir @Tradehull_Imran

I had a question, for trailing a stop loss, i designed this function, which just modifies the STOPLIMIT with new sell price and trigger price,

in tutorial we learned that, for options stop loss market order is not possible.
but if we somehow whats to simulate it, can we use cancel_order(order_id) , provided that we are tracking LTP and last updated trigger price,
we cancel the order if the ltp drop below last updated trigger price ?

let me know your opinion sir ?
or if you recommend something else ?

@Tradehull_Imran sir,

while viewing the code of Dhan_TardeHull_V2, I found that the
get_option_chain(self, Underlying, exchange, expiry): is commented.

below is the image of same.

if it is commented then how can it be called…?
I think thats why the error to fetch the option chain …?

is it intentionally commented or by mistake…?

Have a nice day

1 Like

Hello @Tradehull_Imran

Is it possible to code RSI “uptick” and “downtick” ?

I have the code and want to add the condition

import pdb
from Dhan_Tradehull_V2 import Tradehull
import pandas as pd
import talib
import time
import datetime

Client details

client_code = “19”
token_id = “1w”

Initialize Tradehull

tsl = Tradehull(client_code, token_id)

available_balance = tsl.get_balance()
leveraged_margin = available_balance5
max_trades = 2
per_trade_margin = (leveraged_margin/max_trades)
max_loss = (available_balance
1)/100*-1

watchlist = [‘ITC’]
traded_wathclist =

while True:

live_pnl = tsl.get_live_pnl()
current_time = datetime.datetime.now().time()

if current_time < datetime.time(9, 30):
	print("wait for market to start", current_time)
	continue

if (current_time > datetime.time(15, 00)) or (live_pnl < max_loss):
	order_details = tsl.cancel_all_orders()
	print("Market is over, Bye Bye see you tomorrow", current_time)
	break


for stock_name in watchlist:
	time.sleep(1)
	print(stock_name)

	chart_1          = tsl.get_historical_data(tradingsymbol = stock_name,exchange = 'NSE',timeframe="1")
	chart_5          = tsl.get_historical_data(tradingsymbol = stock_name,exchange = 'NSE',timeframe="5") # this call has been updated to get_historical_data call, 
	chart_15          = tsl.get_historical_data(tradingsymbol = stock_name,exchange = 'NSE',timeframe="15") # this call has been updated to get_historical_data call,

	if (chart_1 is None) or (chart_5 is None) :
		continue

	if (chart_1.empty) or (chart_5.empty):
		continue

	if (chart_15.empty) or (chart_15.empty):
		continue

	if (chart_15 is None) or (chart_15 is None) :
		continue


	# Conditions that are on 5 minute timeframe
	chart_5['rsi'] = talib.RSI(chart_5['close'], timeperiod=14) #pandas
	cc_5           = chart_5.iloc[-1]  #pandas  completed candle of 5 min timeframe
	uptrend        = cc_5['rsi'] < 30
	downtrend      = cc_5['rsi'] > 65

	'''
	# Conditions that are on 5 minute timeframe
	chart_5['upperband'], chart_5['middleband'], chart_5['lowerband'] = talib.BBANDS(chart_5['close'], timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
	cc_5           = chart_5.iloc[-1]   # pandas
	ub_breakout    = cc_1['high'] > cc_1['upperband']
	lb_breakout    = cc_1['low'] < cc_1['lowerband']

	# MACD Conditions that are on 5 minute timeframe
	chart_5['macd'], chart_5['macdsignal'], chart_5['macdhist'] = talib.MACDEXT(chart_5['close'], fastperiod=12, fastmatype=0, slowperiod=26, slowmatype=0, signalperiod=9, signalmatype=0)
	cc_5	 		= chart_5.iloc[-1]   # pandas
	up_cross       = cc_5['macd'] > cc_5['macdsignal']
	down_cross     = cc_5['macdsignal'] > cc_5['macd']
	'''

	no_repeat_order = stock_name not in traded_wathclist
	max_order_limit = len(traded_wathclist) <= max_trades


	if uptrend and no_repeat_order and max_order_limit:
		print(stock_name, "is in uptrend, Buy this script")

		sl_price          = round((cc_5['close']*0.98),1)
		qty               = int(per_trade_margin/cc_5['close'])
		sell_price        = round((cc_5['close']*1.01),1)

		buy_entry_orderid = tsl.order_placement(stock_name,'NSE', qty, 0, 0, 'MARKET', 'BUY', 'MIS')
		sl_orderid        = tsl.order_placement(stock_name,'NSE', qty, 0, sl_price, 'STOPMARKET', 'SELL', 'MIS')
		sell_orderid      = tsl.order_placement(stock_name,'NSE', qty, 0, sell_price, 'LIMIT', 'SELL', 'MIS')
		traded_wathclist.append(stock_name)

	if downtrend and no_repeat_order and max_order_limit:
		print(stock_name, "is in downtrend, Sell this script")

		sl_price          = round((cc_5['close']*1.02),1)
		qty               = int(per_trade_margin/cc_5['close'])
		buy_price          = round((cc_5['close']*0.98),1)

		buy_entry_orderid = tsl.order_placement(stock_name,'NSE', qty, 0, 0, 'MARKET', 'SELL', 'MIS')
		sl_orderid        = tsl.order_placement(stock_name,'NSE', qty, 0, sl_price, 'STOPMARKET', 'BUY', 'MIS')
		sell_orderid        = tsl.order_placement(stock_name,'NSE', qty, 0, buy_price, 'LIMIT', 'SELL', 'MIS')
		traded_wathclist.append(stock_name)

sl_orderid= tsl.order_placement(tradingsymbol=“NIFTY 20 FEB 24100 CALL” ,exchange=‘NFO’, quantity=75, price=0, trigger_price=3, order_type=‘STOPMARKET’, transaction_type =‘SELL’, trade_type=‘MIS’)

WHEN PLACING STOP LOSS ORDER , ALWAYS FAILED

@Tradehull_Imran

I want to place a stop-loss order after my buy order is executed, but my stop-loss order is rejected. Please help me resolve this.


strike = ‘NIFTY 13 FEB 23100 PUT’
lot_size = 75
entry = 11.0
sl = 10.55

Place entry order

orderid = tsl.order_placement(
tradingsymbol=strike,
exchange=‘NFO’,
quantity=lot_size,
price=entry,
trigger_price=0,
order_type=‘LIMIT’,
transaction_type=‘BUY’,
trade_type=‘MIS’
)

Check order status and place SL order if executed

while tsl.get_order_status(orderid) != “TRADED”:
pass # Wait until order is traded

Place stop-loss order

orderid = tsl.order_placement(
tradingsymbol=strike,
exchange=‘NFO’,
quantity=lot_size,
price=sl,
trigger_price=sl,
order_type=‘STOPMARKET’, # Use ‘STOPMARKET’ for SL-M
transaction_type=‘SELL’,
trade_type=‘MIS’
)

modified_order = tsl.modify_order(‘1125021326673’,order_type=‘STOPLIMIT’,quantity=1,price=8.50,trigger_price=8.75) cancel_order = tsl.cancel_order(‘6125021326513’)


I am facing error “screenshot attached” while running these commands, modified_order = tsl.modify_order(‘1125021326673’,order_type=‘STOPLIMIT’,quantity=1,price=8.50,trigger_price=8.75) and cancel_order = tsl.cancel_order(‘6125021326513’), cancel_order working for cancelling SL pending entries but it is not cancelling buy entries, once entries is made how shall be cancel it if it is traded. Should I use “entry_orderid = tsl.order_placement(tradingsymbol=‘IDEA’ ,exchange=‘NSE’, quantity=1, price=0, trigger_price=0, order_type=‘MARKET’, transaction_type=‘SELL’, trade_type=‘MIS’)” for selllling the bought entries, is it possible to cancel the buy entries using “cancel_order = tsl.cancel_order(‘6125021326513’)”. Kindly suggest solutions. Thank you

1 Like

Hi @anandc ,

There seems to be no issue to get ltp for ATM strike:

refer the below code, let me know if u face any issues:

ce_strike, pe_strike, strike = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry=0)
ltp = tsl.get_ltp_data([ce_strike, pe_strike])
1 Like

Hi @anandc ,

There are 2 get_option_chain() functions out of which one is commented, this can be ignored.

1 Like

I had the same question, i think for options, stop loss market orders are not allowed by regulations, so dhan does not have it on purpose.

i could be wrong, please correct me if so !

1 Like

For option STOPMARKET order is not supported, do use STOPLIMIT orders,

sl_orderid     = tsl.order_placement(tradingsymbol='NIFTY 19 DEC 24400 CALL' ,exchange='NFO', quantity=75, price=29, trigger_price=30, order_type='STOPLIMIT', transaction_type='SELL', trade_type='MIS')

2 Likes

Dear @Tradehull_Imran Sir

:rose: :rose: :rose: :rose: :rose: :rose: :rose: :rose: :rose:

आपके आशीर्वाद और सिखाए गए कौशल की वजह से मैं एल्गोरिदम सफलतापूर्वक बनाने में सक्षम हुआ। आपका ज्ञान और मार्गदर्शन मेरे लिए हमेशा अमूल्य रहेगा।
धन्यवाद, गुरुजी!

कोड की हर लाइन में, आपकी शिक्षा की छाप है,
एल्गोरिदम जो बना, उसमें आपके ज्ञान की थाप है।
सिर्फ तार्किक सोच नहीं, धैर्य भी सिखाया,
हे गुरुवर, आपका आभार, जो सफलता का रास्ता दिखाया

2 Likes

@Tradehull_Imran sir,

Thanks a lot sir… and pls, what about fetching complete option chain…?
With your support, finished another algo today, will test it live for couple of days… and then… will work on another for multi-client algo…

For multi-client, will all have to subscribe for data API or a single of them, to subscribe Data API… to place orders…?

have a nice day

Amazing @Tradehull_Imran sir,

Congratulations sir, salutes for your efforts and Claps for the finest documentation

5 Likes