Learn Algo Trading with Python | Codes | Youtube Series

Sir please see this code …
Correct or not

If any correction then plz correct it

import yfinance as yf
import datetime

def scan_stocks(tickers):
today = datetime.date.today()
results =

for ticker in tickers:
    try:
        stock = yf.Ticker(ticker)
        hist = stock.history(period="1mo", interval="1d")

        # Check for breakout
        for i in range(1, 8):
            if hist.iloc[-i]['High'] <= hist.iloc[-i-1]['High']:
                break
            if hist.iloc[-i]['Low'] <= hist.iloc[-i-1]['Low']:
                break
        else:
            # Check for uptrend
            if hist.iloc[-1]['Close'] > hist.iloc[-1]['Open']:
                if hist.iloc[-5]['Close'] > hist.iloc[-5]['Open']:
                    if hist.iloc[-22]['Close'] > hist.iloc[-22]['Open']:
                        # Check for volume
                        if hist.iloc[-1]['Volume'] > 10000 and hist.iloc[-1]['Volume'] > hist.iloc[-2]['Volume'] * 1.25:
                            # Check for moving averages
                            if hist.iloc[-20:].Close.mean() > hist.iloc[-40:].Close.mean() > hist.iloc[-60:].Close.mean():
                                results.append(ticker)

    except Exception as e:
        print(f"Error fetching data for {ticker}: {e}")

return results

Example usage with a list of tickers

tickers = [“AAPL”, “GOOGL”, “MSFT”, “AMZN”, “TSLA”] # Replace with your desired tickers
results = scan_stocks(tickers)

print(results)

@Tradehull_Imran mujhe kisi perticular ltp ke increase hone ke bad trade lena hai for example mene 50 ka ltp select Kiya ab me chahta hu ki ye 100% increase ho mean 100 pr jaye tabhi trade le to iska function Janna hai

1 Like

@Tradehull_Imran, @RahulDeshpande - Below are the things i would like to implement through Algo

  1. Backtesting module
  2. Forward testing module
  3. One complete option selling strategy with adjustments (preferably short iron condor)
    Kindly incorporate these in your next video
3 Likes

Hello @Tradehull_Imran sir,
I have written this code and would really appreciate it if you could review it.
I am a little dicey about the MODIFY ORDER function call.

Looking forward to your response suggesting the exact changes needed.
Best Regards

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 = “1100578034”
token_id = “SET UR API”
tsl = Tradehull(client_code,token_id)

Trading parameters

options_name = “NIFTY 28 NOV 24300 PUT”
qty_lots = 25 # Lot size
target_points = 35 # Target in points
sl_points = 25 # Stop-loss in points
limit_price_order = 171 #higher than trigger
trigger_price_order = 170.6 #lower than limit
order_type = “STOPLIMIT”

Get current LTP (Last Traded Price)

fno_ltp = tsl.get_ltp_data(options_name)

traded = “no”
trade_info = {“options_name”: None, “qty”: None, “sl”: None}

max_orders = 1
counter = 0

while True:
counter += 1
try:
# Get current time
current_time = datetime.datetime.now()

    # Fetch historical data
    fno_chart = tsl.get_historical_data(tradingsymbol=options_name, exchange="NFO", timeframe="1" )
    time.sleep(3)

    # Get current LTP (Last Traded Price)
    fno_ltp = tsl.get_ltp_data(options_name) 
    
    # Handle missing data
    if fno_chart is None or fno_ltp is None:
        print("Data unavailable. Retrying...")
        time.sleep(60)
        continue

    # Place a trade if no trade is active
    if traded == "no":
        # Place a Buy Order
        buy_entry_orderid = tsl.order_placement(options_name, "NFO", qty_lots, limit_price_order, trigger_price_order,order_type,"BUY", "MIS")
        print("BUY ORDER EXECUTED")
        traded = "yes"
        if counter >= max_orders:
            break 


        # Get executed price
        #order_price_response = tsl.get_executed_price(orderid=buy_entry_orderid)
        #pprint(order_price_response)

        #executed_price = order_price_response ("executed_price", 0)
        #executed_price = data.get('price', 0.0)
        executed_price = tsl.get_executed_price(orderid=buy_entry_orderid)
        if executed_price == 0:
            print("Error fetching executed price. Skipping trade.")
            traded = "no"
            continue

        # Place Stop-Loss Order Immediately
        sl_price_trigger = executed_price - sl_points
        sl_price_limit = sl_price_trigger - 1
        tsl.order_placement(options_name,"NFO", qty_lots, sl_price_limit, sl_price_trigger, "STOPLIMIT",  "SELL", "MIS",)
        print("SL Order Placed Immediately.")

    # Monitor for Target Exit
    if traded == "yes":
        tg_hit = fno_ltp > round((executed_price + target_points), 1)
        if tg_hit:
            print("Target Hit. Exiting Trade.")
            tsl.modify_order(appOrderID=buy_entry_orderid ,modifiedOrderType='MARKET', modifiedOrderQuantity=qty_lots, modifiedLimitPrice=0, modifiedStopPrice=0, trade_type='MIS')
            
            traded = "no"
            print("Exited Trade at Target.")
            pdb.set_trace()  # Debugging

