Let's execute a strategy for the StatArb signal using the following steps:
- Now, using the StatArb signal we just computed, we can build a strategy similar to the trend-following strategy we saw before. Let's start by looking at the trading logic that controls the sell trades:
if ((final_delta_projected < StatArb_VALUE_FOR_SELL_ENTRY and abs(close_price - last_sell_price) > MIN_PRICE_MOVE_FROM_LAST_TRADE) # StatArb above sell entry threshold, we should sell
or
(position > 0 and (open_pnl > MIN_PROFIT_TO_CLOSE))): # long from negative StatArb and StatArb has gone positive or position is profitable, sell to close position
orders.append(-1) # mark the sell trade
last_sell_price = close_price
position -= NUM_SHARES_PER_TRADE # reduce position by the size of this trade
sell_sum_price_qty += (close_price * NUM_SHARES_PER_TRADE) # update vwap sell-price
sell_sum_qty += NUM_SHARES_PER_TRADE
print("Sell ", NUM_SHARES_PER_TRADE, " @ ", close_price, "Position: ", position)
print("OpenPnL: ", open_pnl, " ClosedPnL: ", closed_pnl, " TotalPnL: ", (open_pnl + closed_pnl))
- Now, let's look at the buy trade logic, which is quite similar to the sell trade logic:
elif ((final_delta_projected > StatArb_VALUE_FOR_BUY_ENTRY and abs(close_price - last_buy_price) > MIN_PRICE_MOVE_FROM_LAST_TRADE) # StatArb below buy entry threshold, we should buy
or
(position < 0 and (open_pnl > MIN_PROFIT_TO_CLOSE))): # short from positive StatArb and StatArb has gone negative or position is profitable, buy to close position
orders.append(+1) # mark the buy trade
last_buy_price = close_price
position += NUM_SHARES_PER_TRADE # increase position by the size of this trade
buy_sum_price_qty += (close_price * NUM_SHARES_PER_TRADE) # update the vwap buy-price
buy_sum_qty += NUM_SHARES_PER_TRADE
print("Buy ", NUM_SHARES_PER_TRADE, " @ ", close_price, "Position: ", position)
print("OpenPnL: ", open_pnl, " ClosedPnL: ", closed_pnl, " TotalPnL: ", (open_pnl + closed_pnl))
else:
# No trade since none of the conditions were met to buy or sell
orders.append(0)
positions.append(position)
- Finally, let's also look at the position management and PnL update logic, very similar to previous trading strategies:
# This section updates Open/Unrealized & Closed/Realized positions
open_pnl = 0
if position > 0:
if sell_sum_qty > 0: # long position and some sell trades have been made against it, close that amount based on how much was sold against this long position
open_pnl = abs(sell_sum_qty) * (sell_sum_price_qty / sell_sum_qty - buy_sum_price_qty / buy_sum_qty)
# mark the remaining position to market i.e. pnl would be what it would be if we closed at current price
open_pnl += abs(sell_sum_qty - position) * (close_price - buy_sum_price_qty / buy_sum_qty)
elif position < 0:
if buy_sum_qty > 0: # short position and some buy trades have been made against it, close that amount based on how much was bought against this short position
open_pnl = abs(buy_sum_qty) * (sell_sum_price_qty / sell_sum_qty - buy_sum_price_qty / buy_sum_qty)
# mark the remaining position to market i.e. pnl would be what it would be if we closed at current price
open_pnl += abs(buy_sum_qty - position) * (sell_sum_price_qty / sell_sum_qty - close_price)
else:
# flat, so update closed_pnl and reset tracking variables for positions & pnls
closed_pnl += (sell_sum_price_qty - buy_sum_price_qty)
buy_sum_price_qty = 0
buy_sum_qty = 0
sell_sum_price_qty = 0
sell_sum_qty = 0
last_buy_price = 0
last_sell_price = 0
pnls.append(closed_pnl + open_pnl)