By Sunil Guglani (Assistant V.P. at NCDEX)

Are you new to Algo trading? Confused about how to set off, where to originate?

There are stacks of courses and placid available on backtesting, bailiwick indicators, Python for finance on the web.

Also, there is a good amount of stuff available on the benefits of Algo trading complete non-automatic trading. Merely if you lack to uprise your opening algo, what are the stages you have to go through, in that location is limited info connected this.

Take note: These stages are purely based on my experience, it may/may not take issue from standard procedures (which I could not find ☺).

Python Basics Handbook

I will try to explain this by pickings a real trading strategy. Here are the stages I volition hide:

  • Formulate the Trading Conception/Logical system
  • Filtering criteria to choose the scripts
  • Verification of Logic (at High Level)
  • Backtesting
  • Optimisation of Parameters
  • Paper Trading or Forward Testing surgery Simulation Trading in the real environment
  • Deployment in the real environment

Articulate the Trading Concept/Logic

Premiere matter first, algo trading is non - rocket engine scientific discipline..yes.. it is truly not…IT is exactly a puzzle, which you need to solve more effectively, efficiently than a couple of other people. And we know the bewilder..Buy at broken and betray at high.

Not necessary to follow whatsoever existing hypothesis or indicators Oregon strategy. You don't need to be a market expert. You can make your possess if you are comfortable. (my first off algo was an arbitrage across the exchange. I was an amateur and I didn't even make out the meaning of arbitrage at that meter. ☺)

You penury to resolve following in that stage:

  1. What leave be my logic to achieve my goal(Shop at Low and Sell at Higher)?
  2. What wish be the frequency of my trades?
  3. Which segment testament it work well-nig effectively(Equity/Commodity/FX/Crypto..)
  4. How much should be backtesting period?
  5. Which automation tools/languages wish be most reusable for this system of logic?

Example: I think FMCG (Fast moving consumer goods) stocks are generally less volatile in nature and they revolve around the same price range. IT makes me cogitate that they are range bound and so they are mean returning. Therefore I will try to give few mean reversion technique in my strategy. Also, intraday prices are extremely explosive therefore I will prefer each day closedown prices for calculation and trade.

Considering my preceding idea, my answers to the following are :

What will be my logic to achieve my goal (Buy at Low and Sell at Overlooking)?

I testament be using mean retrogression trading strategy. For this, I will use Bollinger band. Buy: if Close price goes below -2 standard deviation from the mean.dannbsp;square up position: if Adjacent price goes above +2 standard deviation from the mean.

What wish be the frequency of my trades?

Day-after-day.

Which segment will it work most effectively (Fairness, Trade good, FX or Crypto)?

I will use the fairness cash in section.

How much should equal backtesting period?

3 years (longer the better).

Which mechanization tools/languages will be almost profitable for this logic?

I am comfortable with Python. We should consumption the tools where we are about well-to-do with.

Filtering criteria to choose the scripts

Great. You have achieved a big milestone. You have penned down the core system of logic and did high level planning for your algo.

If you observe, your logic will work best along some specific conditions and ad hoc scripts. Remember you have already decided the segment in first stage.

The selection/filtration of scripts can be done before or during the trading hours (concrete-clock time). It all depends connected your core logic.

Example:

As we have decided, we volition use FMCG scripts and high liquid stocks exclusive, therefore filtering criteria to live used as follows: a. Industry(FMCG). b. Volumedangt;100000

Substantiation of Logic (at High Degree)

Algo development is an pricy process, it requires a lot of effort and time. It is improve to assert your Core logic at High level using a Visualization tool or excel.

It will save a lot of time later. You can use Tableau, power BI or just excel to write the logic and verify your logics. You can too use charting tools like trading perspective, investing.com or something similar.

It is a 5 year graph of ITC Ltd along daily frequency. And SMA, STD(-2,+2) is applied on the 20 years lookback time period. (Good manners: tradingview.com ). The visual below gives us confirmation roughly our logic.

Backtesting

Backtesting is the way of verification of your logic victimisation historical Mary Leontyne Pric information. This stagecoach helps in understanding how well the logic would sustain worked if you used this in the past. This stage gives an indication about the execution of your system of logic. It besides gives you the chance to optimize the logic and its parameters.

