Dynamic Asset Allocation using Neural Networks

17 min read

The project aims at building an asset allocation strategy for stocks comprising the nifty bank index by leveraging daily returns prediction from a set of dynamic linear neural network models.

The neural network models are dynamic and updated on a daily basis at the end of each trading day providing for reactivity to changes in market and stock trends in general. Besides that, the linearity of models accounts for an easy explainability of the results.

The complete data files and python code used in this project are also available in a downloadable format at the end of the article.

This article is the final project submitted by the author as a part of his coursework in the Executive Programme in Algorithmic Trading (EPAT®) at QuantInsti®. Do check our Projects page and have a look at what our students are building.


About the Author

Mrinal Mahajan has graduated in Mechanical Engineering from IIT Kanpur.

Trading and Investing is something that has always fascinated him and in a direction to make a career in the same, he cleared Financial Risk Management (FRM) from the Global Association of Risk Professionals (GARP).

He has been working in the analytics domain for the past 3 years having worked for some of the largest US banks. He is currently working with a leading US Bank in the credit card fraud risk modelling space.

As a next step towards getting hands-on experience with trading, he decided to leverage his analytical skills in order to develop something which could be profitable and requires minimal monitoring.

That’s when the idea for this project struck him and with the guidance from Quantinsti Team, he was able to execute it.


Defining the problem statement

Predict the percent change in the price of the stock from today’s close to close on the next day based on data till yesterday.

In simple words, if let’s say data is available to us on a daily frequency then based on the variables created on yesterday’s (d-1) data we want to predict the percent price change in close at next day (d+1) and close today(d).

Based on predictions we can know that if we buy the stock at today’s close whether or not will it turn profitable by tomorrow.

Based on the model results we want to make an asset allocation strategy that can leverage the BTST (Buy Today Sell Tomorrow) feature offered at relatively lower transaction costs as compared to intraday trades by various brokers.


Approached Solution

Part 1 - Model Development

We created the following set of dynamic neural network models:-

  1. Probability Predictor – Determines the probability of a positive return
  2. Positive Return Predictor – A model trained on only the positive returns instances which predicts the positive log value for the return
  3. Negative Return Predictor - A model trained on only the negative returns instances which predicts the negative log value for the return

Here log returns are used as dependent variable instead of percentage returns or price changes in order to maintain stationarity in series.

  • Development Data – 2010 to 2015
  • Validation data – 2016 to Apr’2018
  • Out of Time Data – May’2018 to Dec’2020

The historical data taken for the stocks as given below:-

Bank/Company Name

Symbol

Weightage in Nifty Bank

Data Available from

HDFC Bank Ltd.

HDFCBANK

28.39%

01-01-2010

ICICI Bank Ltd.

ICICIBANK

19.48%

01-01-2010

Kotak Mahindra Bank Ltd.

KOTAKBANK

16.31%

01-01-2010

Axis Bank Ltd.

AXISBANK

14.95%

01-01-2010

State Bank of India

SBIN

9.56%

01-01-2010

IndusInd Bank Ltd.

INDUSINDBK

4.37%

01-01-2010

Bandhan Bank Ltd.

BANDHANBNK

2.58%

27-03-2018

Federal Bank Ltd.

FEDERALBNK

1.33%

01-01-2010

RBL Bank Ltd.

RBLBANK

1.06%

31-08-2016

IDFC First Bank Ltd.

IDFCFIRSTB

0.85%

06-11-2015

Punjab National Bank

PNB

0.46%

01-01-2010

Bank of Baroda

BANKBARODA

0.66%

01-10-2010

Part 2 - Strategy

The aim of the strategy is to distribute the available cash generated from cash inflow and sale of any existing positions amongst the 12 banking stocks on a daily basis.

