Learn Algo Trading with Python | Codes | Youtube Series

SIR CAN I PLACE A PRICE ALART IN DHAN USING PYTHON CODE @Tradehull_Imran

@Tradehull_Imran
Hi Imran,

I am on 3 episode of Algo Trading course and tried to fetch previous_hist_data and intraday_hist_data but i am getting the error in attached print screenshot. could you please guide me why i am unable to fetch the data.

sir talib is not installing

if this statement is used in terminal pip install talib

out put is given below

(.venv) PS C:\Users\Intel\PycharmProjects\dhanhq> pip install talib
ERROR: Could not find a version that satisfies the requirement talib (from versions: none)
ERROR: No matching distribution found for talib
(.venv) PS C:\Users\Intel\PycharmProjects\dhanhq>

please share your whatsapp no sir

Hi @Vinod_Kumar1

I think its a version issue,

do use this upgraded codebase file : Dhan_Tradehull_V2.py - Google Drive

Note : The library will update when necessary, but the link to the codebase file remains same

1 Like

Hi @s_nandi

Yes Price or Condition based alerts can be made using dhanhq,
we do use telegram api / gmail api to create alerts

1 Like

Hi @Avi_Shetty

Some upgrades were made in dhan-tradehull codebase, regarding historical data

Apply this solution: Learn Algo Trading with Python | Codes | Youtube Series - #952 by Tradehull_Imran

1 Like

Hi @Sampathraj_Madagunak

See this session for installation process : https://www.youtube.com/watch?v=YAyIoDJYorA&list=PLnuHyqUCoJsPA4l9KRLrNpWLIfZ9ucLxx&index=8

Talib is installed after we run install_libraries.bat

and install_libraries uses TA_Lib-0.4.24-cp38-cp38-win_amd64.whl to install Talib

1 Like

sir, giving below error
Sell Signal Formed
exception got in ce_pe_option_df ‘<’ not supported between instances of ‘int’ and ‘str’
Algo is working 21:31:36.459860