One should count the following parameters in this microscope stage:

Various performance parameters

  • Returns
  • Easy lay drawdown
  • Max continuous drawdown
  • Easy lay profit
  • Max continuous profit
  • Number of transactions
  • Average returns per dealings
  • Transaction charges
  • Slippages,etc.

Few many points to focus are:

  • Stop going/Trailing stop loss
  • Target price
  • Entry Criteria
  • Exit criteria

A identical rough-cut slip up algo traders set is using the present-day price information in generating the trading signals. We should forever exercise historical data in our logic and side by side price data for buy and sell signals.

Activities to execute are:

We deman to execute the shadowing activities in this stage:

  1. Import the necessary libraries
  2. Fetch the historical OHLC data for an musical instrument.
  3. Write the supporting functions to achieve our logic
  4. Generate the buy/sell signals using candlesticks
  5. Visualize the yield
  6. Checking returns of the scheme

Analysis and visualisation of backtesting output signal data to understand the scope of optimization in your algorithm.

Note: To critical review steps old in backtesting delight name to my clause

https://metier.com/@sunil.guglani/how-to-develop-your-initial-trading-bot-using-python-by-recognising-candlestick-patterns-a755f7fa6674

Representative:

Import the indispensable libraries

importee pandas as pd import numpy as np from nsepy import get_history import datetime import seaborn Eastern Samoa sns import matplotlib.pyplot as plt import plotly import plotly.graph_objs as go away from plotly.offline import download_plotlyjs, init_notebook_mode, plat, iplot                ------------------------------------------------------                ''' Function to fetch data from nsepy ''' def Fetch_Historical_Data_nsepy(script,script_cat,fromdate,todate,fashion):     if mode=='nsepy':         if (script_cat=='NSE_EQ')|(script_cat=='BSE_EQ'):             try:                 df_stock_data = get_history(symbolic representation=script,                                      start=fromdate,                                      stop=todate)                          except (RuntimeError,ConnectionError):                 print ("Fetch_Historical_Data function, nsepy function: ",RuntimeError)                 df_stock_data = get_history(symbolisation=script,                                      start=fromdate,                                      end=todate)             recurrence df_stock_data                      elif script_cat=='NSE_INDEX':             try:                 df_index_data = get_history(symbol=script,                                      start=fromdate,                                      end=todate,                 					index=True)                          exclude (RuntimeError,ConnectionError):                 print ("Fetch_Historical_Data function, nsepy function: ",RuntimeError)                 df_index_data = get_history(symbol=script,                                      start=fromdate,                                      end=todate,                 					exponent=True)             return df_index_data  ''' Function to fetch data for the algorithmic rule  '''  def fetch_data(script) :     todate=datetime.datetime.now().date()     fromdate=todate-datetime.timedelta(days=365*4)     script_cat='NSE_EQ'     script=hand      style='nsepy'     df=Fetch_Historical_Data_nsepy(script,script_cat,fromdate,todate,mode)     return df  ------------------------------------------------------  ''' Function to fetch information from nsepy ''' def Fetch_Historical_Data_nsepy(playscript,script_cat,fromdate,todate,mode):     if mode=='nsepy':         if (script_cat=='NSE_EQ')|(script_cat=='BSE_EQ'):             try:                 df_stock_data = get_history(symbol=script,                                      start=fromdate,                                      oddment=todate)                          demur (RuntimeError,ConnectionError):                 print ("Fetch_Historical_Data function, nsepy function: ",RuntimeError)                 df_stock_data = get_history(symbolisation=script,                                      protrude=fromdate,                                      end=todate)             return df_stock_data                      elif script_cat=='NSE_INDEX':             try:                 df_index_data = get_history(symbol=script,                                      start=fromdate,                                      end=todate,                 					indicator=True)                          except (RuntimeError,ConnectionError):                 print ("Fetch_Historical_Data operate, nsepy function: ",RuntimeError)                 df_index_data = get_history(symbol=script,                                      offse=fromdate,                                      end=todate,                 					index finger=True)             return df_index_data  ''' Function to get data for the algorithm  '''  def fetch_data(script) :     todate=datetime.datetime.immediately().date()     fromdate=todate-datetime.timedelta(days=365*4)     script_cat='NSE_EQ'     script=script      mode='nsepy'     df=Fetch_Historical_Data_nsepy(script,script_cat,fromdate,todate,mode)     return df