The procedure followed to execute the strategy is as follows:-

  1. Get the probability (p) of positive next day return (future return) from the probabilistic model.
  2. Get the positive and negative log returns from the deterministic return models and convert the log values to percentages. Let’s say the positive percentage return is m and the negative percentage return is n.
  3. Calculate expected return(e) as p*m+(1-p)n. Convert the expected return to log and divide it by Volatility (standard deviation) of the last 5 days log return to get a ratio. Let’s call this ratio Sharpe.
  4. Modify the Sharpe as a minimum (0, Sharpe). For the stocks with 0 Sharpe sell the shares if holding in the proportion of expected losses (calculated from the expected return)/ [profits made till date] if profits are positive else sell all shares for that stock.
  5. For the stocks with positive Sharpe distribute the available cash from the sale of stocks and actual cash in the proportion of their Sharpe.

Part 3 - Risk Management

Apply a stop loss at 20% for investments made in each stock i.e. that if the market value of existing positions for a stock is less than 80% of value invested into it then sell all shares for that stock.


Model Development

The variables created as inputs to the models are as follows:-

Variable

Dimension

Description 

return_1d

past returns

last 1 day log return

return_2d

past returns

last 2 day log return

return_3d

past returns

last 3 day log return

return_4d

past returns

last 4 day log return

return_5d

past returns

last 5 day log return

return_6d

past returns

last 6 day log return

return_7d

past returns

last 7 day log return

return_8d

past returns

last 8 day log return

return_9d

past returns

last 9 day log return

return_10d

past returns

last 10 day log return

Open_Chg

Changes

log change for open last day

High_Chg

Changes

log change for high last day

Low_Chg

Changes

log change for low last day

Range_Chg

Changes

log change for high-low range last day

Volume_Chg

Changes

log change for volume last day

Volatility5

Volatility

standard deviation of last 5 day log returns

Volatility20

Volatility

standard deviation of last 20 day log returns

MA5_ratio

Ratios

ratio of last day close to last 5 days moving average

MA20_ratio

Ratios

ratio of last day close to last 20 days moving average

High5_ratio

Ratios

ratio of last day close to last 5 days high

Low5_ratio

Ratios

ratio of last 5 day low to last day close

High20_ratio

Ratios

ratio of last day close to last 20 days high

Low20_ratio

Ratios

ratio of last 20 day low to last day close

return_1d_nifty

past returns nifty

last 1 day log return for nifty bank

return_2d_nifty

past returns nifty

last 2 day log return for nifty bank

return_3d_nifty

past returns nifty

last 3 day log return for nifty bank

return_4d_nifty

past returns nifty

last 4 day log return for nifty bank

return_5d_nifty

past returns nifty

last 5 day log return for nifty bank

return_6d_nifty

past returns nifty

last 6 day log return for nifty bank

return_7d_nifty

past returns nifty

last 7 day log return for nifty bank

return_8d_nifty

past returns nifty

last 8 day log return for nifty bank

return_9d_nifty

past returns nifty

last 9 day log return for nifty bank

return_10d_nifty

past returns nifty

last 10 day log return for nifty bank

MA5_ratio_nifty

ratios nifty

ratio of last day close to last 5 days moving average for nifty bank

MA20_ratio_nifty

ratios nifty

ratio of last day close to last 20 days moving average for nifty bank

High5_ratio_nifty

ratios nifty

ratio of last day close to last 5 days high for nifty bank

Low5_ratio_nifty

ratios nifty

ratio of last 5 day low to last day close for nifty bank

High20_ratio_nifty

ratios nifty

ratio of last day close to last 20 days high for nifty bank

Low20_ratio_nifty

ratios nifty

ratio of last 20 day low to last day close for nifty bank

Volatility5_nifty

volatility nifty

standard deviation of last 5 day log returns for nifty bank

Volatility20_nifty

volatility nifty

standard deviation of last 20 day log returns for nifty bank

Bollinger5_ratio

Bollinger

(price-lower bollinger)/(upper bollinger - lower bollinger) in last 5 days

Bollinger20_ratio

Bollinger

(price-lower bollinger)/(upper bollinger - lower bollinger) in last 20 days

ADX5

Momentum Indicator

average direction movement index over 5 days

RSI5

Momentum Indicator

Relative Strength index over 5 days

ADX20

Momentum Indicator

average direction movement index over 20 days

RSI20

Momentum Indicator

Relative Strength index over 20 days

correlation

nifty correlation

