Quantifying and computing StatArb trading signals

  1. We will see over available prices a day at a time and see what calculations need to be performed, starting with the computation of SimpleMovingAverages and price deviation from the rolling SMA first:
for i in range(0, num_days):
close_prices = {}

# Build ClosePrice series, compute SMA for each symbol and price-deviation from SMA for each symbol
for symbol in SYMBOLS:
close_prices[symbol] = symbols_data[symbol]['Close'].iloc[i]
if not symbol in price_history.keys():
price_history[symbol] = []
price_deviation_from_sma[symbol] = []

price_history[symbol].append(close_prices[symbol])
if len(price_history[symbol]) > SMA_NUM_PERIODS: # we track at most SMA_NUM_PERIODS number of prices
del (price_history[symbol][0])

sma = stats.mean(price_history[symbol]) # Rolling SimpleMovingAverage
price_deviation_from_sma[symbol].append(close_prices[symbol] - sma) # price deviation from mean
if len(price_deviation_from_sma[symbol]) > PRICE_DEV_NUM_PRICES:
del (price_deviation_from_sma[symbol][0])
  1. Next, we need to compute the relationships between the CAD/USD currency pair price deviations and the other currency pair price deviations. We will use covariance and correlation between the series of price deviations from SMA that we computed in the previous section. In this same loop, we will also compute the CAD/USD price deviation as projected by every other lead currency pair, and see what the difference between the projected price deviation and actual price deviation is. We will need these individual deltas between projected price deviation and actual price deviation to get a final delta value that we will use for trading.

First, let's look at the code block that populates the correlation_history and the delta_projected_actual_history dictionaries:

  # Now compute covariance and correlation between TRADING_INSTRUMENT and every other lead symbol
# also compute projected price deviation and find delta between projected and actual price deviations.
projected_dev_from_sma_using = {}
for symbol in SYMBOLS:
if symbol == TRADING_INSTRUMENT: # no need to find relationship between trading instrument and itself
continue

correlation_label = TRADING_INSTRUMENT + '<-' + symbol
if correlation_label not in correlation_history.keys(): # first entry for this pair in the history dictionary
correlation_history[correlation_label] = []
delta_projected_actual_history[correlation_label] = []

if len(price_deviation_from_sma[symbol]) < 2: # need atleast two observations to compute covariance/correlation
correlation_history[correlation_label].append(0)
delta_projected_actual_history[correlation_label].append(0)
continue

Now, let's look at the code block to compute correlation and covariance between the currency pairs:

    corr = np.corrcoef(price_deviation_from_sma[TRADING_INSTRUMENT], price_deviation_from_sma[symbol])
cov = np.cov(price_deviation_from_sma[TRADING_INSTRUMENT], price_deviation_from_sma[symbol])
corr_trading_instrument_lead_instrument = corr[0, 1] # get the correlation between the 2 series
cov_trading_instrument_lead_instrument = cov[0, 0] / cov[0, 1] # get the covariance between the 2 series

correlation_history[correlation_label].append(corr_trading_instrument_lead_instrument)

Finally, let's look at the code block that computes the projected price movement, uses that to find the difference between the projected movement and actual movement, and saves it in our delta_projected_actual_history list per currency pair:

    # projected-price-deviation-in-TRADING_INSTRUMENT is covariance * price-deviation-in-lead-symbol
projected_dev_from_sma_using[symbol] = price_deviation_from_sma[symbol][-1] * cov_trading_instrument_lead_instrument

# delta positive => signal says TRADING_INSTRUMENT price should have moved up more than what it did
# delta negative => signal says TRADING_INSTRUMENT price should have moved down more than what it did.
delta_projected_actual = (projected_dev_from_sma_using[symbol] - price_deviation_from_sma[TRADING_INSTRUMENT][-1])
delta_projected_actual_history[correlation_label].append(delta_projected_actual)

  1. Let's combine these individual deltas between projected and actual price deviation in CAD/USD to get one final StatArb signal value for CAD/USD that is a combination of projections from all the other currency pairs. To combine these different projections, we will use the magnitude of the correlation between CAD/USD and the other currency pairs to weigh the delta between projected and actual price deviations in CAD/USD as predicted by the other pairs. Finally, we will normalize the final delta value by the sum of each individual weight (magnitude of correlation) and that is what we will use as our final signal to build our trading strategy around:
  # weigh predictions from each pair, weight is the correlation between those pairs
sum_weights = 0 # sum of weights is sum of correlations for each symbol with TRADING_INSTRUMENT
for symbol in SYMBOLS:
if symbol == TRADING_INSTRUMENT: # no need to find relationship between trading instrument and itself
continue

correlation_label = TRADING_INSTRUMENT + '<-' + symbol
sum_weights += abs(correlation_history[correlation_label][-1])

final_delta_projected = 0 # will hold final prediction of price deviation in TRADING_INSTRUMENT, weighing projections from all other symbols.
close_price = close_prices[TRADING_INSTRUMENT]
for symbol in SYMBOLS:
if symbol == TRADING_INSTRUMENT: # no need to find relationship between trading instrument and itself
continue

correlation_label = TRADING_INSTRUMENT + '<-' + symbol

# weight projection from a symbol by correlation
final_delta_projected += (abs(correlation_history[correlation_label][-1]) * delta_projected_actual_history[correlation_label][-1])

# normalize by diving by sum of weights for all pairs
if sum_weights != 0:
final_delta_projected /= sum_weights
else:
final_delta_projected = 0

final_delta_projected_history.append(final_delta_projected)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.102.178