Fetch the historical OHLC information for an instrument.

''' Part to fetch information from nsepy ''' def Fetch_Historical_Data_nsepy(playscript,script_cat,fromdate,todate,mode):     if musical mode=='nsepy':         if (script_cat=='NSE_EQ')|(script_cat=='BSE_EQ'):             try:                 df_stock_data = get_history(symbol=script,                                      start=fromdate,                                      end=todate)                          except (RuntimeError,ConnectionError):                 print ("Fetch_Historical_Data function, nsepy function: ",RuntimeError)                 df_stock_data = get_history(symbol=script,                                      start=fromdate,                                      oddment=todate)             riposte df_stock_data                      elif script_cat=='NSE_INDEX':             try:                 df_index_data = get_history(symbol=book,                                      start=fromdate,                                      terminate=todate,                 					index=True)                          except (RuntimeError,ConnectionError):                 publish ("Fetch_Historical_Data function, nsepy function: ",RuntimeError)                 df_index_data = get_history(symbolic representation=script,                                      start=fromdate,                                      end=todate,                 					index=True)             return df_index_data  ''' Officiate to fetch information for the algorithmic program  '''  def fetch_data(script) :     todate=datetime.datetime.now().date stamp()     fromdate=todate-datetime.timedelta(days=365*4)     script_cat='NSE_EQ'     playscript=script      mode='nsepy'     df=Fetch_Historical_Data_nsepy(script,script_cat,fromdate,todate,mode)     return df              

Write the supporting functions to achieve our logic