correlation of last 10 day's return with nifty last 10 day returns

 

A common input data set was created in the first place. Then we moved on to analyze the variable trends for the 3 use cases – probability, positive return and negative returns model.

As an example, we are showing below the trends of the correlation variable in 3 models.

Model 1 - Probability Model Trend

Model 2 - Positive Return Model Trend

The trend signifies the assumption that for the upward move in prices a higher correlation of stock with market accounts for higher returns.

The trend shows that in general with increased correlation the negative impact on share prices is also increased.

After visualizing the trends we did variable reduction for each model specifically using advanced analytics techniques like variance inflation, variable clustering and backward selection along with a basic intuitive visualization of trends.

Note: The codes and resources for model development can be found towards the end of the blog.

After the variable analysis and reductions following variables were used as input into the models.

Probability Prediction Model

Variable

Description

return_1d

last 1 day log return

return_3d

last 3 day log return

return_5d

last 5 day log return

return_10d

last 10 day log return

Open_Chg

log change for open last day

High_Chg

log change for high last day

Low_Chg

log change for low last day

Volume_Chg

log change for volume last day

MA5_ratio

ratio of last day close to last 5 days moving average

MA20_ratio

ratio of last day close to last 20 days moving average

Low5_ratio

ratio of last 5 day low to last day close

High20_ratio

ratio of last day close to last 20 days high

Bollinger5_ratio

(price-lower bollinger)/(upper bolinger - lower bollinger) in last 5 days

Bollinger20_ratio

(price-lower bollinger)/(upper bolinger - lower bollinger) in last 20 days

RSI5

Relative Strength index over 5 days

RSI20

Relative Strength index over 20 days

return_1d_nifty

last 1 day log return for nifty

return_2d_nifty

last 2 day log return for nifty

return_3d_nifty

last 3 day log return for nifty

return_4d_nifty

last 4 day log return for nifty

return_8d_nifty

last 8 day log return for nifty

return_10d_nifty

last 10 day log return for nifty

MA5_ratio_nifty

ratio of last day close to last 5 days moving average for nifty bank

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

Positive Return Prediction Model

Variable

Description

return_1d

last 1 day log return

return_2d

last 2 day log return

return_3d

last 3 day log return

return_4d

last 4 day log return

Open_Chg

log change for open last day

Volume_Chg

log change for volume last day

Voltality5

standard deviation of last 5 day log returns

Voltality20

standard deviation of last 20 day log returns

MA5_ratio

ratio of last day close to last 5 days moving average

High5_ratio

ratio of last day close to last 5 days high

Low5_ratio

ratio of last 5 day low to last day close

High20_ratio

ratio of last day close to last 20 days high

ADX20

average direction movement index over 20 days

RSI20

Relative Strength index over 20 days

return_1d_nifty

last 1 day log return for nifty

return_2d_nifty

last 2 day log return for nifty

return_3d_nifty

last 3 day log return for nifty

return_4d_nifty

last 4 day log return for nifty

return_9d_nifty

last 9 day log return for nifty

return_10d_nifty

last 10 day log return for nifty

MA5_ratio_nifty

ratio of last day close to last 5 days moving average for nifty bank

Low5_ratio_nifty

ratio of last 5 day low to last day close for nifty bank

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

Voltality5_nifty

standard deviation of last 5 day log returns for nifty bank

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

correlation

correlation of last 10 day's return with nifty last 10 day returns

 

Negative Return Prediction Model

Variable

Description

return_1d

last 1 day log return

return_2d

last 2 day log return

return_3d

last 3 day log return

High_Chg

log change for high last day

Voltality5

standard deviation of last 5 day log returns

Voltality20

standard deviation of last 20 day log returns

MA20_ratio

ratio of last day close to last 20 days moving average

Low5_ratio

ratio of last 5 day low to last day close

High20_ratio

ratio of last day close to last 20 days high

RSI20

Relative Strength index over 20 days

return_1d_nifty

last 1 day log return for nifty

return_2d_nifty

last 2 day log return for nifty

return_3d_nifty

last 3 day log return for nifty

return_4d_nifty

last 4 day log return for nifty