except Exception as e:
    print(f"Error occurred: {e}")
    traceback.print_exc()
    time.sleep(60)

Hi
@Tradehull_Imran @RahulDeshpande
I want to learn

  1. How to apply multi option stratagy with multi index in a single algo
  2. How to split over positions and book partial profit and remaining position with trailing SL
  3. How to use any common database/pickle/HDF5 for two strategy and send our data frame to it for both algo strategy can read from the same source.

Please provide lectures for learning topics
Thank you

3 Likes

Hi @Qaisar

WebSocket is a old method which we used to call for LTP, now we have a easier method for it.

since you are starting out on the series do study in below sequence.

1 Like

Hi @Samis
Orders cannot be squared-off based on orderid
however order can be cancelled its in OPEN/TRIGGER PENDING based on orderid.

to square off the position you need to send the reverse transaction type order

Hi @Himansshu_Joshi

use below code for order modification

orderid = '12465466576'
tsl.Dhan.modify_order(order_id = orderid, order_type='LIMIT', leg_name='', quantity=40, price=23.50, trigger_price=0, disclosed_quantity=0, validity='DAY')

also make changes here

        # Handle missing data
        if index_chart.empty  or fno_ltp is None:
            print("Data unavailable. Retrying...")
            time.sleep(60)
            continue

Hi @Md_Naquibuddin,

Yes the code seems to be correct on a high level,
also send the error if you face any.

Hi @Kishore007

use below code

First check Target and Stoploss status then cancel the other order 

sl_status = tsl.get_order_status(ordered =sl_orderid )
if sl_status == 'TRADED':
      tsl.Dhan.cancel_order(order_id=tp_orderid )
      traded_wathclist.remove(stock_name)

tg_status = tsl.get_order_status(ordered =tp_orderid )
if tg_status == 'TRADED':
      tsl.Dhan.cancel_order(order_id=sl_orderid )
      traded_wathclist.remove(stock_name)
1 Like

Hi @Aijaz_Ahmad

use below code for Cover Orders - Market

tradingsymbol = 'YESBANK'
exchange = tsl.Dhan.NSE
security_id = tsl.instrument_df[((tsl.instrument_df['SEM_TRADING_SYMBOL']==tradingsymbol)|(tsl.instrument_df['SEM_CUSTOM_SYMBOL']==tradingsymbol))&(tsl.instrument_df['SEM_EXM_EXCH_ID']=='NSE')].iloc[-1]['SEM_SMST_SECURITY_ID']
tsl.Dhan.place_order(security_id=int(security_id), exchange_segment=exchange, transaction_type='BUY', quantity=1,order_type='MARKET', product_type='CO', price=0, trigger_price=19.54, disclosed_quantity=0, after_market_order=False, validity='DAY', amo_time='OPEN',bo_profit_value=0, bo_stop_loss_Value=0, tag=None)

use below code for Cover Orders - Limit

