# Translating code from Quantiacs Legacy¶

## Technical changes¶

The new version of Quantiacs addresses several issues:

it includes a private user space for developing code online and test ideas for forecasting global financial markets based on Jupyter Notebook and JupyterLab;

you can install in your private area any Python library you need for developing and submitting strategies;

you have access to historical data for futures, Bitcoin futures and cryptocurrencies;

we updated open-source libraries for algorithm development, which has become more efficient.

## Example¶

A distinctive feature of the new version of Quantiacs is the simplification of the strategy code, which became much easier to read and use. Let us consider a simple strategy based on a crossing of moving averages.

### Quantiacs Legacy¶

In **Quantiacs Legacy** you would write a function defining weights and a settings function on the following lines:

```
def myTradingSystem(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings):
nMarkets = CLOSE.shape[1]
perL = 200
perS = 40
smaLong = numpy.nansum(CLOSE[-perL:, :], axis=0) / perL
smaRecent = numpy.nansum(CLOSE[-perS:, :], axis=0) / perS
longEquity = smaRecent > smaLong
shortEquity = ~longEquity
pos = numpy.zeros(nMarkets)
pos[longEquity] = 1
pos[shortEquity] = -1
weights = pos / numpy.nansum(abs(pos))
return weights, settings
def mySettings():
settings = {}
settings['markets'] = ['CASH', 'F_AD', 'F_BO', 'F_BP', 'F_C']
settings['beginInSample'] = '20120506'
settings['endInSample'] = '20150506'
settings['lookback'] = 504
settings['budget'] = 10 ** 6
settings['slippage'] = 0.05
return settings
if __name__ == '__main__':
import quantiacsToolbox
results = quantiacsToolbox.runts(__file__)
```

### Quantiacs: Single-Pass Mode¶

A similar logic in the new **Quantiacs** can be implemented using the following compact **single-pass implementation**. By **single-pass implementation** we mean an implementation where the **complete** time series of data is constantly accessible at any step of the evaluation:

```
import xarray as xr
import qnt.ta as qnta
import qnt.data as qndata
import qnt.output as qnout
data = qndata.futures_load_data(
assets=["F_AD", "F_BO", "F_BP", "F_C"],
min_date="2006-01-01")
close = data.sel(field="close")
sma_long = qnta.sma(close, 200)
sma_short = qnta.sma(close, 40)
weights = xr.where(sma_short > sma_long, 1, -1)
weights = weights / abs(weights).sum("asset")
weights = qnout.clean(weights, data, "futures")
qnout.check(weights, data, "futures")
qnout.write(weights)
```

The single-pass implementation is very fast because it uses fast bulk operations on the full time series. On the other hand, it is possible that implicit looking-forward is taking place. To verify the results of your single-pass strategy you can use the file **precheck.ipynb** (in the root directory of your strategy) and read the warnings.

### Quantiacs: Multi-Pass Mode¶

As an alternative, you can use the function **qnt.backtester.backtest** and perform a slower multi-pass simulation which is looking-forward free. Note that we will check your In-Sample Sharpe ratio at submission time using a multi-pass implementation which will reveal looking-forward issues.

This is an example of **multi-pass implementation** where at timestamp “t” only data until timestamp “t” are available by construction:

```
import xarray as xr
import qnt.ta as qnta
import qnt.backtester as qnbt
import qnt.data as qndata
def load_data(period):
return qndata.futures_load_data(
assets=["F_AD", "F_BO", "F_BP", "F_C"],
tail=period)
def strategy(data):
close = data.sel(field="close")
sma_long = qnta.sma(close, 200).isel(time=-1)
sma_short = qnta.sma(close, 40).isel(time=-1)
pos = xr.where(sma_short > sma_long, 1, -1)
return pos / abs(pos).sum("asset")
weights = qnbt.backtest(
competition_type = "futures",
load_data = load_data,
lookback_period = 365,
test_period = 365 * 15,
strategy = strategy)
```

Here we have used the function **qnt.backtester.backtest** whose details can be found in your private area in the **/qnt/backtester.py** file.

The function requires the following input:

**competition type**: “futures” for the futures contest or “cryptofutures” for the Bitcoin futures contest;**load data**: the pre-defined**load_data**function. The**period**passed to**load_data**is given by**test_period + lookback_period**;**lookback_period**: the maximal lookback period in calendar days used for building indicators. In this case, as we use 200 trading days for defining the largest simple moving average, 1 year is fine;**test_period**, in calendar days, is the In-Sample period used for the simulation. Here we use 15 years of data;**strategy**: the pre-defined**strategy**function which should return allocation weights for all assets at a fixed point in time (note that in**strategy**we select the last index, isel(time=-1)).

The function returns the time series **weights** for all assets. It performs automatically the last 3 operations of the **single-pass** evaluation:

```
weights = qnout.clean(weights, data, "futures")
qnout.check(weights, data, "futures")
qnout.write(weights)
```