Learn Algo Trading with Python | Codes | Youtube Series

Hi @Vinod_Kumar1

Do share your code as well, I will check if some optimization in code is possible or not.

Also tagging @Hardik for rate limits.

@Tradehull_Imran Sir,

Is there any way or source from where we can get older OHLCV of 3 minute or 5 minute timeframe data like 6 month or 1 year for stocks of our choices. if any other community member can help in the same, please help. thanks in advance.

Regards,

Hi @Vinod_Kumar1
we will be covering this in upcoming OSB video.

Hi @abhaynarayan27

The code seems to be working fine
Do use latest codebase file : Dhan_Tradehull_V2.py - Google Drive

Hi @TAPAS_KUMAR_DUTTA

Do share the access to tradehull_mentorship@tradehull.com

@Tradehull_Imran Sir Thanks For Solving The Query

1 Like

Done Sir.

1 Like

Thank you for replying sir. It is working now in VISUAL STUDIO CODE, I think there was something wrong with sublime text.

1 Like

Dear Sir @Tradehull_Imran,

I am getting following two errors, please help i am using ltp_data = tsl.get_ltp_data(open_stocks) every 60 seconds only for the stocks for which i have position open these could be max 2 to 5 at a time, still i am getting being blocked warnings.

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’}}

got exception in pnl as ‘Titan’

def monitor_open_positions():
    """
    Monitor open positions and manage stop-loss or profit targets in live mode.
    If limit orders don't trigger as expected, place market orders.
    """
    global current_positions, mode, order_api_calls, consolidated_data, tsl, data_api_calls

    if mode != "live":
        print("monitor_open_positions is not running because the mode is not live.")
        return

    while True:
        try:
            current_time = datetime.datetime.now(pytz.timezone("Asia/Kolkata"))
            
            # Get open stocks from current_positions
            open_stocks = [
                stock for stock, position in current_positions.items()
                if position["type"] != "None"
            ]

            # End-of-Day (EOD) position closure at 3:10 PM IST
            if current_time.time() >= datetime.time(15, 10) and mode == "live":
                if not open_stocks:
                    print("No open positions to Close at 3:10 PM IST.")
                else:
                    print("Closing all positions at 3:10 PM IST.")
                    message = "Closing all positions at 3:10 PM in monitoring mode"
                    send_telegram_message(message, ongroup)
                    with rate_limit_lock:
                        order_api_calls += 1
                    tsl.cancel_all_orders()  # Cancel all open orders
                    force_close_positions()  # Force close open positions               
                    break  # Exit monitoring loop after EOD closure

            if not open_stocks:
                print("No open positions to monitor.")
                time.sleep(120)  # Monitor every 120 seconds if no open positions
                continue

            print(f"Monitoring open positions for stocks: {', '.join(open_stocks)}")
            message=f"Monitoring open positions for stocks: {', '.join(open_stocks)}"
            
            if mode == 'live':
                send_telegram_message(message)

            ltp_data = {}
            with rate_limit_lock:
                data_api_calls += 1
            ltp_data = tsl.get_ltp_data(open_stocks)  # Correct usage of get_ltp_data
            
            # Retry mechanism for missing LTP
            retry_count = 0
            while retry_count < 3 and any(ltp is None for ltp in ltp_data.values()):
                print(f"LTP missing for some stocks. Retrying... ({retry_count+1}/3)")
                time.sleep(2)
                with rate_limit_lock:
                    data_api_calls += 1
                ltp_data = tsl.get_ltp_data(open_stocks)
                retry_count += 1

            # Handle missing LTP by fallback to last known price or skip
            for stock_name in open_stocks:
                ltp = ltp_data.get(stock_name)
                if ltp is None:
                    print(f"LTP missing for {stock_name}. Using last known price.")
                    ltp = (
                        consolidated_data[consolidated_data["stockName"] == stock_name]
                        .sort_values(by="timestamp", ascending=False)
                        .iloc[0]["close"]
                    )

                if ltp is None:
                    print(f"Warning: No LTP or fallback for {stock_name}. Skipping...")
                    continue
                # Monitor Stop-Loss and Profit Target
                position = current_positions[stock_name]
                check_and_manage_orders(stock_name, ltp, position)
            
            ManageOpenPositions(ltp_data)
            
            time.sleep(60)  # Monitor at intervals

        except Exception as e:
            print(f"Error in monitoring positions: {e}")
            time.sleep(10)  # Add small delay before retry


 tsl = Tradehull(client_id,access_token)
    ltp_data = tsl.get_ltp_data(names = ['BANKNIFTY', 'NIFTY','NIFTY 16 JAN 24000 CALL' ])
    print(ltp_data)