tradingsymbol = 'YESBANK'
exchange = tsl.Dhan.NSE
security_id = tsl.instrument_df[((tsl.instrument_df['SEM_TRADING_SYMBOL']==tradingsymbol)|(tsl.instrument_df['SEM_CUSTOM_SYMBOL']==tradingsymbol))&(tsl.instrument_df['SEM_EXM_EXCH_ID']=='NSE')].iloc[-1]['SEM_SMST_SECURITY_ID']
tsl.Dhan.place_order(security_id=int(security_id), exchange_segment=exchange, transaction_type='BUY', quantity=1,order_type='LIMIT', product_type='CO', price=20.14, trigger_price=19.54, disclosed_quantity=0, after_market_order=False, validity='DAY', amo_time='OPEN',bo_profit_value=0, bo_stop_loss_Value=0, tag=None)

Thanks for the reply, i am following the seqeunce but stuck with the errors, shall I take code files from session 4 to practice?

Hi @Qaisar
yes you can start with session 4 files.

1 Like

thanks you for the support…
will try with the reverse transaction of SELL , to square off the BUY position, hope it will not create a new short position…

1 Like

Hi @Tradehull_Imran,

Thanks for sharing the CO code, but instead of using BO or CO I used the method you suggested i.e. once the stock was bought, immediately placed SL order and tracked price of the stock once target was reached, immediately canceled the SL order and placed the sell order, though I am using time.sleep(0.5) for continously checking the price. Never thought I would be able to complete my first algo. Thanks for all the help you have given, without it, completing my first algo wouldn’t have been possible.

1 Like

@Tradehull_Imran , I’m getting this error on this line
atm_ce_ltp = tsl.get_ltp_data(names = [atm_ce_name])[atm_ce_name]

