5. Single-instrument signal strategy

To build on your RollingFutureStrategy, add signals to take long or short positions during different time periods.

A simple signal strategy

1. Set up a single-instrument RollingFutureStrategy again

The first few code blocks are very close to what you already used in the previous two tutorials:

Set up environment

import sigtech.framework as sig
import datetime as dtm

sig.init();

Define instrument, time period, and RollingFutureStrategy

my_instrument = sig.obj.get("KC COMDTY FUTURES GROUP")

my_start = dtm.date(2019, 1, 4)
my_end = dtm.date(2021, 12, 31)

my_rfs = sig.RollingFutureStrategy(
    start_date=my_start,
    end_date=my_end,

    currency=my_instrument.currency,
    contract_code=my_instrument.contract_code,
    contract_sector=my_instrument.contract_sector,

    rolling_rule="F_0"
)

2. Create a DataFrame of signals

Every RollingFutureStrategy instance has a history, in the format of a simple table of dates and values:

# View your RollingFutureStrategy instance's history
my_rfs.history()

Note: the table is a pandas Series. Run my_rfs.history? to see this confirmed in its docstring.

Duplicate the history Series and reset its values

# Make a copy of the history Series
signals = my_rfs.history().copy()

# Reset its values to 0
signals.values[:] = 0

# View it
signals

The signals series you've just created has all the same dates as the history of your RollingFutureStrategy, but the values are now reset to 0. In the next step you will repopulate the values with signals—indicators of what position to take.

Add the signals

A signal of 1 indicates a 100% long position, while a signal of -1 indicates a 100% short position. Set a signal of -1 for the first four months of each year in the time period, and 1 for the final four months of each year, assuming there is a strategic rationale for this relating to seasonal market activity:

# short position for first 4 months of each year
signals.loc[signals.index.month <= 4] = -1 

# long position for last 4 months of each year
signals.loc[signals.index.month >= 8] = 1 

# view new values
signals

Convert series to DataFrame and associate with RFS instance

For future steps to work, signals needs to be in DataFrame format and have the exact same name as your RollingFutureStrategy instance. This name-sharing allows the SignalStrategy instance to reference the relevant RollingFutureStrategy instance:

# Convert pandas Series to pandas Dataframe
# and give it the same name as your RollingFutureStrategy instance
signals = signals.to_frame(my_rfs.name)

# View the dataframe
signals

3. Define SignalStrategy

seasonal_strategy = sig.SignalStrategy(
    start_date=my_start,
    end_date=my_end,
    currency='USD',
    
    # Reference the signals DataFrame
    signal_name=sig.signal_library.from_ts(signals).name,
    # This also tells the SignalStrategy which underyling strategy to use
    # (the RollingFutureStrategy instance) as they have identical names
    
    rebalance_frequency='SOM',
    # Note that this means only the signals for the start of the month matter.
    # All the other signal values are irrelevant.

    # Set allocation function to normalize  number of short and long positions
    # (hold the same number of long and short positions at any given time).
    allocation_function=sig.signal_library.allocation.normalize_weights,
    
    # Use .? to view other possible arguments for the SignalStrategy building block.
)

4. View performance

seasonal_strategy.plot.performance()

👷Your turn: customise the strategy

Try a different set of signals.

Last updated

© 2023 SIG Technologies Limited