getting error anyone please help me

Hi all,

I am happy to share that the 20-depth market data is now live on DhanHQ APIs.

You can start using 20 - Market Depth directly with the documentation here - 20 Market Depth - DhanHQ Ver 2.0 / API Document

Read more about the feature here: Introducing: 20-Depth Market Data on DhanHQ Data APIs

4 Likes

Awesome @RahulDeshpande Ji. Delivered as promised.
Thank you.

Hi @Vinod_Kumar1

use this latest codebase file … its has rate limit issues fixed in it : Dhan_Tradehull_V2.py - Google Drive

Also are you running multiple algo in parallel or 1 algo only.

1 Like

Hi @kumarmohit

The code seems to be working fine. Delete all_instrument file inside Dependencies folder and try again.
let me know if it works

Hi @TAPAS_KUMAR_DUTTA

code seems to be working fine now

use below file

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
import math

warnings.filterwarnings("ignore")


# ---------------for dhan login ----------------
client_code = ""
token_id    = ""
tsl = Tradehull(client_code,token_id)



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

# index_chart = tsl.get_historical_data(tradingsymbol= watchlist, exchange='NSE', timeframe='15') 				# use for equity
#index_chart = tsl.get_historical_data(tradingsymbol= 'NIFTY JAN FUT', exchange='NFO', timeframe='15') 			# Use for Option 

def market_type(num):
	if num > 1.47:
		return "very_bullish"

	if 0.75 < num < 1.46:
		return "bullish"

	if 0 < num < 0.74:
		return "neutral"

	if -0.7 < num < 0:
		return "bearish"

	if num <= -0.7:
		return "very_bearish"


def sqn(df, period):
	df['pnl_sqn'] = ((df['close'] - df['open']) / df['open'])*100
	df['average_pnl'] = df['pnl_sqn'].rolling(period).mean()
	df['average_std'] = df['pnl_sqn'].rolling(period).std()
	name = 'sqn'
	df[name] = (math.sqrt(period)*df['average_pnl'])/df['average_std']
	df.drop(columns=['pnl_sqn', 'average_pnl', 'average_std'], inplace=True)
	return df



# Implementation
# sqn_lib.sqn(df=df, period=21)
# df['market_type'] = df['sqn'].apply(sqn_lib.market_type)


for name in watchlist:
	index_chart = tsl.get_historical_data(tradingsymbol = name,exchange = 'NSE',timeframe="15")
	index_chart = sqn(df=index_chart, period=21)

	index_chart['market_type'] = index_chart['sqn'].apply(market_type)
	last_candle   = index_chart.iloc[-1]
	market_type_x = last_candle['market_type']   # we cant keep variabe name same as fuction name

	print(f"Market Type for {name} is {market_type_x}")


	#---------------------------------- apply indicators -------------------------------------------------------------
	# rsi    
	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(34).mean() / index_chart['volume'].rolling(34).mean()


	# # volume
	# volume = 50,000


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


Also use latest version of codebase : Dhan_Tradehull_V2.py - Google Drive

1 Like

Still getting errors, Not sure if I am missing something


Can you please help me more @Tradehull_Imran sir

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

client_code = "......"
token_id    = "........"

tsl = Tradehull(client_code, token_id)
ltp_data = tsl.get_ltp_data(names = ['BANKNIFTY', 'NIFTY','NIFTY 16 JAN 23500 CALL' ])
print(ltp_data)

index_chart_5 = 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"]
ce_name,pe_name,strike  = tsl.ATM_Strike_Selection(Underlying="NIFTY", Expiry="16-01-2025")      #ATM strike function is not working 
pe_ltp 		  			= tsl.get_ltp_data(names=[pe_name])[pe_name]

Hi @Priyesh_Sharma

Send a detailed explanation of the rulesets.

Hi @Qaisar

Send a detailed explanation of the rulesets.

1 Like

Hi @Himansshu_Joshi

Send a detailed explanation of the rulesets.