Thanks Sir, Also update get_intraday_data for data fetching for specific date period like between from date and to date, although i have modified it for me, but it will be helpful & useful for all if same can be updated in Dhan_Tradehull_V2 from your side

	def get_intraday_datanew(self, tradingsymbol, exchange, timeframe, from_date=None, to_date=None, debug="NO"):            
		try:
			tradingsymbol = tradingsymbol.upper()
			exchange = exchange.upper()
			instrument_df = self.instrument_df.copy()

			# Map available timeframes
			available_frames = {
				2: '2T',    # 2 minutes
				3: '3T',    # 3 minutes
				5: '5T',    # 5 minutes
				10: '10T',   # 10 minutes
				15: '15T',   # 15 minutes
				30: '30T',   # 30 minutes
				60: '60T'    # 60 minutes
			}

			# Handle default date range (last 5 days)
			if from_date is None:
				from_date = (datetime.datetime.now() - datetime.timedelta(days=5)).strftime('%Y-%m-%d')
			if to_date is None:
				to_date = datetime.datetime.now().strftime('%Y-%m-%d')

			# Exchange mappings
			script_exchange = {
				"NSE": self.Dhan.NSE,
				"NFO": self.Dhan.FNO,
				"BFO": "BSE_FNO",
				"CUR": self.Dhan.CUR,
				"BSE": self.Dhan.BSE,
				"MCX": self.Dhan.MCX,
				"INDEX": self.Dhan.INDEX
			}
			instrument_exchange = {
				'NSE': "NSE",
				'BSE': "BSE",
				'NFO': 'NSE',
				'BFO': 'BSE',
				'MCX': 'MCX',
				'CUR': 'NSE'
			}
			index_exchange = {
				"NIFTY": 'NSE',
				"BANKNIFTY": "NSE",
				"FINNIFTY": "NSE",
				"MIDCPNIFTY": "NSE",
				"BANKEX": "BSE",
				"SENSEX": "BSE"
			}

			# Handle index exceptions
			if tradingsymbol in index_exchange:
				exchange = index_exchange[tradingsymbol]

			# Fetch security ID and instrument type
			if tradingsymbol in self.commodity_step_dict.keys():
				security_check = instrument_df[(instrument_df['SEM_EXM_EXCH_ID'] == 'MCX') &
											(instrument_df['SM_SYMBOL_NAME'] == tradingsymbol.upper()) &
											(instrument_df['SEM_INSTRUMENT_NAME'] == 'FUTCOM')]
				if security_check.empty:
					raise Exception("Check the Tradingsymbol")
				security_id = security_check.sort_values(by='SEM_EXPIRY_DATE').iloc[0]['SEM_SMST_SECURITY_ID']
			else:
				security_check = instrument_df[
					((instrument_df['SEM_TRADING_SYMBOL'] == tradingsymbol) | 
					(instrument_df['SEM_CUSTOM_SYMBOL'] == tradingsymbol)) &
					(instrument_df['SEM_EXM_EXCH_ID'] == instrument_exchange[exchange])
				]
				if security_check.empty:
					raise Exception("Check the Tradingsymbol")
				security_id = security_check.iloc[-1]['SEM_SMST_SECURITY_ID']

			instrument_type = security_check.iloc[-1]['SEM_INSTRUMENT_NAME']
			exchange_segment = script_exchange[exchange]

			# Fetch OHLC data from Dhan API
			ohlc = self.Dhan.intraday_minute_data(
				str(security_id), exchange_segment, instrument_type, from_date, to_date, int(1)
			)
			
			if debug.upper() == "YES":
				print(ohlc)

			if ohlc['status'] != 'failure':
				df = pd.DataFrame(ohlc['data'])
				if not df.empty:
					df['timestamp'] = df['timestamp'].apply(lambda x: self.convert_to_date_time(x))
					df = df.dropna(subset=['open', 'high', 'low', 'close'])
					
					# Filter for valid trading days
					df['timestamp'] = pd.to_datetime(df['timestamp'])
					df = df[(df['timestamp'].dt.date >= datetime.datetime.strptime(from_date, "%Y-%m-%d").date()) &
							(df['timestamp'].dt.date <= datetime.datetime.strptime(to_date, "%Y-%m-%d").date())]

					# Resample to desired timeframe
					if timeframe == 1:
						return df
					df = self.resample_timeframe(df, available_frames[timeframe])
					return df
				else:
					return df
			else:
				raise Exception(ohlc) 
		except Exception as e:
			print(e)
			self.logger.exception(f"Exception in Getting OHLC data as {e}")
			traceback.print_exc()

1 Like

Hi, tradehall@imran,
in session 8,
$$$$$$$ cc_5 = chart_5.iloc[-1] # pandas completed candle $$$$$$$

we used ilock[-2] for last completed candle in session 6
but ilock[-1] used for last completed candle in session 8 ---- I request u pls explain it . why are u use iloc[-1] ?

The code below is for Back testing (Paper Trade), working for me , coded for option trading in focus, you can modify it as per your requirement. Waiting for suggestions and remarks. Thank you.

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

client_code = "put your client_code"
token_id = "put your toekn_id"
tsl = Tradehull(client_code,token_id)
traded_watchlist = []
tradelist = []

############## Simulation Input #############
lot_size    = 15
lots_number = 100   #How many lots you want to trade for
watchlist   = {'Script':'BANKNIFTY 30 JAN 51200 PUT','Selected_date': '2025-01-03', 'exchange': 'NFO'}
#############################################

