Welcome to Auquan Toolbox
Auquan provides a backtesting toolbox to develop your trading algorithms. The toolbox is free and open source which you can use to create and backtest strategies.
Quick Startup Guide
-
Install Python and dependent packages
You need Python 2.7 (Python 3 will be supported later) to run this toolbox. For an easy installation process, we recommend Anaconda since it will reliably install all the necessary dependencies. Download Anaconda and follow the instructions on the installation page.
Once you have Python,install the following packages. Easiest way is via pip- numpy
- pandas
- pandas-datareader
- plotly
-
Clone/Download this repository.
git clone https://{your_username}@bitbucket.org/auquan/auquantoolbox.git
-
Navigate to the place where you downloaded the repo. Go inside that folder and run the following code to make sure everything is setup properly.
python my_trading_params.py
-
Use my_trading_params.py as a template which contains skeleton functions (with explanation) that need to be filled in to create your own trading strategy. Copy that template to another file and then start implementing the methods in that file. You can use pair_trading_params.py and meanreversion_trading_params.py as motivation.
How does the toolbox work?
Trading System
The main system that runs your backtest. Raw data (intraday tick data or end of day data) for instruments are sent to the trading system. At every such update of data, the trading system does the following things and then updates the state of that instrument in the system :
- Checks whether it is time to update the features and execute. It updates features at a frequency determined by trading parameters.
- If it is, it first loops over all instruments and updates the features for each instrument (specified by trading parameters). Each instrument stores its features, which can be later extracted out.
- Then, the trading system computes all the market features (specified by trading parameters). The system also stores such market features at every update features interval. An example of market feature is 'prediction' which the user needs to provide - This feaure specifies our prediction probability that the specified instrument is a buy
- Then the trading system looks at the prediction value and passes it to an execution system. This converts uses the prediction value (and current capital, risk limits etc) to decide what positions should he trading system take for various instruments.
- Trade executions generated by Execution System are then passed into the orderPlacer, which tries to place these orders into the market.
Trading System also keeps checking for confirmation of orders which are placed. It updates instrument positions for trades that are confirmed.
For trading system to work, following need to be specified:
DataSource
Emits instrument updates into the trading system. It converts any sort of data from external sources to Instrument Updates. We have a different instrument update for each type of instrument. You need to specify the instrumentID's that you need data for and start and end date for data. Current choices for datasource are:
- GoogleStockDataSource - Stock data from Google
- AuquanDataSource - Data from US stock database of 500 biggest stocks maintained by Auquan.
Benchmark
The market instrument to benchmark your strategy's perfromancy. Strategies that perform better than the benchmark are considered successful. Make sure that you specify the benchmark instrumentID in list of instruments to get data for.
Starting Capital
The initial amount of money you're putting into your trading system. This is set to 1 million notional by default.
Frequency Of Feature Updates
Frequency of updates to features. Any updates within this frequncy to instruments do not trigger feature updates. Consequently any trading decisions that need to take place happen with the same frequency This is important when you are working with frequently updating data - for example intraday tick data
PriceFeatureKey
You may have multiple measures of price for an instrument at the same time, for example open price, close price etc. Specify which price to use for pnl calculations. By default, this is set to 'close' for daily calculations.
Lookback Size
How far back do you want the historical data for your calculations. The historical market features and instrument features are only stored upto this amount. The more data you request, the slower your system will be.
InstrumentFeatures, Market Features and Custom Features
Features can be called by specifying config dictionaries. Create one dictionary per feature and return them in a dictionary as market features or instrument features. Instrument features are calculated per instrument (for example position, fees) and market features are calculated for whole trading system (for example portfolio value)
Feature config Dictionary has the following keys:
featureId: a string representing the type of feature you want to use
featureKey: {optional} a string representing the key you will use to access the value of this feature
If not present, will just use featureId
params: {optional} A dictionary with which contains other optional params if needed by the feature
Full list of features is available here.
To use your own custom features(you need to create them separately using this template, return a dictionary where
key: featureId to access this feature (Make sure this doesnt conflict with any of the pre defined feature Ids)
value: Your custom Class which computes this feature. The class should be an instance of Feature
Eg. if your custom class is MyCustomFeature, and you want to access this via featureId='my_custom_feature',
you will import that class, and return this function as {'my_custom_feature': MyCustomFeature}
Prediction Function
Combine all the features to create a prediction function which should output the probability that a given instrument is a buy. An predicted value of 1 means instrument is a guaranteed buy, 0 means a guaranteed sell and 0.5 means it's trading at fair price (neither a buy or a sell)
ExecutionSystem
Takes a prediction value and converts it into possible trades for each instrument. It takes into account current positions, risk limits, current capital and value of the prediction. Instruments with probability predictions values above enter_threshold are bought and below (1-enter_threshold) are sold. Instrument positions with probability predictions values between (1-exit_threshold) and exit_threshold are closed Current choices are:
- Simple Execution System
- Pair Execution System
OrderPlacer
It helps place an order, and also read confirmations of orders being placed. For Backtesting, you can just use the BacktestingOrderPlacer, which places the order and automatically trades at 'PriceFeatureKey' price.
Available Feature Guide
Features can be called by specifying config dictionaries. Create one dictionary per feature and return them in a dictionary as market features or instrument features. For more details and examples, check out the Prebuilt Feature page
Feature config Dictionary has the following keys:
featureId: a string representing the type of feature you want to use
featureKey: {optional} a string representing the key you will use to access the value of this feature
If not present, will just use featureId
params: {optional} A dictionary with which contains other optional params if needed by the feature
Feature ID | Parameters | Description |
---|---|---|
moving_average | 'featureName', 'period' | calculate rolling average of featureName over period |
moving_correlation | 'period', 'series1', 'series2' | calculate rolling correlation of series1 and series2 over period |
moving_max | 'featureName', 'period' | calculate rolling max of featureName over period |
moving_min | 'featureName', 'period' | calculate rolling min of featureName over period |
moving_sdev | 'featureName', 'period' | calculate moving standard deviation of featureName over period |
moving_sum | 'featureName', 'period' | calculate moving sum of featureName over period |
exponential_moving_average | 'featureName', 'period' | calculate exp. weighted moving average of featureName with period as half life |
argmax | 'featureName', 'period' | Returns the index where featureName is maximum over period |
argmin | 'featureName', 'period' | Returns the index where featureName is minimum over period |
delay | 'featureName', 'period' | Returns the value of featureName with a delay of period |
difference | 'featureName', 'period' | Returns the difference of featureName with it's value period before |
rank | 'featureName', 'period' | Ranks last period values of featureName on a scale of 0 to 1 |
scale | 'featureName', 'period', 'scale' | Resale last period values of featureName on a scale of 0 to scale |
ratio | 'featureName', 'instrumentId1', 'instrumentId2' | ratio of feature values of instrumentID1 / instrumentID2 |
momentum | 'featureName', 'period' | calculate momentum in featureName over period as featureValue(now) - featureValue(now - period) |
bollinger_bands | 'featureName', 'period' | upper and lower bollinger bands as average(period) - sdev(period), average(period) + sdev(period) |
cross_sectional_momentum | 'featureName', 'period', 'instrumentIds' | Returns Cross-Section Momentum of 'instrumentIds' in featureName over period |
macd | 'featureName', 'period1', 'period2' | moving average convergence divergence as average(period1) - average(period2) |
rsi | 'featureName', 'period' | Relative Strength Index - ratio of average profits / average losses over period |
vwap | - | calculated from book data as bid price x ask volume + ask price x bid volume / (ask volume + bid volume) |
fees | - | fees to trade, always calculated |
position | - | instrument position, always calculated |
pnl | - | Profit/Loss, always calculated |
capital | - | Spare capital not in use, always calculated |
portfolio_value | - | Total value of trading system, always calculated |