…can you pls check and advise…below is the 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 514, in ATM_Strike_Selection
closest_index = ce_df[‘diff’].idxmin()
^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\series.py”, line 2561, in idxmin
i = self.argmin(axis, skipna, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\base.py”, line 785, in argmin
result = nanops.nanargmin(delegate, skipna=skipna)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\nanops.py”, line 1188, in nanargmin
result = values.argmin(axis) # type: ignore[var-annotated]
^^^^^^^^^^^^^^^^^^^
ValueError: attempt to get argmin of an empty sequence

Hi @kristrades99
Do send complete code as well for
main file
Dhan_Tradehull_V2
and the complete error

Do remove any confidential strategy information there and api keys.

also see for correct code format: Learn Algo Trading with Python | Codes | Youtube Series - #368 by Tradehull_Imran

Thanks for your kind words.

More thoughtful and helpful content is on the way.

Hello @Tradehull_Imran

Sir, how can we apply Supertrend indicator in our algo
Thanks

Hi @Tradehull_Imran, Sharing the code of main file and error received below. Unable to attach Dhan_Tradehull_v2 as its crossing the word limit allowed in this forum

-----main file-----

import pdb
import pandas as pd
import talib
import time
import datetime
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'
sys.path.insert(0, path)
import credentials as cred
from Dhan_Tradehull_V2 import Tradehull
import PreMarketScanner as pms

# ---------------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 ='28-11-2024'
LOT_SIZE = 1
# ---------------------------------------------------------------------------------------


trade_info = pms.premarketscan()
traded_watchlist = []
trade_dict = {}

while True:

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

	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):
		# I_want_to_trade_no_more = tsl.kill_switch('ON')   # removed Kill swtich as it may get accidenyl hit while Testing and block all future order placement
		order_details = tsl.cancel_all_orders()
		print("Market is closed!", current_time)
		break

	for idx,row in trade_info.iterrows():
		time.sleep(0.2)
		print(f"Scanning {row['script']}")

		chart_5            		= tsl.get_historical_data(tradingsymbol = row['script'], exchange = 'NSE',timeframe="5")       # Upgraded 5 minute chart according to Dhan_Tradehull_V2
		cc_5               		= chart_5.iloc[-1]   # pandas
		cc_volume      			= cc_5['volume']
		average_volume 			= chart_5['volume'].mean()
		no_repeat_order    		= row['script'] not in traded_watchlist
		atm_ce_name, atm_pe_name, strike = tsl.ATM_Strike_Selection(row['script'],EXPIRY)  #atm_ce_name, pe_strike, ce_OTM_price, pe_OTM_price = tsl.OTM_Strike_Selection(stock_name,'08-08-2024',3)
  
		if (idx == "buy") and no_repeat_order: #trade_info['Direction']
			breakout_c1    		= cc_5['close'] > row['level']
			breakout_c2    		= cc_volume > 2*average_volume
			breakout_c3    		= cc_5['open'] != cc_5['close']

			atm_ce_ltp     		= tsl.get_ltp_data(names = [atm_ce_name])[atm_ce_name]
			lot_size       		= tsl.get_lot_size(atm_ce_name)
			
			ce_entry_price    	= round((atm_ce_ltp*1.02),1)
			ce_sl_price       	= round((atm_ce_ltp*0.8),1)
			
			trade_dict['stock_name']  = row['script']
			trade_dict['direction'] = 'buy'
			trade_dict['expiry']    = EXPIRY
			trade_dict['option']    = 'ce'
			trade_dict['lot_size']    = lot_size
			trade_dict['buy_price']   = ce_entry_price
			trade_dict['sl_price']    = ce_sl_price
			trade_dict['sell_price']  = 0	
			traded_watchlist.append(row['script'])

		elif (idx == "sell") and no_repeat_order: #trade_info['Direction']
			breakout_c1    		= cc_5['close'] < row['level']
			breakout_c2    		= cc_volume > 2*average_volume
			breakout_c3    		= cc_5['open'] != cc_5['close']

			atm_pe_ltp     		= tsl.get_ltp_data(names = [atm_pe_name])[atm_pe_name]
			lot_size       		= tsl.get_lot_size(atm_pe_name)
			
			pe_entry_price    	= round((atm_pe_ltp*0.98),1)
			pe_sl_price       	= round((atm_pe_ltp*1.2),1)
			
			trade_dict['stock_name']  = row['script']
			trade_dict['direction'] = 'buy'
			trade_dict['expiry']    = EXPIRY
			trade_dict['option']    = 'pe'
			trade_dict['lot_size']    = lot_size
			trade_dict['buy_price']   = pe_entry_price
			trade_dict['sl_price']    = pe_sl_price
			trade_dict['sell_price']  = 0	
			traded_watchlist.append(row['script'])```

----Error details -----------------

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 514, in ATM_Strike_Selection
closest_index = ce_df[‘diff’].idxmin()
^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\series.py”, line 2561, in idxmin
i = self.argmin(axis, skipna, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\base.py”, line 785, in argmin
result = nanops.nanargmin(delegate, skipna=skipna)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\nanops.py”, line 1188, in nanargmin
result = values.argmin(axis) # type: ignore[var-annotated]
^^^^^^^^^^^^^^^^^^^
ValueError: attempt to get argmin of an empty sequence
— 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 514, in ATM_Strike_Selection
closest_index = ce_df[‘diff’].idxmin()
^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\series.py”, line 2561, in idxmin
i = self.argmin(axis, skipna, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\base.py”, line 785, in argmin
result = nanops.nanargmin(delegate, skipna=skipna)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “c:\Users\krish\anaconda3\Lib\site-packages\pandas\core\nanops.py”, line 1188, in nanargmin
result = values.argmin(axis) # type: ignore[var-annotated]
^^^^^^^^^^^^^^^^^^^
ValueError: attempt to get argmin of an empty sequence

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 “”, line 198, in _run_module_as_main
File “”, line 88, in _run_code
File “c:\Users\krish\anaconda3\Lib\site-packages\ipykernel_launcher.py”, line 17, in
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_30692\1532818857.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 “”, line 64, in
atm_ce_name, atm_pe_name, strike = tsl.ATM_Strike_Selection(row[‘script’],EXPIRY) #atm_ce_name, pe_strike, ce_OTM_price, pe_OTM_price = tsl.OTM_Strike_Selection(stock_name,‘08-08-2024’,3)
File “C:\Users/krish/OneDrive/Documents/Krishna/2 Areas/Finance/Stock Market/Trading/Trading Courses/Development/AlgoTrading/Dhan/DhanAlgoTrading\Dhan_Tradehull_V2.py”, line 541, in ATM_Strike_Selection
self.logger.exception("Got exception in ce_pe_option_df ", e)
Message: 'Got exception in ce_pe_option_df ’
Arguments: (ValueError(‘attempt to get argmin of an empty sequence’),)