''' # Part to backtest whatever strategy by using parameter              #Dataframe,      #strategy_type(mindful/short),entry_criteria,exit_criteria     #positional_field ,price_field(example Close cost),stoploss_pct(block off expiration pct),target_pct,only_profit(should hold back for craft to be in profit Real/False) ''' def backtest_strategy_stoploss(df, strategy_type,lst_entry_criteria,lst_exit_criteria, positional_field,price_field,stoploss_pct,target_pct,only_profit):     df['buy_price']=0.0000     df['sell_price']=0.0000        df['buy_time']=None     df['sell_time']=None     exit_reason_field=positional_field+'_exit_flag'     df[positional_field]=0     df[exit_reason_field]=''     pos=0      last_buy_price=0.00     last_sell_price=0.00          for d in browse(0,len(df)):         entry_flag=lst_entry_criteria[d]         exit_flag=lst_exit_criteria[d]         curr_price=df[price_field].iloc[d]         curr_time=df.index[d]         stoploss_exit=False         target_exit=False         only_profit_exit=Dishonorable         exit_reason=''                  if stoploss_pct!=0:             if (strategy_type=='long')danamp;(last_buy_pricedangt;0):                 if ((curr_price-last_buy_price)*100/last_buy_price)0):                     if ((last_sell_price-curr_price)*100/curr_price)0):                 if ((curr_price-last_buy_price)*100/last_buy_price)dangt;target_pct:                     target_exit=True                     exit_reason='TRM'             elif (strategy_type=='short')danamp;(last_sell_pricedangt;0):                     if ((last_sell_price-curr_price)*100/curr_price)dangt;target_pct:                     target_exit=On-key                     exit_reason='TRM'          if only_profit==True:             if (strategy_type=='long')danamp;(last_buy_pricedangt;0):                 if ((curr_price-last_buy_price)*100/last_buy_price)dangt;0:                     only_profit_exit=True             elif (strategy_type=='short')danadenosine monophosphate;(last_sell_pricedangt;0):                     if ((last_sell_price-curr_price)*100/curr_price)dangt;0:                     only_profit_exit=True         else:             only_profit_exit=True          if exit_flag:             exit_reason='Electronic countermeasures'                      if entry_flagdanamp;(pos==0) :              if strategy_type=='long':                 df['buy_price'].iat[d]= df[price_field].iloc[d]                 last_buy_price=df[price_field].iloc[d]                 df[positional_field].iat[d]=1              elif strategy_type=='short':                 df['sell_price'].iat[d]= df[price_field].iloc[d]                 last_sell_price=df[price_field].iloc[d]                 df[positional_field].iat[d]=-1              pos=1         elif (exit_flag|stoploss_exit|target_exit)danamp; only_profit_exit danamp; (pos==1) :              df[exit_reason_field].iat[d]=exit_reason                            if strategy_type=='long':                 df['sell_price'].iat[d]= df[price_field].iloc[d]                 last_sell_price=df[price_field].iloc[d]                 df[positional_field].iat[d]=-1              elif strategy_type=='short':                 df['buy_price'].iat[d]= df[price_field].iloc[d]                 last_buy_price=df[price_field].iloc[d]                 df[positional_field].iat[d]=1              pos=0      df_temp=df[df[positional_field]!=0].copy()          df_temp['buy_time']=df_temp.index     df_temp['sell_time']=df_temp.index      df_buy=df_temp[df_temp.buy_pricedangt;0][['buy_price','buy_time']]     df_buy.reset_index(drop=True up,inplace=Literal)          df_sell=df_temp[df_temp.sell_pricedangt;0][['sell_price','sell_time']]     df_sell.reset_index(drop=Rightful,inplace=True)          long= pd.concat([df_buy,df_sell],axis=1,copy=True)          if len(long)dangt;0:         if ~(long['sell_price'].iloc[-1]dangt;0):             drawn-out['sell_price'].iat[-1]=curr_price             long['sell_time'].iat[-1]=curr_time                       long["returns"]=(long-snouted["sell_price"]-long["buy_price"])*100/long["buy_price"]     long['cum_returns']=(long['sell_price']/long['buy_price']).cumprod()     aware['investment_period']=(long['sell_time']-long['buy_time'])      short= pd.concat([df_buy,df_sell],bloc=1,copy=Truthful)          if len(short)dangt;0:         if ~(discourteous['buy_price'].iloc[-1]dangt;0):             short['buy_price'].iat[-1]=curr_price             short['buy_time'].iat[-1]=curr_time                  short["returns"]=(short["sell_price"]-short["buy_price"])*100/short["buy_price"]     short['cum_returns']=(short['sell_price']/short['buy_price']).cumprod()     truncate['investment_period']=(short['buy_time']-half-length['sell_time'])          if strategy_type=='long':         return df,long     else:         return df,short  ''' # Function to generate backtest reports ''' def backtest_reports_local(df_summary,lot_size,trx_charge):     #black and white("investing period", df_summary['investment_period'].sum())     #print("number of transactions", df_summary['investment_period'].count())     publish("Sum of returns in %", df_summary['returns'].tot())     print("Average returns per transaction in %", df_summary['returns'].mean())     print("Absolute returns", df_summary['returns_abs'].sum())     print("Absolute returns per trx", df_summary['returns_abs'].sum()/df_summary['returns_abs'].weigh())     black and white("Max drawdown for a trx", df_summary[df_summary.returns_absdanlt;0]['returns_abs'].min())     print("Max returns for a trx", df_summary[df_summary.returns_absdangt;0]['returns_abs'].max())     print("Losing trx", df_summary[df_summary.returns_absdanlt;0]['returns_abs'].consider())     black and white("Winning trx", df_summary[df_summary.returns_absdangt;0]['returns_abs'].bet())     publish("Win/Lose ratio ", (df_summary[df_summary.returns_absdangt;0]['returns_abs'].matter to())/(df_summary[df_summary.returns_absdanlt;0]['returns_abs'].count()))      df_summary.index=df_summary.buy_time     df_summary['returns2']=atomic number 93.round((np.int64(df_summary['returns']/.5))*.5,0)          g1=df_summary[['returns2']].cumsum().plot(figsize=(12,8))     #fig.autofmt_xdate()     #ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')          plt.tight_layout()      plt.establish(g1)          g2=df_summary[['returns_abs']].cumsum().diagram(figsize=(12,8))          plt.tight_layout()          plt.show(g2)         '''         df_summary['investment_period2']=(np.int64(df_summary['investment_period']))          plt.title("Investment period vs Count of transactions")      g2=sns.countplot(x="investment_period2",     information=df_summary)     plt.show(g2)          #print ('Tot returns', df_summary[['returns_abs']].cumsum())     '''     plt.title("Percentage Returns vs Count of transactions")          g3=sns.countplot(x="returns2",      data=df_summary)          plt.evince(g3)

