Can you help pls with an example on how to include more than one feature, such as from the fields (OHLCV)?
And also from the qnt.ta library?
I am running into a problem converting the feature set to pandas when there are more than one features.
price = data.sel(field="close").ffill('time').bfill('time').fillna(0) # fill NaN
for_result = price.to_pandas()
As optimal parameters are maximizing the chosen score function in the past, and financial data are very noisy, the usual result of parameter optimization is overfitting: the trading system works so well with past data that it becomes useless for predicting future market moves.
The problem of inflating the simulated performance of a trading system extends beyond backtest optimizers: for example, developers tend to focus and report only on positive outcomes out of all the models they try, an issue known as selection bias. For a detailed description of these problems we refer to the 2014 article by Marcos Lopez de Prado.
Nevertheless, optimizers rely on a basic functionality which can be used for testing the robustness of a trading system: a grid scan of the system over possible combinations of the parameters. The results of the scan can be used to visualize and test how much the performance of the trading system is sensitive to the parameter choice. A robust system will have a good Sharpe ratio for a wide range of the independent parameters.
Trading System Optimization with Quantiacs
You can find our optimizer in the Examples section of the Development area of your account:
Screenshot from 2021-03-16 11-04-37.png
For running the example, simply click on the Clone button and work in your favourite environment, Jupyter Notebook or JupyterLab. Alternatively you can download locally the Quantiacs toolbox and take advantage of parallelization on your own machine.
Let us analyze the code. First of all we import the needed libraries:
import qnt.data as qndata
import qnt.ta as qnta
import qnt.output as qnout
import qnt.stats as qns
import qnt.log as qnlog
import qnt.optimizer as qnop
import qnt.backtester as qnbt
import xarray as xr
In addition to the Quantiacs library, freely available at our GitHub page, we import xarray for quick processing of multi-dimensional data structures.
Next we define a simple trading rule based on two parameters. The strategy is going long only when the rate of change in the last "roc_period" trading days (in this case 10) of the linear-weighted moving average over the last "wma_period" trading days (in this case 20) is positive:
The code returns the values of the relevant statistical indicators, including the Sharpe ratio, in a table, since beginning of the in-sample period:
Screenshot from 2021-03-16 11-16-21.png
Next we run the optimization code, which performs a scan over a predefined range of parameter values: the user can choose for each parameter the starting value, the final one and the step:
data = qndata.futures.load_data(min_date='2004-01-01')
result = qnop.optimize_strategy(
wma_period=range(10, 150, 5), # min, max, step
roc_period=range(5, 100, 5) # min, max, step
workers=1 # you can set more workers on your PC
The code returns an interactive plot where one can analyze the dependence of the key statistical indicators on the parameters. In this plot we display the two independent parameters on the x and y axis, the Sharpe ratio value on he z axis and use different colors according to the maximum drawdown.
Screenshot from 2021-03-16 11-19-23.png
As a reference, we display the optimal values of the parameters which maximize the Sharpe ratio (beware of overfitting!):
Screenshot from 2021-03-16 11-20-50.png
A robust trading system will have a smooth dependence of the Sharpe ratio on the parameter values, ideally with good values larger than 1 for a wide choice of the parameters. An overfitted system will display typically a Sharpe ratio peak for a particular choice of the independent parameters.