While using the packages of Dhan_Tradehull , Dhan_Codebase etc. Is the privacy of user data assured while using those code. Is the execution data, strategy, code & other sensitive data available to Tradehull while using their package etc ? Is it safe ?
Hi @Tradehull_Imran Sir,
made Changes, but today still got error-
Reason - is
RMS:22250319231501:Insufficient Funds, required margin is 193311.75 and available margin 39391. Add Funds to Trade
my new code is-
sl_order_id = tsl.order_placement(option_symbol,
"NFO",
client_qty,
sl_price - 0.5,
sl_price,
"STOPLIMIT",
"SELL",
"MIS")
BTW, are both sl_price and triggr_price mandatory ? It seems like Selling CALLâŚ!! Pls correct the SL Order.
for your information this is the order status -
{'dhanClientId': '110XXXXXXXX0', 'orderId': '22250319231501', 'exchangeOrderId': '0', 'correlationId': '1102350080-1742359314096', 'orderStatus': 'REJECTED', **'transactionType': 'SELL**', 'exchangeSegment': 'NSE_FNO', 'productType': 'INTRADAY', 'orderType': 'STOP_LOSS_MARKET', 'validity': 'DAY', 'tradingSymbol': 'NIFTY-Mar2025-22850-PE', 'securityId': '50218', 'quantity': 75, 'disclosedQuantity': 0, 'price': 0.0, 'triggerPrice': 77.69, 'afterMarketOrder': False, 'boProfitValue': 0.0, 'boStopLossValue': 0.0, 'legName': 'NA', 'createTime': '2025-03-19 10:11:54', 'updateTime': '2025-03-19 10:11:54', 'exchangeTime': '0001-01-01 00:00:00', 'drvExpiryDate': '2025-03-20', **'drvOptionType': 'PUT',** 'drvStrikePrice': 22850.0, 'omsErrorCode': '0', 'omsErrorDescription': 'RMS:22250319231501:Insufficient Funds, required margin is 193311.75 and available margin 39391. Add Funds to Trade', 'algoId': '0', 'remainingQuantity': 75, 'averageTradedPrice': 0.0, 'filledQty': 0}
I am confused, I Simply want to place a Stop loss order after buying atm option. after scrolling back, I found in your reply this -
sl_orderid = tsl.order_placement(stock_name,
'NSE',
1,
0,
sl_price,
'STOPMARKET',
'SELL',
'MIS')
in your sl order, you have used 0 and i hv used sl_price-0.5 and for trigger price, u hv used sl_price and I too hv used same⌠I am confused, please explain and tell me exact code to be usedâŚ
Where m i going wrong? Pls explain
Have a nice dayâŚ
Regards
tsl.cancel_all_orders() is not working now it appears, its not cancelling any open orders
Hi,
if you are using get_intraday_data() method, then its deprecated, instead use get_historical_data() to fetch the data. Also try to use print(your_stockname) so that you will know which stock is generating this error. pls scroll upward to get proper method, Imran Sir had earlier answered on this topic. pls check this link-
HTH,
Regards
Hi @Ganesh_Surwase ,
Refer the below code to place AMO orders:
orderid = tsl.order_placement(tradingsymbol="ACC", exchange="NSE", quantity=1, price=0, trigger_price=0, order_type='MARKET', transaction_type='BUY', trade_type='MIS', after_market_order=True, amo_time='OPEN')
- tsl.order_placement(tradingsymbol: str, exchange: str, quantity: int, price: int, trigger_price: int, order_type: str, transaction_type: str, trade_type: str, disclosed_quantity=0, after_market_order=False, validity=âDAYâ, amo_time=âOPENâ, bo_profit_value=None, bo_stop_loss_value=None) â str
- Arguments:
- tradingsymbol (str): The trading symbol (e.g., âNIFTY 21 NOV 23300 CALLâ).
- exchange (str): The exchange (e.g., âNFOâ, âMCXâ, âNSEâ).
- quantity (int): The number of contracts to buy/sell.
- price (int): The price at which to place the order.
- trigger_price (int): The trigger price for stop orders.
- order_type (str): Type of order (âMARKETâ, âLIMITâ, âSTOPLIMITâ, âSTOPMARKETâ).
- transaction_type (str): Type of transaction (âBUYâ or âSELLâ).
- trade_type (str): Type of trade (âMISâ, âMARGINâ, âMTFâ, âCOâ, âBOâ, âCNCâ).
- disclosed_quantity (int, optional): Quantity disclosed to the market (default is 0).
- after_market_order (bool, optional): Whether it is an after-market order (default is False).
- validity (str, optional): Validity of the order (âDAYâ, âIOCâ).
- amo_time (str, optional): AMO time (âPRE_OPENâ, âOPENâ, âOPEN_30â, âOPEN_60â) if after-market order.
For more details refer the below URL:
Dhan-Tradehull ¡ PyPI
Hi @trader_in_loss ,
Yes, using the Dhan_Tradehull
, Dhan_Codebase
, and related packages is completely safe. These libraries do not collect, transmit, or store any user data, execution details, strategies, or code.
They function purely as execution tools and do not have any mechanisms to access or extract sensitive information.
Hi @Jana_HS ,
The issue may arise because max_risk_for_today
exceeds the live PNL, causing the code to break midway.
Hi @anandc ,
Your code seems to be right for STOPLIMIT
order, but the order status mentions that the account has in sufficient funds,
{âdhanClientIdâ: â110XXXXXXXX0â, âorderIdâ: â22250319231501â, âexchangeOrderIdâ: â0â, âcorrelationIdâ: â1102350080-1742359314096â, âorderStatusâ: âREJECTEDâ, âtransactionTypeâ: 'SELLâ, âexchangeSegmentâ: âNSE_FNOâ, âproductTypeâ: âINTRADAYâ, âorderTypeâ: âSTOP_LOSS_MARKETâ, âvalidityâ: âDAYâ, âtradingSymbolâ: âNIFTY-Mar2025-22850-PEâ, âsecurityIdâ: â50218â, âquantityâ: 75, âdisclosedQuantityâ: 0, âpriceâ: 0.0, âtriggerPriceâ: 77.69, âafterMarketOrderâ: False, âboProfitValueâ: 0.0, âboStopLossValueâ: 0.0, âlegNameâ: âNAâ, âcreateTimeâ: â2025-03-19 10:11:54â, âupdateTimeâ: â2025-03-19 10:11:54â, âexchangeTimeâ: â0001-01-01 00:00:00â, âdrvExpiryDateâ: â2025-03-20â, âdrvOptionTypeâ: âPUTâ, âdrvStrikePriceâ: 22850.0, âomsErrorCodeâ: â0â, âomsErrorDescriptionâ: âRMS:22250319231501:Insufficient Funds, required margin is 193311.75 and available margin 39391. Add Funds to Tradeâ, âalgoIdâ: â0â, âremainingQuantityâ: 75, âaverageTradedPriceâ: 0.0, âfilledQtyâ: 0}
Hi @Msk92 ,
Kindly use the updated codebase version 3.0.6.
- 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 :
Refer the below pypi link for more details:
https://pypi.org/project/Dhan-Tradehull/
Hi @Tradehull_Imran SIR,
I have 40K, out of which, say I bought put at 100 rs then 7500 will get minus from account, still balance will be 32500, so do placing stop loss need margin � Also, my sl_Price is 20% of buy price, which means 80 will be my sl level, so 80*75=6000, which is very less than my balance⌠!!! then why insufficient fund?
Sir, Kuch to gadbad hain, jo mujhe samaz nahi aa rahi hainâŚ
Doesnât seem to work
-----Logged into Dhan-----
reading existing file all_instrument 2025-03-19.csv
Got the instrument file
Exception in Getting OHLC data as âintâ object has no attribute âupperâ
Traceback (most recent call last):
File âScreener 1.pyâ, line 18, in
chart[ârsiâ] = talib.RSI(chart[âcloseâ], timeperiod=14)
TypeError: âNoneTypeâ object is not subscriptable
C:\Users\Ajay Singh Rajput\Downloads\6. Session6- 1st Live Algo\6. Session6- 1st Live Algo\1st live Algo>
watchlist = ["SHRIRAMFIN", "HDFCBANK","COALINDIA","TRENT","HINDALCO","AXISBANK","ADANIENT","ADANIPORTS","GRASIM","RELIANCE","DRREDDY","TATASTEEL","LT","ITC","HchartCLIFE","ASIANPAINT","HEROMOTOCO","NTPC","APOLLOHOSP","POWERGRID","ICICIBANK","BAJFINANCE","SBIN","BEL","JSWSTEEL","HINDUNILVR","ONGC","CIPLA","KOTAKBANK","EICHERMOT","SBILIFE","BPCL","BAJAJFINSV","HCLTECH","ULTRACEMCO","MARUTI","SUNPHARMA","NESTLEIND","TCS","BAJAJ-AUTO","BRITANNIA","INFY","TATACONSUM","TITAN","TATAMOTORS","M&M","BHARTIARTL","WIPRO","TECHM","INDUSINDBK",]
for stock in watchlist:
chart = tsl.get_historical_data(stock, 'NSE', 5)
chart['rsi'] = talib.RSI(chart['close'], timeperiod=14)
lcc = chart.iloc[-2]
uptrend = lcc['rsi'] > 60
downtrend = lcc['rsi'] < 30
if uptrend:
print(stock, "is in uptrend")
if downtrend:
print(stock, "is in downtrend")
Dear @RahulDeshpande @Tradehull_Imran,
Iâve been following your âALGO TRADING WITH PYTHONâ series and really enjoying the content. However, I noticed that it has been over five months and the series is still incomplete.
I completely understand that creating quality content takes time, but I (and many others) am eagerly waiting for the back-testing videos. Would it be possible to upload more frequently?
Thanks for all the hard work you put into your contentâI really appreciate it!
Thanks
@Tradehull_Imran Dear Sir, I just wanted to take a moment to sincerely thank you for your invaluable guidance and support in teaching us automated trading using Python. Your in-depth knowledge, clear explanations, and practical insights have made learning this complex topic both engaging and insightful.
The skills youâve shared will undoubtedly help me in my trading journey. I truly appreciate the effort you put into making each session informative and interactive.
Once again, thank you for your mentorship and for making this learning experience so rewarding. I look forward to applying what Iâve learned and continuing to grow in this field.
Sir, I require assistance with my order execution algorithm, as I am experiencing difficulties.
I have developed an Index Scanner Algo and Order execution Algo, the scanner is working efficiently. The scanner updates key trading parameters such as strike price, entry price, target price, and stop-loss (SL) price in an Excel file. Additionally, the Excel file incorporates automation using VBA to update buy condition, sl trigger price, lock profit, initial tsl, final tsl, exit status and exchange.
However, there are some issues with the order execution algo:
- Sometimes, the stop-loss (SL) order is not placed as expected.
- Occasionally, SL order modifications do not work properly, leading to execution errors.
I have attached my excel sheet and code, please help me to structure the code properly into a well-organized framework.
Code_______
import pdb
import time
import talib
import logging
import datetime
import traceback
import pandas as pd
import xlwings as xw
import logging # LOGGING ADDED
from pprint import pprint
from Dhan_Tradehull import Tradehull
Configure logging # LOGGING ADDED
log_handler = logging.FileHandler(âtrade_log.logâ, mode=âaâ, encoding=âutf-8â) # Set encoding explicitly
log_handler.setFormatter(logging.Formatter(â%(asctime)s - %(levelname)s - %(message)sâ))
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(log_handler)
def log_and_print(message, level=âinfoâ):
âââLogs and prints messages simultaneously.âââ
print(message)
if level == âinfoâ:
logger.info(message)
elif level == âwarningâ:
logger.warning(message)
elif level == âerrorâ:
logger.error(message)
elif level == âcriticalâ:
logger.critical(message)
Client details for Dhan API
client_code = âxxxxxxxxxxxxâ
token_id = âxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxâ
tsl = Tradehull(client_code, token_id)
wb = xw.Book(â00. Trade_Details.xlsmâ)
Live_Trading = wb.sheets[âLive_Tradingâ]
Orderbook = wb.sheets[âOrderbookâ]
previous_sl_prices = {}
order_entry_time = {}
trade_count = 0
trade_pnl =
Live_Trading.range(âA2:H1000â).value = None
Live_Trading.range(âJ2:K1000â).value = None
Live_Trading.range(âM2:R1000â).value = None
Live_Trading.range(âT2:X1000â).value = None
log_and_print(âTrading script startedâ) # LOGGING ADDED
while True:
try:
watchlist = Live_Trading.range(âB2â).expand(âdownâ).value
if watchlist is None:
log_and_print(âWatchlist is empty. RetryingâŚâ, âwarningâ) # LOGGING ADDED
time.sleep(1)
continue
if isinstance(watchlist, str):
watchlist = [watchlist]
current_time = datetime.datetime.now()
# Fetch LTP for all scripts
try:
ltp_for_all_scripts = tsl.get_ltp_data(names=watchlist) # UPDATED LOGIC
except Exception as e:
log_and_print(f"Error fetching LTP data: {e}", "error") # LOGGING ADDED
continue
for row_no, name in enumerate(watchlist, start=2): # UPDATED LOGIC - Loop through all rows
try:
if name is None:
log_and_print(f"Skipping None value in row {row_no}.", "warning") # LOGGING ADDED
continue
p_column_value = Live_Trading.range(f'P{row_no}').value # UPDATED LOGIC
if p_column_value is not None and p_column_value != "": # UPDATED LOGIC - Skip rows where P is not blank
# log_and_print(f"Skipping row {row_no} as column P is not blank.", "info") # LOGGING ADDED
continue
ltp = ltp_for_all_scripts.get(name)
if ltp is None:
log_and_print(f"Skipping {name}: LTP not found.", "warning") # LOGGING ADDED
continue
log_and_print(f"Updating LTP: {name} LTP:{ltp}") # LOGGING ADDED
Live_Trading.range(f'G{row_no}').value = ltp # UPDATED LOGIC - Update LTP for each row
# Proceed with the existing trade logic for each row
is_this_script_traded = Live_Trading.range(f'J{row_no}').value
buy_cell_value = Live_Trading.range(f'H{row_no}').value
if is_this_script_traded is not None:
buy_order_status = tsl.get_order_status(is_this_script_traded)
Live_Trading.range(f'Q{row_no}').value = buy_order_status
log_and_print(f"Order {is_this_script_traded} status: {buy_order_status}") # LOGGING ADDED
if buy_order_status == "PENDING":
if name in order_entry_time:
elapsed_time = (current_time - order_entry_time[name]).total_seconds() / 60
if elapsed_time > 4:
log_and_print(f"Cancelling buy order for {name} after 5 minutes.", "warning") # LOGGING ADDED
tsl.cancel_order(is_this_script_traded)
Live_Trading.range(f'J{row_no}').value = None
del order_entry_time[name]
else:
order_entry_time[name] = current_time
if buy_cell_value == "BUY" and is_this_script_traded is None and trade_count < 3:
if trade_count == 2 and len(trade_pnl) >= 2 and trade_pnl[0] < 0 and trade_pnl[1] < 0:
log_and_print("Skipping third trade due to previous losses.", "info") # LOGGING ADDED
continue
quantity = tsl.get_lot_size(name)
Live_Trading.range(f'X{row_no}').value = quantity
sl_trigger_price = Live_Trading.range(f'I{row_no}').value
entry_price = Live_Trading.range(f'C{row_no}').value
sl_price = Live_Trading.range(f'N{row_no}').value
exch = Live_Trading.range(f'Y{row_no}').value
margin_available = tsl.get_balance()
margin_required = entry_price * quantity
if margin_available < margin_required + 50:
continue
entry_orderid = tsl.order_placement(
tradingsymbol=name, exchange=exch, quantity=quantity,
price=entry_price, trigger_price=0,
order_type='LIMIT', transaction_type='BUY', trade_type='MIS'
)
log_and_print(f"Buy order placed: {name} at {entry_price}") # LOGGING ADDED
if entry_orderid:
Live_Trading.range(f'J{row_no}').value = entry_orderid
trade_count += 1
order_entry_time[name] = current_time
buy_order_status = tsl.get_order_status(entry_orderid)
Live_Trading.range(f'Q{row_no}').value = buy_order_status
log_and_print(f"Buy order status: {buy_order_status}") # LOGGING ADDED
# aa=Live_Trading.range(f'K{row_no}').value
# print(aa)
if entry_orderid is not None and Live_Trading.range(f'K{row_no}').value is None and buy_order_status == "TRADED":
sl_orderid = tsl.order_placement(
tradingsymbol=name, exchange=exch, quantity=quantity,
price=sl_price, trigger_price=sl_trigger_price,
order_type='STOPLIMIT', transaction_type='SELL', trade_type='MIS'
)
log_and_print(f"SL order placed: {name} at {sl_price}") # LOGGING ADDED
Live_Trading.range(f'K{row_no}').value = sl_orderid
previous_sl_prices[name] = sl_price
new_sl_price = Live_Trading.range(f'N{row_no}').value
if name in previous_sl_prices and previous_sl_prices[name] != new_sl_price:
log_and_print(f"SL changed: {name} {previous_sl_prices[name]} â {new_sl_price}") # LOGGING ADDED
modify_status = tsl.modify_order(
order_id=sl_orderid,
order_type="STOPLIMIT",
quantity=quantity,
price=new_sl_price,
trigger_price=new_sl_price + 0.1,
disclosed_quantity=0,
validity="DAY"
)
if modify_status:
previous_sl_prices[name] = new_sl_price
except Exception as e:
log_and_print(f"Error processing {name}: {e}", "error") # LOGGING ADDED
traceback.print_exc()
continue
except Exception as e:
log_and_print(f"Unexpected error: {e}", "critical") # LOGGING ADDED
traceback.print_exc()
time.sleep(1)
sir,
i tried to run loop to fetch daily historical data(time frame DAY) by below listed coding
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 datetime
client_code = ââ
token_id = ââ
tsl = Tradehull(client_code,token_id)
watchlist = [âINDUSINDBKâ,âTATAMOTORSâ,âULTRACEMCOâ,âPOWERGRIDâ,âTATASTEELâ,âBAJAJFINSVâ,âJSWSTEELâ,âSUNPHARMAâ,âICICIBANKâ,âCOALINDIAâ,âGRASIMâ,âONGCâ,âSBILIFEâ,âBELâ,âNTPCâ,âITCâ,âTECHMâ,âSBINâ,âHINDALCOâ,âAXISBANKâ,âLTâ,âMARUTIâ,âHDFCLIFEâ,âDRREDDYâ,âWIPROâ,âTRENTâ,âTATACONSUMâ,âBAJAJ-AUTOâ,âHDFCBANKâ,âCIPLAâ,âBAJFINANCEâ,âKOTAKBANKâ,âM&Mâ,âADANIPORTSâ,âHCLTECHâ,âRELIANCEâ,âTCSâ,âHINDUNILVRâ,âNESTLEINDâ,âTITANâ,âADANIENTâ,âSHRIRAMFINâ,âASIANPAINTâ,âHEROMOTOCOâ,âBHARTIARTLâ,âBPCLâ,âEICHERMOTâ,âAPOLLOHOSPâ,âINFYâ,âBRITANNIAâ]
for name in watchlist:
#print(name)
daily_data = tsl.get_historical_data(tradingsymbol= name,exchange=âNSEâ,timeframe=âDAYâ)
Am trying to trade the Nifty ATM Strikes of next week (27 Mar) expiry . But the data is fetching for Nifty ATM Strikes only but its showing as FinNifty. Even the Python code is referring for Nifty only. Is there any glitch on DHAN API.
Hi @anandc ,
There is an API call in Dhan TradeHull codebase⌠which can fetch margin required to place an order.
margin = tsl.margin_calculator(tradingsymbol='NIFTY 19 DEC 24400 CALL', exchange='NFO', transaction_type='BUY', quantity=25, trade_type='MARGIN', price=43, trigger_price=0)
Also you can check the available balance in your account;
tsl.get_balance()
Hi @Ajay_Singh_Rajput ,
The code seems to be right, make sure you have subscribed to the data API.
Hi @iamsanjay ,
Can you elaborate your issue?
Hi @Mahikbs ,
Use the below code to fetch ATM strikes of next week.
CE_symbol_name, PE_symbol_name, atm_strike = tsl.ATM_Strike_Selection(Underlying='NIFTY', Expiry=1)