Python 3.9+
This page will guide you through the steps to backtest your strategy locally in Python 3.9+
Let us do a small backtest with our strategy locally, to ensure our algo logic is working and behaving as expected.
Preparing your main file for testing and live deployment scenarios
Once your strategy class is ready, now is the time to use it to test and deploy your strategy with Algorum. As mentioned in the Code your first strategy section, your strategy class will receive some parameters, which you need to pass in if you are testing/debugging your strategy class locally. As you can see in the below main method of your main.py file in the src sub folder of your project, we are reading those parameters from the environment variables. These environment variables will be filled in for you during the backtesting and live deployment of the strategy in Algorum Cloud. But for local testing and debugging you need to have these in the main.py file or somewhere that your main method can access.
import datetime
import os
import uuid
import AlgorumQuantClient.algorum_types
import golden_crossover_quant_strategy
if __name__ == '__main__':
if 'url' in os.environ:
url = os.environ['url']
else:
url = None
if url is None or url == '':
url = 'wss://<Your Algorum Quant Engine IP/URL>/quant/engine/api/v1'
if 'apiKey' in os.environ:
apikey = os.environ['apiKey']
else:
apikey = None
if apikey is None or apikey == '':
apikey = '<Your ALgorum API Key>'
if 'launchMode' in os.environ:
launchmode = os.environ['launchMode']
else:
launchmode = None
if launchmode is None or launchmode == '':
launchmode = AlgorumQuantClient.algorum_types.StrategyLaunchMode.Backtesting
if 'sid' in os.environ:
sid = os.environ['sid']
else:
sid = None
if sid is None or sid == '':
sid = uuid.uuid4().hex
if 'userId' in os.environ:
user_id = os.environ['userId']
else:
user_id = None
if user_id is None or user_id == '':
user_id = '<Your Alogrum User Account Id>'
if 'bkApiKey' in os.environ:
bk_api_key = os.environ['bkApiKey']
else:
bk_api_key = None
if bk_api_key is None or bk_api_key == '':
bk_api_key = '<Your Brokerage/Alpaca API Key>'
if 'bkApiSecretKey' in os.environ:
bk_api_secret_key = os.environ['bkApiSecretKey']
else:
bk_api_secret_key = None
if bk_api_secret_key is None or bk_api_secret_key == '':
bk_api_secret_key = '<Your Brokerage/Alpaca API Secret Key>'
if 'clientCode' in os.environ:
client_code = os.environ['clientCode']
else:
client_code = None
if 'password' in os.environ:
password = os.environ['password']
else:
password = None
if 'twoFactorAuth' in os.environ:
two_factor_auth = os.environ['twoFactorAuth']
else:
two_factor_auth = None
if 'brokerageCountry' in os.environ:
brokerage_country = os.environ['brokerageCountry']
else:
brokerage_country = None
if brokerage_country is None or brokerage_country == '':
brokerage_country = 'USA'
if 'samplingTime' in os.environ:
sampling_time = os.environ['samplingTime']
else:
sampling_time = 15
url += '?sid=' + sid + '&apiKey=' + apikey + '&launchMode=' + launchmode + '&brokerageCountry=' + brokerage_country
client = golden_crossover_quant_strategy.GoldenCrossoverQuantStrategy(
url,
apikey,
launchmode,
sid,
user_id
)
if 'brokeragePlatform' in os.environ:
brokerage_platform = os.environ['brokeragePlatform']
else:
brokerage_platform = None
if brokerage_platform is None or brokerage_platform == '':
brokerage_platform = AlgorumQuantClient.algorum_types.BrokeragePlatform.Alpaca
# Backtesting mode
if launchmode == AlgorumQuantClient.algorum_types.StrategyLaunchMode.Backtesting:
if 'startDate' in os.environ:
startDate = datetime.datetime.strptime(os.environ['startDate'], '%d-%m-%Y')
else:
startDate = None
if startDate is None or startDate == '':
startDate = datetime.datetime.strptime('07-04-2021', '%d-%m-%Y')
if 'endDate' in os.environ:
endDate = datetime.datetime.strptime(os.environ['endDate'], '%d-%m-%Y')
else:
endDate = None
if endDate is None or endDate == '':
endDate = datetime.datetime.strptime('09-04-2021', '%d-%m-%Y')
backtestRequest = AlgorumQuantClient.algorum_types.BacktestRequest(
startDate, endDate, sid, bk_api_key, bk_api_secret_key,
client_code, password, two_factor_auth, sampling_time, brokerage_platform)
client.backtest(backtestRequest)
else:
tradingRequest = AlgorumQuantClient.algorum_types.TradingRequest(
bk_api_key, bk_api_secret_key,
client_code, password, two_factor_auth, sampling_time, brokerage_platform)
client.start_trading(tradingRequest)
client.wait()
print('Main strategy thread exited')
Strategy Parameters
We have read about apikey, url, launchmode and sid parameters in the Code your first strategy section. The other parameters that you need for your strategy are described below.
Parameter Name | Description |
---|---|
bkApiKey | This parameter is your brokerage API key. Applies mostly to the brokerages that provide access to their API using an API Key and Secret Key mechanism. Typical example is Alpaca Brokerage users. |
bkApiSecretKey | This parameter is your brokerage API Secret key. Applies mostly to the brokerages that provide access to their API using an API Key and Secret Key mechanism. Typical example is Alpaca Brokerage users. |
clientCode | This parameter is your brokerage account user id or client code, where applicable. Typically used only for live trading for Indian users. Not applicable for Alpaca Brokerage users. |
password | This parameter is you brokerage account password, where applicable. Typically used only for live trading for Indian users. Not applicable for Alpaca Brokerage users. |
twoFactorAuth | This parameter is your brokerage account two factor authentication code, where applicable. Typically used only for live trading for Indian users. Not applicable for Alpaca Brokerage users. |
samplingTime | This parameter is the sampling time, which indicates a period in seconds. Your strategy will receive the tick data from the Algorum Cloud at the interval of the given period in seconds. So if the value of samplingTime is 1, your strategy will receive ticks accumulated for each second. If you want to receive every tick from Algorum Cloud, then set this parameter value to 0. |
brokeragePlatform | This parameter indicates the brokerage your strategy would run on. For USA users this is always Alpaca for now. For India users, this will be brokerage of the user, from the list of brokerages supported by Algorum. |
Security of your strategy parameters
We understand that your strategy parameters are sensitive and need to be protected when deploying onto the Algorum Cloud. While running your strategy locally, you can use whatever means that best suites you to secure these parameters. While deploying the strategy to Algorum cloud, you need not embed these parameters in your code or in appsettings.json file. You can pass them directly to the Algorum CLI commands (backtest or paper/live trading), which encrypts them and makes them available to your strategy while running in Algorum Cloud. None of these parameters are stored permanently in any of our databases.
Create an instance of your strategy
Once you understand about the strategy parameters, you have to now create an instance of your strategy and initialize it with required parameters, which include your Algorum Quant Engine IP, your Algorum API Key, Launch Mode and Strategy Identifier.
url += '?sid=' + sid + '&apiKey=' + apikey + '&launchMode=' + launchmode
client = golden_crossover_quant_strategy.GoldenCrossoverQuantStrategy(
url,
apikey,
launchmode,
sid
)
Backtesting locally
Once you are ready with your parameters and instantiated your strategy class, as you can see in the main method, you can initiate the backtest using QuantEngineClient backtest method, by setting your launchMode parameter to a value of backtesting in your main method. If you want to preload the indicator data, you can override the backtest method in your strategy class, and use QuantEngineClient preload_candles method. Below is how you can override the backtest method.
def backtest(self, backtest_request: AlgorumQuantClient.algorum_types.BacktestRequest):
# Preload the indicator evaluator with 200 candles
self.evaluator.preload_candles(200, backtest_request.StartDate, backtest_request.ApiKey,
backtest_request.ApiSecretKey)
AlgorumQuantClient.quant_client.QuantEngineClient.backtest(self, backtest_request)
To start the backtesting you need to pass in the BacktestRequest object with backtest date range, Api keys (for USA users), etc.,. As the backtesting starts, your strategy on_tick method will start receiving the ticks from the backtest period and you can test and debug your strategy logic accordingly.
# Backtesting mode
if launchmode == AlgorumQuantClient.algorum_types.StrategyLaunchMode.Backtesting:
if 'startDate' in os.environ:
startDate = datetime.datetime.strptime(os.environ['startDate'], '%d-%m-%Y')
else:
startDate = None
if startDate is None or startDate == '':
startDate = datetime.datetime.strptime('07-04-2021', '%d-%m-%Y')
if 'endDate' in os.environ:
endDate = datetime.datetime.strptime(os.environ['endDate'], '%d-%m-%Y')
else:
endDate = None
if endDate is None or endDate == '':
endDate = datetime.datetime.strptime('09-04-2021', '%d-%m-%Y')
backtestRequest = AlgorumQuantClient.algorum_types.BacktestRequest(
startDate, endDate, sid, bk_api_key, bk_api_secret_key,
client_code, password, two_factor_auth, sampling_time, brokerage_platform)
client.backtest(backtestRequest)
Updated almost 3 years ago