Note: this article points to the Legacy Version of Quantiacs. Please check more recent material on the new version of Quantiacs: get started, simple bitcoin algorithm, machine learning example and optimizer.
A unique feature of the Quantiacs toolbox is the use of asset exposure rather than discrete trades. In this short article we show a simple example which will help you in getting started.
Most trading backtester are event- or order-based. The developer of the trading system has normally to define the set of assets which should be bought or sold and the number of contracts for a specific asset which should be bought or sold.
Quantiacs uses a different approach to the simulation and bases its engine on the concept of asset exposure: instead of defining events (or orders), the developer should decide on a daily basis how the available capital should be allocated to the assets. The Quantiacs backtester takes care of translating exposure (or allocation) to assets into discrete orders. The advantage for the developer is clear, as it is possible to focus on the idea behind the trading strategy without spending time on the details.
Here we show a simple passive trading system which allocates equal weights to four futures contracts: Gold, Crude Oil, the S&P500 Index and the 10-Year US Treasury Note.
Each system should have a ‘mySettings’ function which in this case will simply take care of defining the four assets:
def mySettings():
'''Settings for assets to be traded.''' settings = {} # Futures contracts we trade:
settings['markets'] = ['CASH', 'F_GC', 'F_CL', 'F_ES', 'F_TY'] settings['lookback'] = 504
settings['budget'] = 10**6
settings['slippage'] = 0.05 return settings
The set of available assets for Quantiacs can be found on our page. Quantiacs uses a CASH artificial asset which can be used for reducing overall exposure. In this case we will have no CASH exposure and be fully invested.
The trading system allocates fixed weights to the four assets as follows:
def myTradingSystem(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings):
'''This system assigns fixed allocation weights.''' # 1st step: inititalize a list for the 5 assets
pos = numpy.zeros(5) # 2nd step: set fixed allocation weights. The order of the markets in the list defined in mySettings matters, so indices are:
# 0: CASH
# 1: F_GC (Gold)
# 2: F_CL (Crude Oil)
# 3: F_ES (S&P500)
# 4: F_TY (10-Year US Treasury Note) # we decide to be fully invested (no CASH), and assign:
pos[0] = 0 # CASH
pos[1] = 0.25 # Gold
pos[2] = 0.25 # Crude Oil
pos[3] = 0.25 # S&P500
pos[4] = 0.25 # 10-Year US Treasury Note weights = pos/numpy.nansum(abs(pos)) # normalize weights return weights, settings
This simple rule can be made dynamic by using an if…else structure and defining different allocations according to different events:
if [condition A]:
pos[0] = 0 # CASH
pos[1] = 0.25 # Gold
pos[2] = 0.25 # Crude Oil
pos[3] = 0.25 # S&P500
pos[4] = 0.25 # 10-Year US Treasury Note
elif [condition B]:
pos[0] = 0 # CASH
pos[1] = 0 # Gold
pos[2] = 0 # Crude Oil
pos[3] = 0.5 # S&P500
pos[4] = 0.5 # 10-Year US Treasury Note
else:
pos[0] = 0 # CASH
pos[1] = 0.5 # Gold
pos[2] = 0.5 # Crude Oil
pos[3] = 0 # S&P500
pos[4] = 0 # 10-Year US Treasury Note
The Quantiacs backtester takes then care of rebalancing weights on a daily basis ensuring that we are always fully investing the available capital.
If you have some simple ideas on asset allocation, try them taking part to our Q14 contest. Deadline for submissions is December 31st, 2020, and 2.25 M USD will be allocated to winning systems.
Do not forget to subscribe to our YouTube channel where you will find useful material:
The Full Strategy
import numpydef myTradingSystem(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings): pos = numpy.zeros(5) pos[0] = 0 # CASH
pos[1] = 0.25 # Gold
pos[2] = 0.25 # Crude Oil
pos[3] = 0.25 # S&P500
pos[4] = 0.25 # 10-Year US Treasury Note weights = pos/numpy.nansum(abs(pos))
return weights, settingsdef mySettings(): settings = {}
settings['markets'] = ['CASH', 'F_GC', 'F_CL', 'F_ES', 'F_TY']
settings['lookback'] = 504
settings['budget'] = 10**6
settings['slippage'] = 0.05 return settingsif __name__ == '__main__':
from quantiacsToolbox.quantiacsToolbox import runts, optimize results = runts(__file__)