Calculate pair stats

Go back to index

Before we proceed, I just want to comment about couple of decisions we made and make you aware that there are multiple options available.

  1. Choosing a pair

For the current discussion we will select JINDALSTEL and JSWSTEEL because I found some trading opportunities in the time period we selected. (It is possible that you might not get an opportunity for a long time period and waiting for that opportunity is the most important part of the strategy. To mitigate that, you can track multiple pairs). This process can be repeated for each and every pair, but to keep things simple we will focus on just one pair.

  1. Choosing the variable for pair

The varsity article describes three variables to describe the pair - Spread, Differential and Ratio. The article later recommends using ratio as main variable for the pair.

In this article, we will

  1. Download historical stock data for the pair
  2. Calculate the ratio of the pair
  3. Calculate the stats for the ratio - mean, standard deviation
  4. Plot 1σ, 2σ and 3σ values

1. Download historical stock data for the pair

from datetime import date
from jugaad_data import nse
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from_date = date(2019,1,1)
to_date = date(2019,6,30)
sym_1 = "JINDALSTEL"
sym_2 = "JSWSTEEL"
stock_1 = nse.stock_df(sym_1, from_date, to_date)
stock_2 = nse.stock_df(sym_2, from_date, to_date)

2. Calculate ratio of the pair

ratio = stock_1['CLOSE'] / stock_2['CLOSE']

3. Calculate ratio stats

mean = ratio.mean()
stdev = ratio.std()
print("Mean (μ): {:.3f} and Standard Deviation (σ): {:.4f}".format(mean, stdev))

Mean (μ): 0.561 and Standard Deviation (σ): 0.0433

4. Plot

We will plot the ratio values against the mean and standard deviation lines to see how the ratio changed over the time period.

fig,ax = plt.subplots()
# Plot the ratio
data_line = ax.plot(ratio, label='Ratio')

# For drawing mean line
mean_arr = [mean for _ in ratio]

stdev_2_pos_line = ax.plot(mean_arr + 2 * stdev, label='μ + 2σ', linestyle='--')
stdev_1_pos_line = ax.plot(mean_arr + stdev, label='μ + 1σ', linestyle='--')
mean_line = ax.plot(mean_arr, label='μ', linestyle='--')
stdev_1_neg_line = ax.plot(mean_arr - stdev, label='μ - 1σ', linestyle='--')
stdev_2_neg_line = ax.plot(mean_arr - 2 * stdev, label='μ - 2σ', linestyle='--')

# Make a legend
legend = ax.legend(loc='upper right')

fig.suptitle('Daily ratio', fontsize=20)

Let us see different levels around the mean-

print(" \t Ratio")
for i in range(3, -4, -1):
    r = mean + i * stdev
    print("μ{0:+}σ \t {1:.3f}".format(i, r))
μ+3σ 	 0.691
μ+2σ 	 0.648
μ+1σ 	 0.605
μ+0σ 	 0.561
μ-1σ 	 0.518
μ-2σ 	 0.475
μ-3σ 	 0.432

Decision matrix

I have modified the entry and exit logic slightly from what is described in the varsity article-

Position Entry condition Entry Ratio Exit condition Exit Ratio Stop Loss Stop loss ratio
Long < μ - 2σ < 0.475 > μ - 1σ > 0.518 < μ - 3σ < 0.432
Short > μ + 2σ > 0.648 < μ + 1σ < 0.605 > μ + 3σ > 0.691

You can see that ratio barely touched (μ - 2σ) and (μ + 2σ) level once each. So these opportunities are not very common.

We ran our analysis on Jan 2019 to Jun 2019 data, we will backtest this strategy on next six months ie. from July 2019 to Dec 2019.

At the time of the writing, I’m not sure if we will find any opportunity, will we make profit or we will hit a stoploss, lets find out in the next section.

Next step

Go back to index

Download notebook