Learn Algo Trading with Python | Codes | Youtube Series

@Tradehull_Imran thank sir for giving it a try …i actually figured out …i was putting quantity value wrong …as no. lots 1 instead of total quantity 1* 25 .
And i was using ‘NSE_FNO’ instead of dhan.NSE_FNO

I am avoiding tsl library as SSL issues requires to know admin password of my office pc and i don’t know that .

1 Like

Hi @Tradehull_Imran,
I’m trying to implement the 2 candle strategy as per your video. However, I keep running into couple of errors. This is inspite of adhering to the rate limit and calling get_ltp with a gap of 60 secs between two calls.

Error list…

  1. 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’}}
    exception got in ce_pe_option_df ‘NIFTY’
  2. UnboundLocalError: cannot access local variable ‘strike’ where it is not associated with a value
  3. Message: 'Got exception in ce_pe_option_df ’
    Arguments: (KeyError(‘NIFTY’),)

I’m pasting the detailed code file and error file below. Kindly help

Code file

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,sys

warnings.filterwarnings("ignore")

path = r'C:/Users/krish/OneDrive/Documents/Krishna/2 Areas/Finance/Stock Market/Trading/Trading Courses/Development/AlgoTrading/Dhan/DhanAlgoTrading'
# path = r'../DhanAlgoTrading'
sys.path.insert(0, path)
import credentials as cred
from Dhan_Tradehull_V2 import Tradehull

# ---------------Basic setup for dhan login & Defining Constants------------------------
client_code = cred.CLIENT_ID
token_id = cred.ACCESS_TOKEN
tsl = Tradehull(client_code,token_id)