return_5d_nifty

last 5 day log return for nifty

return_9d_nifty

last 9 day log return for nifty

High5_ratio_nifty

ratio of last day close to last 5 days high for nifty bank

Low5_ratio_nifty

ratio of last 5 day low to last day close for nifty bank

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

Voltality5_nifty

standard deviation of last 5 day log returns for nifty bank

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

correlation

correlation of last 10 day's return with nifty last 10 day returns

Using the given variables the linear neural network models are developed which have a converging architecture. A converging architecture is such that at the next hidden layer the number of nodes is half of that at the current layer.

For example: In the probability model there are 26 inputs i.e. 26 nodes at the input layer, then 13 nodes at the 1st hidden layer, 6 nodes at the 2nd hidden layer, 3 nodes at the 3rd hidden layer and finally one node at the output.

All hidden layer nodes have a linear function in this case and just the output layer has a sigmoid function. In the positive and negative returns model, all nodes including output have linear activation.

The development data used for training the model is from 2010-2015 – 5 Years.

The static equation coefficients obtained for each of the models are as follows:-

Probability Prediction Model

A linear equation for the log of odds log(p/1-p)

Variable

Description

return_1d

last 1 day log return

return_3d

last 3 day log return

return_5d

last 5 day log return

return_10d

last 10 day log return

Open_Chg

log change for open last day

High_Chg

log change for high last day

Low_Chg

log change for low last day

Volume_Chg

log change for volume last day

MA5_ratio

ratio of last day close to last 5 days moving average

MA20_ratio

ratio of last day close to last 20 days moving average

Low5_ratio

ratio of last 5 day low to last day close

High20_ratio

ratio of last day close to last 20 days high

Bollinger5_ratio

(price-lower bollinger)/(upper bolinger - lower bollinger) in last 5 days

Bollinger20_ratio

(price-lower bollinger)/(upper bolinger - lower bollinger) in last 20 days

RSI5

Relative Strength index over 5 days

RSI20

Relative Strength index over 20 days

return_1d_nifty

last 1 day log return for nifty

return_2d_nifty

last 2 day log return for nifty

return_3d_nifty

last 3 day log return for nifty

return_4d_nifty

last 4 day log return for nifty

return_8d_nifty

last 8 day log return for nifty

return_10d_nifty

last 10 day log return for nifty

MA5_ratio_nifty

ratio of last day close to last 5 days moving average for nifty bank

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

Positive Return Model

A linear equation for log returns

Variable

Description

Coefficient

return_1d

last 1 day log return

0.112714604

return_2d

last 2 day log return

0.076917067

return_3d

last 3 day log return

0.137521163

return_4d

last 4 day log return

0.139919728

Open_Chg

log change for open last day

0.044385113

Volume_Chg

log change for volume last day

0.00109395

Voltality5

standard deviation of last 5 day log returns

-0.00038334

Voltality20

standard deviation of last 20 day log returns

0.056020129

MA5_ratio

ratio of last day close to last 5 days moving average

0.314374059

High5_ratio

ratio of last day close to last 5 days high

0.315460533

Low5_ratio

ratio of last 5 day low to last day close

0.204366401

High20_ratio

ratio of last day close to last 20 days high

0.133332253

ADX20

average direction movement index over 20 days

0.001150683

RSI20

Relative Strength index over 20 days

0.01172027

return_1d_nifty

last 1 day log return for nifty

0.267879993

return_2d_nifty

last 2 day log return for nifty

0.193813279

return_3d_nifty

last 3 day log return for nifty

0.161507115

return_4d_nifty

last 4 day log return for nifty

0.104044914

return_9d_nifty

last 9 day log return for nifty

0.039391026

return_10d_nifty

last 10 day log return for nifty

0.029924326

MA5_ratio_nifty

ratio of last day close to last 5 days moving average for nifty bank

0.247091874

Low5_ratio_nifty

ratio of last 5 day low to last day close for nifty bank

0.047915675

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

0.018904656

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

0.055917718

Voltality5_nifty

standard deviation of last 5 day log returns for nifty bank

0.097226188

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

0.048495531

