Minimum Profit Strategy

Introduction

This trading strategy takes new spread values one by one and allows checking if the conditions to open a position are fulfilled with each new timestamp and value provided. This allows for easier integration of these strategies into an existing data pipeline. Also, the strategy object keeps track of open and closed trades and the supporting information related to them.

Minimum Profit Strategy

The Minimum Profit class from the Cointegration Approach generates optimal entry and exit levels (buy_level, close_level, sell_level) as well as number of shares (shares_A, shares_B) to trade per asset in a cointegrated pair. The strategy described in this section of the documentation can be used to trade those generated signals.

The signal generation process relies on the performance of the spread, which is calculated as:

\[Spread = PriceA + beta * PriceB\]

Where the \(beta\) parameter is given by the Minimum Profit class. If the spread value drops below the buy_level, a buy trade should be opened, meaning we should go shares_A long and shares_B short. If the spread value rises above the sell_level, a sell trade should be opened, so we short shares_B and go long shares_A. Upon reaching the close_level, a buy or a sell trade should be closed. This strategy assumes only one open trade at a time.

../_images/AME-DOV1.png

An example of pair trading Ametek Inc. (AME) and Dover Corp. (DOV) from January 2nd, 2019 to date. The green line is the sell level, the red line is the buy level, and the black line is the close level.

The strategy object is initialized with a number of shares and optimal levels.

The update_spread_value method allows adding new spread values one by one - when they are available. At each stage, the check_entry_signal method checks if the trade should be entered according to the above-described logic. If the trade should be opened, it can be added to the internal dictionary using the add_trade method.

As well, the update_trades method can be used to check if any trades should be closed. If so, the internal dictionaries are updated, and the list of the closed trades at this stage is returned.

Implementation

Example

# Importing packages
import pandas as pd
import numpy as np

# Importing ArbitrageLab tools
from arbitragelab.cointegration_approach.minimum_profit import MinimumProfit
from arbitragelab.trading import MinimumProfitTradingRule

# Using MinimumProfit as optimizer ...

# Generate optimal trading levels and number of shares to trade
num_of_shares, optimal_levels = optimizer.get_optimal_levels(optimal_ub,
                                                             minimum_profit,
                                                             beta_eg,
                                                             epsilon_t_eg)

# Calculating spread
spread = optimizer.construct_spread(data, beta_eg)

# Creating a strategy
strategy = MinimumProfitTradingRule(num_of_shares, optimal_levels)

# Adding initial spread value
strategy.update_spread_value(spread[0])

# Feeding spread values to the strategy one by one
for time, value in spread.iteritems():
    strategy.update_spread_value(value)

    # Checking if logic for opening a trade is triggered
    trade, side = strategy.check_entry_signal()

    # Adding a trade if we decide to trade signal
    if trade:
        strategy.add_trade(start_timestamp=time, side_prediction=side)

    # Update trades, close if logic is triggered
    close = strategy.update_trades(update_timestamp=time)

# Checking currently open trades
open_trades = strategy.open_trades

# Checking all closed trades
closed_trades = strategy.closed_trades

Research Notebooks

The following research notebook can be used to better understand the Strategy described above.

References