available_balance = tsl.get_balance()
# leveraged_margin  = available_balance*5
max_trades = 5
per_trade_margin = (available_balance/max_trades/5)
max_loss = -available_balance/100
EXPIRY ='26-12-2024'
LOT_SIZE = 3
VOLUME = 10000
# ---------------------------------------------------------------------------------------

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()
    month = datetime.datetime.now().strftime("%b").upper()
    
    if current_time < datetime.time(9, 30):
        print("Market yet to open", current_time)
        continue
    
    if (current_time > datetime.time(15, 15)) or (live_pnl < max_loss):
        order_details = tsl.cancel_all_orders()
        print("Market is closed!", current_time)
        break
    
    index_chart  = tsl.get_historical_data(tradingsymbol=f'NIFTY {month} FUT', exchange='NFO', timeframe="1")
    time.sleep(60)
    
    index_ltp    = tsl.get_ltp_data(names = [f'NIFTY {month} FUT'])[f'NIFTY {month} FUT']
    
    # if (index_chart.empty):
    #     time.sleep(60)
    #     continue
    if index_chart is None or index_ltp is None:
        print("Data unavailable. Retrying...")
        time.sleep(60)
        continue

	# rsi    ------------------------ apply indicators
    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'] = ta.vwap(index_chart['high'] , index_chart['low'], index_chart['close'] , index_chart['volume'])

	# Supertrend
    supertrend = ta.supertrend(index_chart['high'], index_chart['low'], index_chart['close'], 10, 2)
    index_chart = pd.concat([index_chart, supertrend], axis=1, join='inner')

	# vwma
    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]

    # print(index_chart)
    

	# ---------------------------- BUY ENTRY CONDITIONS ----------------------------
    buy_condition_1 = first_candle['close'] > first_candle['vwap']                # First Candle close is above VWAP
    buy_condition_2 = first_candle['close'] > first_candle['SUPERT_10_2.0']       # First Candle close is above Supertrend 
    buy_condition_3 = first_candle['close'] > first_candle['vwma']                # First Candle close is above VWMA
    buy_condition_4 = first_candle['rsi'] < 80                                    # First candle RSI < 80	
    buy_condition_5 = second_candle['volume'] > VOLUME                             # Second candle Volume should be greater than 50,000 for Nifty and above 125,000 for Bank Nifty
    buy_condition_6 = traded == "no"
    buy_condition_7 = index_ltp > first_candle['low']
    print(f"BUY \t {current_time} \t {buy_condition_1} \t {buy_condition_2} \t {buy_condition_3} \t {buy_condition_4} \t {buy_condition_5} \t {buy_condition_6} \t {buy_condition_7} \t first_candle {str(first_candle['timestamp'].time())}")


	# ---------------------------- SELL ENTRY CONDITIONS ----------------------------
    sell_condition_1 = first_candle['close'] < first_candle['vwap']                # First Candle close is below VWAP
    sell_condition_2 = first_candle['close'] < first_candle['SUPERT_10_2.0']       # First Candle close is below Supertrend 
    sell_condition_3 = first_candle['close'] < first_candle['vwma']                # First Candle close is below VWMA
    sell_condition_4 = first_candle['rsi'] > 20                                    # First candle RSI < 80	
    sell_condition_5 = second_candle['volume'] > VOLUME                             # Second candle Volume should be greater than 50,000 for Nifty and above 125,000 for Bank Nifty
    sell_condition_6 = traded == "no"
    sell_condition_7 = index_ltp < first_candle['high']
    print(f"SELL \t {current_time} \t {sell_condition_1} \t {sell_condition_2} \t {sell_condition_3} \t {sell_condition_4} \t {sell_condition_5} \t {buy_condition_7} \t {sell_condition_7} \t first_candle {str(first_candle['timestamp'].time())} \n")

    # pdb.set_trace()

    if buy_condition_1 and buy_condition_2 and buy_condition_3 and buy_condition_4 and buy_condition_5 and buy_condition_6 and buy_condition_7:
        print("Buy Signal Formed")  
        ce_name, pe_name, strike   = tsl.ATM_Strike_Selection(Underlying ='NIFTY',Expiry =EXPIRY)
        total_lots                 = tsl.get_lot_size(ce_name)*LOT_SIZE
        # call_buy_orderid           = tsl.order_placement(ce_name,'NFO', total_lots, 0, 0, 'MARKET', 'BUY', 'MIS')
        traded                     = "yes"
        trade_info['options_name'] = ce_name
        trade_info['qty']          = total_lots
        trade_info['buy_price']    = tsl.get_ltp_data(names = [ce_name])[ce_name]   #call_buy_orderid['price']
        trade_info['create_time']  = datetime.datetime.now()
        trade_info['sl']           = first_candle['low']
        trade_info['CE_PE']        = "CE"

    if sell_condition_1 and sell_condition_2 and sell_condition_3 and sell_condition_4 and sell_condition_5 and sell_condition_6 and sell_condition_7:
        print("Sell Signal Formed")
        ce_name, pe_name, strike   = tsl.ATM_Strike_Selection(Underlying ='NIFTY',Expiry =EXPIRY)
        total_lots                 = tsl.get_lot_size(pe_name)*LOT_SIZE
        # put_buy_orderid            = tsl.order_placement(pe_name,'NFO', total_lots, 0, 0, 'MARKET', 'BUY', 'MIS')
        traded                     = "yes"
        trade_info['options_name'] = pe_name
        trade_info['qty']          = total_lots
        trade_info['buy_price']    = tsl.get_ltp_data(names = [pe_name])[pe_name]
        trade_info['create_time']  = datetime.datetime.now()
        trade_info['sl']           = first_candle['high']
        trade_info['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:
            stop_loss_hit = index_ltp < trade_info['sl']
            target_hit = index_ltp < running_candle['SUPERT_10_2.0']

            if stop_loss_hit or target_hit:
                # call_exit_orderid        = tsl.order_placement(trade_info['options_name'],'NFO', trade_info['qty'], 0, 0, 'MARKET', 'SELL', 'MIS')
                if stop_loss_hit:
                    trade_info['exit_reason']   = 'SL Hit'
                else:
                    trade_info['exit_reason']   = 'Target Hit'
                trade_info['sell_price']   = tsl.get_ltp_data(names = [ce_name])[ce_name]
                trade_info['exit_time']  = datetime.datetime.now()
                print("Order Exited", trade_info)
                traded = "no"
                # pdb.set_trace()

        if short_position:
            stop_loss_hit = index_ltp > trade_info['sl']
            target_hit = index_ltp > running_candle['SUPERT_10_2.0']

            if stop_loss_hit or target_hit:
                # put_exit_orderid        = tsl.order_placement(trade_info['options_name'],'NFO', trade_info['qty'], 0, 0, 'MARKET', 'SELL', 'MIS')
                if stop_loss_hit:
                    trade_info['exit_reason']   = 'SL Hit'
                else:
                    trade_info['exit_reason']   = 'Target Hit'
                trade_info['sell_price']   = tsl.get_ltp_data(names = [pe_name])[pe_name]
                trade_info['exit_time']  = datetime.datetime.now()
                print("Order Exited", trade_info)
                traded = "no"
                # pdb.set_trace()


Error details

Sell Signal Formed
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'}}
exception got in ce_pe_option_df 'NIFTY'
Traceback (most recent call last):
  File "C:\Users/krish/OneDrive/Documents/Krishna/2 Areas/Finance/Stock Market/Trading/Trading Courses/Development/AlgoTrading/Dhan/DhanAlgoTrading\Dhan_Tradehull_V2.py", line 489, in ATM_Strike_Selection
    ltp = ltp_data[Underlying]
          ~~~~~~~~^^^^^^^^^^^^
KeyError: 'NIFTY'
--- Logging error ---
Traceback (most recent call last):
  File "C:\Users/krish/OneDrive/Documents/Krishna/2 Areas/Finance/Stock Market/Trading/Trading Courses/Development/AlgoTrading/Dhan/DhanAlgoTrading\Dhan_Tradehull_V2.py", line 489, in ATM_Strike_Selection
    ltp = ltp_data[Underlying]
          ~~~~~~~~^^^^^^^^^^^^
KeyError: 'NIFTY'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\Users\krish\anaconda3\Lib\logging\__init__.py", line 1110, in emit
    msg = self.format(record)
          ^^^^^^^^^^^^^^^^^^^
  File "c:\Users\krish\anaconda3\Lib\logging\__init__.py", line 953, in format
    return fmt.format(record)
           ^^^^^^^^^^^^^^^^^^
  File "c:\Users\krish\anaconda3\Lib\logging\__init__.py", line 687, in format
    record.message = record.getMessage()
                     ^^^^^^^^^^^^^^^^^^^
  File "c:\Users\krish\anaconda3\Lib\logging\__init__.py", line 377, in getMessage
    msg = msg % self.args
          ~~~~^~~~~~~~~~~
TypeError: not all arguments converted during string formatting
Call stack:
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel_launcher.py", line 17, in <module>
    app.launch_new_instance()
  File "c:\Users\krish\anaconda3\Lib\site-packages\traitlets\config\application.py", line 992, in launch_instance
    app.start()
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\kernelapp.py", line 701, in start
    self.io_loop.start()
  File "c:\Users\krish\anaconda3\Lib\site-packages\tornado\platform\asyncio.py", line 195, in start
    self.asyncio_loop.run_forever()
  File "c:\Users\krish\anaconda3\Lib\asyncio\windows_events.py", line 321, in run_forever
    super().run_forever()
  File "c:\Users\krish\anaconda3\Lib\asyncio\base_events.py", line 607, in run_forever
    self._run_once()
  File "c:\Users\krish\anaconda3\Lib\asyncio\base_events.py", line 1922, in _run_once
    handle._run()
  File "c:\Users\krish\anaconda3\Lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 534, in dispatch_queue
    await self.process_one()
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 523, in process_one
    await dispatch(*args)
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 429, in dispatch_shell
    await result
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 767, in execute_request
    reply_content = await reply_content
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\ipkernel.py", line 429, in do_execute
    res = shell.run_cell(
  File "C:\Users\krish\AppData\Local\Temp\ipykernel_30488\1990712033.py", line 29, in wrapper
    result = old_func(*args, **kwargs)
  File "c:\Users\krish\anaconda3\Lib\site-packages\ipykernel\zmqshell.py", line 549, in run_cell
    return super().run_cell(*args, **kwargs)
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3051, in run_cell
    result = self._run_cell(
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3106, in _run_cell
    result = runner(coro)
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\async_helpers.py", line 129, in _pseudo_sync_runner
    coro.send(None)
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3311, in run_cell_async
    has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3493, in run_ast_nodes
    if await self.run_code(code, result, async_=asy):
  File "c:\Users\krish\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3553, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-1-fd9addb455cf>", line 125, in <module>
    ce_name, pe_name, strike   = tsl.ATM_Strike_Selection(Underlying ='NIFTY',Expiry =EXPIRY)
  File "C:\Users/krish/OneDrive/Documents/Krishna/2 Areas/Finance/Stock Market/Trading/Trading Courses/Development/AlgoTrading/Dhan/DhanAlgoTrading\Dhan_Tradehull_V2.py", line 542, in ATM_Strike_Selection
    self.logger.exception("Got exception in ce_pe_option_df ", e)
Message: 'Got exception in ce_pe_option_df '
Arguments: (KeyError('NIFTY'),)

in running market i tested, its working,

in running market i tested sir its working, after market hours its not. thx

from NSE India… check step value for individual script
(https://nsearchives.nseindia.com/content/fo/NSE_FO_SosScheme.csv)

1 Like

Hi @kristrades99
Till how long did the algo run.

Hi @Tradehull_Imran, It ran for about 5-6 mins and then entered the ‘if condition’ once all the “sell conditions” were met. After this it threw up the error.

After market close order placement not working

May be this is stupid question but still asking …
Can we use get_historical_data() for live trading? I mean is historical data gives current trading candle for 1, 5 min timeframe?

Hi @kristrades99
I will check on this one,

Hi @vinay_kumaar @babji3

If the code is try to place MIS orders after market it wont be placed,
so, we need to send AMO order after market.

Hi @thakurmhn
Yes get_historical_data() can be used for live trading as well.

@RahulDeshpande @Tradehull_Imran Sir could you do one deep dive video on back testing & how we can save profit loss entry exit in excel( means it is part of Python but with your expertise we will get better logics and methodlogy).

It is much needed because before doing our algos live we will get assured about reliability and
will make fine tunning accordingly

D:\Deepak Personal\Algo trading program\3. Session3 - Codebase\3. Session3 - Codebase\3. Session3 - Codebase\Dhan codebase>py “Session 2.1.py”
-----Logged into Dhan-----
reading existing file all_instrument 2024-11-28.csv
Got the instrument file
intraday_minute_data() missing 2 required positional arguments: ‘from_date’ and ‘to_date’
Traceback (most recent call last):
File “D:\Deepak Personal\Algo trading program\3. Session3 - Codebase\3. Session3 - Codebase\3. Session3 - Codebase\Dhan codebase\Dhan_Tradehull.py”, line 253, in get_intraday_data
ohlc = self.Dhan.intraday_minute_data(str(security_id),exchangeSegment,instrument_type)
TypeError: intraday_minute_data() missing 2 required positional arguments: ‘from_date’ and ‘to_date’
Traceback (most recent call last):
File “Session 2.1.py”, line 18, in
chart[‘rsi’] = talib.RSI(chart[‘close’], timeperiod=14)
TypeError: ‘NoneType’ object is not subscriptable

Please help to resolve this error

Hi sir, i have one query , how to get first 15 minutes candle data? and can we place order in multiple stocks, please cover this topic in next videos.

1 Like

Hi @Tradehull_Imran

I am attemping hiustorical data…


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


client_code = "1102790337"
token_id    = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJkaGFuIiwicGFydG5lcklkIjoiIiwiZXhwIjoxNzM0ODUzNzY1LCJ0b2tlbkNvbnN1bWVyVHlwZSI6IlNFTEYiLCJ3ZWJob29rVXJsIjoiIiwiZGhhbkNsaWVudElkIjoiMTEwMjc5MDMzNyJ9.-sbgXkDN5Nm-bMFj3H2j1BdCQIZtTzbtV11ELQNxS7ncxAw98Ny6-3IZ_NC0rjXP7ECublc8LAiqqlRcW9s4pQ"
tsl = Tradehull(client_code,token_id)


data_day = tsl.get_historical_data(tradingsymbol = 'BANKNIFTY',exchange = 'INDEX',timeframe="DAY")
data_5 = tsl.get_historical_data(tradingsymbol = 'BANKNIFTY',exchange = 'IDK',timeframe="5")


options_data = tsl.get_historical_data(tradingsymbol = 'NIFTY 07 NOV 24000 CALL',exchange = 'NFO',timeframe="5")
options_data['ema30'] = talib.EMA(options_data['close'], timeperiod=30)


order_details = tsl.get_order_detail(orderid=102241105310027)
order_status  = tsl.get_order_status(orderid=102241105310027)
order_price   = tsl.get_executed_price(orderid=102241105310027)
order_time    = tsl.get_exchange_time(orderid=102241105310027)

error



Microsoft Windows [Version 10.0.22631.4460]
(c) Microsoft Corporation. All rights reserved.

C:\Users\imran\Desktop\Dhan Lecture Sessions\Forum Support\Forum Support\20. Kalpesh>py "2. Good Historical Data.py"
Codebase Version 2.2
-----Logged into Dhan-----
This BOT Is Picking New File From Dhan
Got the instrument file
Exception in Getting OHLC data as {'status': 'failure', 'remarks': {'error_code': 'DH-906', 'error_type': 'Order_Error', 'error_message': 'Invalid Token'}, 'data': {'errorType': 'Order_Error', 'errorCode': 'DH-906', 'errorMessage': 'Invalid Token'}}
Exception in Getting OHLC data as 'IDK'
Exception in Getting OHLC data as single positional indexer is out-of-bounds
Traceback (most recent call last):
  File "2. Good Historical Data.py", line 21, in <module>
    options_data['ema30'] = talib.EMA(options_data['close'], timeperiod=30)
TypeError: 'NoneType' object is not subscriptable

C:\Users\imran\Desktop\Dhan Lecture Sessions\Forum Support\Forum Support\20. Kalpesh>


Your Index name is wrong
Put the correct index

1 Like

@Tradehull_Imran Sir thanks for yesterday but today i am struck can you explain …why some times only the call order is placed and some other time put order …why? please help .

Hi @vejey_deepak

The codebase file is upgraded now for Historical data
do check this video for upgrade : https://www.youtube.com/watch?v=HLiEpNZSD80

Hi @Hitesh_Maurya

I am bit unclear on the question need more detail regarding it
also do send your code file on forum/google drive link/pastebin