correlation

correlation of last 10 day's return with nifty last 10 day returns

0.001289934

intercept

 

-0.232171148

Negative Return Model

A linear equation for log returns

Variable

Description

Coefficient

return_1d

last 1 day log return

0.124469906

return_2d

last 2 day log return

0.094707593

return_3d

last 3 day log return

0.098002963

High_Chg

log change for high last day

0.061372437

Voltality5

standard deviation of last 5 day log returns

0.489989489

Voltality20

standard deviation of last 20 day log returns

0.461109012

MA20_ratio

ratio of last day close to last 20 days moving average

0.143796369

Low5_ratio

ratio of last 5 day low to last day close

0.245543823

High20_ratio

ratio of last day close to last 20 days high

0.214187935

RSI20

Relative Strength index over 20 days

0.017691486

return_1d_nifty

last 1 day log return for nifty

0.152266026

return_2d_nifty

last 2 day log return for nifty

0.149913758

return_3d_nifty

last 3 day log return for nifty

0.137844741

return_4d_nifty

last 4 day log return for nifty

0.135978788

return_5d_nifty

last 5 day log return for nifty

0.005645283

return_9d_nifty

last 9 day log return for nifty

0.035861455

High5_ratio_nifty

ratio of last day close to last 5 days high for nifty bank

0.303022981

Low5_ratio_nifty

ratio of last 5 day low to last day close for nifty bank

0.101814494

High20_ratio_nifty

ratio of last day close to last 20 days high for nifty bank

0.074914791

Low20_ratio_nifty

ratio of last 20 day low to last day close for nifty bank

0.029958185

Voltality5_nifty

standard deviation of last 5 day log returns for nifty bank

0.481154203

Voltality20_nifty

standard deviation of last 20 day log returns for nifty bank

0.024172308

correlation

correlation of last 10 day's return with nifty last 10 day returns

0.000418738

intercept

 

-0.212120146


Static versus Dynamic Model

The model development of 2010-2015 (5 Years) of data gave us the static equations for all models. However, the good thing about a neural network is that its weights for different nodes can be updated by feeding in the new data.

This intuitively makes sense as the markets or stocks don’t really follow a fixed static equation all the time and we need a dynamic solution that could reflect those changes.

As a proof of concept for the same, we created a dynamic model by feeding data from 2016’Jan to 2018’Apr on a daily frequency and updating model weights. The equation for all 3 models showed changes over a period of time.

Next, we compared the results for the 2018’Jan to 2018’Apr period to see the difference. Here we are trying to compare the accuracies and precision for both model over these 4 months for different stocks.

To explain how we are building a predicting indicator, let’s say the probability model returns a probability p for the rise in price, and positive and negative return models gave x and - y as returns, then expected return e = p*x+(1-p)*(-y).

We say positive return predicted if e is positive and base our accuracy precision and recall on that.

Static vs Dynamic – Month Wise Split

Month

Static

Dynamic

Accuracy 

Precision 

Recall 

Accuracy 

Precision 

Recall 

2018-01

43%

42%

41%

46%

46%

53%

2018-02

46%

42%

89%

53%

40%

35%

2018-03

50%

44%

46%

54%

46%

27%

2018-04

50%

48%

46%

50%

48%

53%

Total

47%

44%

54%

51%

46%

43%

As can be seen from the above stats the dynamic model is more accurate and precise in its predictions as compared to the static model. Also, there is a great possibility of model results improving in future as more and more data is fed into it.

Static vs Dynamic – Stock Wise Split

Symbol

Static

Dynamic

Accuracy 

Precision 

Recall 

Accuracy 

Precision 

Recall 

AXISBANK

46%

41%

67%

51%

41%

42%

BANKBARODA

50%

45%

56%

51%

45%

36%

FEDERALBNK

51%

49%

47%

49%

45%

37%

HDFCBANK

46%

39%

24%

61%

61%

53%

ICICIBANK

48%

42%

76%

50%

39%

36%

INDUSINDBK

48%

48%

37%

49%

50%

43%

KOTAKBANK

46%

58%

43%

53%

64%

51%

PNB