Collecting everything

''' main Function  '''  def bb_backtest_positional(script,lot_size,trx_charges,slippages):      summary_min_grand=pd.DataFrame()     df=fetch_data(handwriting)              draw_cndl_chart(df)      for strat_type in ['drawn-out']:         df_temp=df.re-create()         price_field='Close'                  strategy_type=strat_type         df_temp,boll_entry,boll_exit=bb(df_temp,price_field,strategy_type)          if strategy_type=='long':             final_entry=boll_entry             final_exit=boll_exit         elif strategy_type=='short':                 final_entry=boll_entry             final_exit=boll_exit                  positional_field='pos_bb'         price_field='Close'         stoploss_pct=0         target_pct=200         only_profit=True                  df_temp,summary_min=backtest_strategy_stoploss(df_temp, strategy_type,list(final_entry),list(final_exit), positional_field,price_field,stoploss_pct,target_pct,only_profit)                  summary_min['returns_abs']=(summary_min['sell_price']-summary_min['buy_price'])*lot_size         summary_min['returns_abs']=summary_min['returns_abs']-trx_charges         summary_min['strat_type']=strat_type                  summary_min_grand=summary_min_grand.append(summary_min)     return summary_min_grand              

Output is as follows:

Candlestick chart

**************BACKTEST RESULTS OF : ITC ************************

Sum of returns in % 12.582204198954024
Average returns per dealing in % 1.7974577427077176
Absolute returns 39.50000000000003
Absolute returns per trx 5.642857142857147
Max drawdown for a trx -36.30000000000001
Max returns for a trx 34.200000000000045
Losing trx 1
Fetching trx 6
Gain/Lose ratio 6.0

Optimization of Parameters

We should keep on optimizing our algo parameters regularly. By exploitation liberal arts information and using various methods like ML/backtesting performance.

Things to consider are :

Avoid overfitting of parameters. Overfitting that you optimize the logic and parameters to the extent that the program will shape best in whatsoever specific situations and scenarios. Just it may go under unfit if the scenario changes.

Paper Trading or Forward Testing or Simulation Trading in the real environment

Paper trading is the way of verification of your logic in the real environment. Peerless doesn't need to invest actual money in this stage. And It gives very accurate and punctilious results. One can gestate synoptical/replaceable results in the material environment. But it is time-consuming activity. One can do this by using the feature provided past his/her broker, or you can too develop your framework to test the same.

Deployment in the real environment

Deployment in the real environment requires multiple facets to be managed, which are in general not being considered in backtesting

Functionally following aspects are required to be managed:

  1. Order management
  2. Risk Management
  3. Money/Fund Management
  4. Variegation of assets
  5. Portfolio management
  6. User Management
  7. Slippages

Technically following aspects are required to be managed:

  • Establish Connection with the broker API.
  • Passing the grease one's palms/sell orders exploitation the broker connection,
  • Establish Link with the data API (if information vendor is different from factor)
  • Accessing the real time and diachronic data using data API connection.

This concludes the article. If I lost out on anything, tone free to apportion your thoughts. I leave try to contain it.

Conclusion:

To summarise the followers algo trading strategies, Algo can make up considered as a software ware and all the stages can cost well mapped with "Software Product Development Life Cps"

All the stages have their own importance and are critical to the success of the algo.

  • Formulate the trading logic/idea
  • Filtering criteria to choose the scripts
  • Verification of Logic( Visualization)
  • Backtesting
  • Optimisation of Parameters
  • Paper Trading operating room Presumptuous Testing or Simulation Trading
  • Deployment in the real environment

Disclaimer: All investments and trading in the stock securities industry involve risk. Any decisions to place trades in the business markets, including trading in stock or options or other financial instruments is a personal decision that should but embody ready-made after thorough research, including a personal risk and financial appraisal and the involvement of professional assistance to the extent you believe necessary. The trading strategies or related information mentioned in this article is for cognition purposes only.

Getting Started with Algorithmic Trading Course