print("\nSimulation started for selected_date.....", datetime.datetime.now().strftime("%H:%M:%S"))
try:    
    data_1min = tsl.get_historical_data(watchlist['Script'], watchlist['exchange'], '1')
    data_1min = pd.DataFrame(data_1min)
    data_1min['timestamp'] = pd.to_datetime(data_1min['timestamp'])
    data_1min.set_index('timestamp', inplace=True)
    selected_date = pd.Timestamp(watchlist['Selected_date'])

    # Filter data for simulation
    data_1min_filtered = data_1min[data_1min.index.date < selected_date.date()]  # Data till
    final_data_1min = data_1min[data_1min.index.date == selected_date.date()]  # Data for

    def filter_market_hours(data):
        market_open = datetime.time(9, 15)
        market_close = datetime.time(15, 30)
        return data.between_time(market_open, market_close)

    def update_5min_data(data_1min_filtered):
        resampled = data_1min_filtered.resample('5T').agg({
            'open': 'first',
            'high': 'max',
            'low': 'min',
            'close': 'last',
            'volume': 'sum'
        })
        resampled = resampled.dropna(how='any')
        return filter_market_hours(resampled)

    def update_15min_data(data_1min_filtered):
        resampled = data_1min_filtered.resample('15T').agg({
            'open': 'first',
            'high': 'max',
            'low': 'min',
            'close': 'last',
            'volume': 'sum'
        })
        resampled = resampled.dropna(how='any')
        return filter_market_hours(resampled)

    data_5min_filtered = update_5min_data(data_1min_filtered)
    data_15min_filtered = update_15min_data(data_1min_filtered)

    for index, row in final_data_1min.iterrows():
        row_df = pd.DataFrame([row], index=[index])
        data_1min_filtered = pd.concat([data_1min_filtered, row_df]).sort_index()
        data_5min_filtered = update_5min_data(data_1min_filtered)
        data_15min_filtered = update_15min_data(data_1min_filtered)

        tradingsymbol = watchlist['Script']
        chart_1       = data_1min_filtered
        chart_5       = data_5min_filtered
        chart_15      = data_15min_filtered #use it if u need
        chart_1['rsi']  = talib.RSI(chart_1['close'], timeperiod=14)
        chart_5['rsi']  = talib.RSI(chart_5['close'], timeperiod=14)

        max_order_limit = len(traded_watchlist)
        if (max_order_limit < 1):
            bc_5    = (chart_5['rsi'].iloc[-2]) < chart_5['rsi'].iloc[-1]
            ltp     = chart_1['close'].iloc[-1]

            # Buy conditions
            if (bc_5): 
                if (chart_1['rsi'].iloc[-1] > 60):
                    buy_time     = chart_1.index[-1].strftime("%H:%M:%S")
                    buy_price    = ltp
                    sl_price     = chart_1['low'].iloc[-2]
                    traded_watchlist.append({"Script":tradingsymbol, "Buy": buy_price, "Buy_Time": buy_time, "SL_price": sl_price})

        #Selling
        max_order_limit = len(traded_watchlist)
        if (max_order_limit > 0):
            for wstock_name in traded_watchlist:                        
                tradingsymbol   = wstock_name["Script"]
                sl_price        = wstock_name["SL_price"]
                buy_price       = wstock_name["Buy"]
                buy_time        = wstock_name["Buy_Time"]
                
                wltp            = chart_1['close'].iloc[-1]
                sell_time       = chart_1.index[-1].strftime("%H:%M:%S")

                #Sell conditions
                if ((sl_price > wltp) or (chart_5['low'].iloc[-2] > wltp)): #Modify the selling condition as per your requirment
                    sell_price = wltp
                    quantity   = lot_size * lots_number
                    Trade_point  = round((sell_price - buy_price),2)
                    Trade_TO     =  sell_price + buy_price
                    Trade_PNL  = round((Trade_point*quantity - (40 + Trade_TO*quantity*0.0011)),2) #Broker and other charges included roughly 
                    tradelist.append({"SN": len(tradelist) + 1, "Script":tradingsymbol, "Buy": buy_price, "Buy_Time": buy_time, "SL_price": sl_price, "Sell": sell_price, "Sell_Time": sell_time, "Trade_point":Trade_point, "Trade_PNL":Trade_PNL})
                    traded_watchlist[:] = [item for item in traded_watchlist if item['Script'] != tradingsymbol]
except KeyboardInterrupt:
    print("\nProcess interrupted by user (Ctrl+C).")
except Exception as e:
    print("\nAn unexpected error occurred:", e)
finally:
    print("\nSimulation ended.....", datetime.datetime.now().strftime("%H:%M:%S"))
    print(f"\nFinal Trade Details for {watchlist['Selected_date']}:")
    if tradelist:
        for trade in tradelist:
            trade['Buy_Time'] = trade['Buy_Time'].strftime("%H:%M:%S") if isinstance(trade['Buy_Time'], datetime.time) else trade['Buy_Time']
            trade['Sell_Time'] = trade['Sell_Time'].strftime("%H:%M:%S") if isinstance(trade['Sell_Time'], datetime.time) else trade['Sell_Time']

        headers = tradelist[0].keys()
        column_widths = {header: max(len(str(header)), *(len(str(row[header])) for row in tradelist)) for header in headers}
        header_row = "  ".join(f"{header:<{column_widths[header]}}" for header in headers)
        print(header_row)
        for trade in tradelist:
            row = "  ".join(f"{str(value):<{column_widths[header]}}" for header, value in trade.items())
            print(row)
        Final_PNL   = round(sum(trade['Trade_PNL'] for trade in tradelist), 2)
        Final_point = round(sum(trade['Trade_point'] for trade in tradelist), 2)
        print(f"\nFinal_point of 1 unit: {Final_point}")
        print(f"Final_PNL of 1 lot: Rs.{Final_PNL}/-")
    else:
        print("No trades to display.")