40%

34%

63%

53%

37%

37%

SBIN

45%

40%

75%

49%

36%

38%

RBLBANK

50%

50%

60%

41%

41%

43%

BANDHANBNK

69%

40%

67%

54%

29%

67%

IDFCFIRSTB

45%

41%

53%

49%

44%

50%

Total

47%

44%

54%

51%

46%

43%

As can be seen for most of the stocks as well the dynamic model is coming out to be much more accurate and precise.


Strategy

Based on the dynamic model results we implemented some variants of a Buy Today Sell Tomorrow (BTST) strategy. The backtest period was from 1st May’2018 – 10th Dec’2020 which is 2.61 years.

The benchmark strategy to compare with is taken as buy and hold strategy on nifty bank index. The variant that came out to be the best choice was a monthly SIP with Stop loss for an investment in each stock at 20%. The SIP amount in our case was taken as INR 20,000 per month.

Below are the statistics for the same:-

Statistics

Benchmark

Monthly SIP

Max ROI

26.89%

131.87%

Min ROI

-33.83%

-22.92%

Max Drawdown

47.86%

55.39%

Final ROI

19.70%

53.31%

YOY Return

7.14%

17.80%

As can be seen that the strategy generates at least more than 10% year on year returns as compared to the benchmark strategy of buying and holding bank nifty. The overtime performance of strategy can be seen in the below chart:

As can be seen from the chart that though the strategy lags a bit from the benchmark in the initial years it outperforms it in the more recent period.


Limitations

  1. The backtest doesn’t account for any transaction costs, however, for this strategy, the minimalistic transaction cost is available by various brokers. However in order to further fine-tune it one can sell only the delivered shares rather than open positions.
  2. There is some requirement of implementing a market microstructure strategy in order to obtain the best price for buying or selling the stock on a day.
  3. An automated application to execute the strategy on daily basis will be required. This has been worked upon by creating an app on the KITE platform of Zerodha.

Results

At the time of documenting this project 11th Feb’21, the model has given approximately 5% return on investment over a month’s period.

The details can be seen in the table below:-

Symbol

Money Invested

Market value

P/L

Shares Hold

Shares in Demat

LTP

HDFCBANK

1,387.15

1,581.75

194.60

1

1

1,581.75

ICICIBANK

6.20

-

-6.20

0

0

632.15

KOTAKBANK

7,066.20

7,808.20

742.00

4

4

1,952.05

AXISBANK

-

-

-

0

0

734.80

SBIN

16.55

-

-16.55

0

0

392.25

INDUSINDBK

4,256.60

5,114.00

857.40

5

5

1,022.80

BANDHANBNK

376.15

-

-376.15

0

0

331.20

FEDERALBNK

779.70

745.65

-34.05

9

8

82.85

RBLBANK

2,483.95

2,673.55

189.60

11

11

243.05

IDFCFIRSTB

719.21

758.25

39.04

15

13

50.55

BANKBARODA

412.75

398.50

-14.25

5

4

79.70

PNB

228.40

118.35

-110.05

3

3

39.45

Market Money

17732.86

19,198.25

1,465.39

  

  

  

Cash in hand

2267.14

1886.55

-380.59

  

  

  

Total

20000.00

21,084.80

1,084.80

  

  

  

ROI

5.42%

  

  

  

  

  


Codes

The codes and detailed analysis of this strategy can be found here.


Conclusion

An active daily portfolio rebalancing asset allocation strategy for nifty bank stocks leveraging the dynamic linear models can help generate annual returns of close to 20% within an approximate span of 3 years.

If you want to learn various aspects of Algorithmic trading then check out the Executive Programme in Algorithmic Trading (EPAT). The course covers various training modules and equips you with the required skill sets to build a promising career in algorithmic trading.

In order to assist individuals who are considering pursuing a career in algorithmic and quantitative trading, this case study has been collated based on the personal experiences of a student or alumni from QuantInsti’s EPAT programme. Case studies are for illustrative purposes only and are not meant to be used for investment purposes. The results achieved post completion of the EPAT programme may not be uniform for all individuals.

Algo Trading Course