2 Likes

@Tradehull_Imran - getting below error “ModuleNotFoundError: No module named ‘Dhan_Tradehull_V2’”.
And while installing pip install Dhan_Tradehull_V2, getting below error, any idea sir?
“ERROR: Could not find a version that satisfies the requirement Dhan_Tradehull_V2 (from versions: none)
ERROR: No matching distribution found for Dhan_Tradehull_V2”

@Tradehull_Imran sir Can You Share Strategy Backtesting Code

Hello sir Im Nimesh Guliana
Use API of Angel one
Algo for swing trading
Algo start time 9:15 end time 15:15
Algo for Equity time 1W chart
Strategy SME 50 for buy and SME 100 for sell ( just for try not for real )
Add
SL on last candel
in a day total trade will 4
no ripped trade
And more learn from you Sir

i hope you will make one video on it

1 Like
index_chart  = tsl.get_historical_data(tradingsymbol='NIFTY JAN FUT', exchange='NFO', timeframe="1")

Dear sir,
For retrieving historical data, previously we were getting 5 trading days data as mentioned in ‘DHANHQ API documentation’, but now i getting for only two days. I am using the latest version of Tradehull_V2. Is this error appearing for all of us? Kindly verify.

Hello Sir, I am not able to understand, whether Vote is registered OR not?
How to confirm my Vote Registration, Please.

VBR Prasad

Oh, That’s a great Initiative…

2 Likes

Hello everyone,

I would like to propose a backtest of a scalping strategy that I’ve been studying. This strategy uses a combination of moving averages and the Average Directional Index (ADX) to identify strong trends and potential trade entries.

Scalping Strategy Overview:

Indicators Used:

  1. Simple Moving Average (SMA) – A basic lagging indicator.
  2. Exponential Moving Average (EMA) – More responsive to recent price changes.
  3. Jurik Moving Average (JMA) – A leading indicator that reacts faster than both SMA and EMA.

Why Three Moving Averages?

  • SMA is lagging, EMA is more reactive, and JMA leads them all. This combination helps in filtering out noise and identifying trends more accurately.

Trend Identification Logic:

  • Buy Signal: If JMA > EMA > SMA, the market is in an uptrend.
  • Sell Signal: If JMA < EMA < SMA, the market is in a downtrend.

Additional Confirmation:

  • ADX Indicator: We only consider trades when the ADX is above 25, which indicates a strong trend.

Entry Conditions:

For a Buy Trade:

  1. Trend Check: Ensure JMA > EMA > SMA.
  2. ADX Confirmation: ADX value must be above 25.
  3. Entry Point: Enter the trade after a pullback when the price bounces upward.

For a Sell Trade:

  1. Trend Check: Ensure JMA < EMA < SMA.
  2. ADX Confirmation: ADX value must be above 25.
  3. Entry Point: Enter the trade after a retracement when the price drops downward.

Risk Management: Stop-Loss and Take Profit

  1. Stop-Loss:
  • Place your stop-loss at the high of the entry candle for a sell trade or the low of the entry candle for a buy trade.
  1. Take Profit:
  • Aim for a 1:1.5 risk-to-reward ratio initially.
  • Book 70% of your profit at this level.
  • For the remaining position, aim for a 1:2 risk-to-reward ratio and exit the trade completely at this point.

I believe this strategy could be effective for fast-paced intraday trades, especially in volatile markets. Backtesting this could give us valuable insights into its success rate and areas of improvement.

Looking forward to hearing your thoughts!

4 Likes

Sir Installation done,
certutil -generateSSTFromWU roots.sst
certutil -addstore -f root roots.sst

i tested run working fine sir,

thankyou very much sir

1 Like