13. Estrategia de comercio de red

Fuente de referencia: docs/_joinquant_migration_source/Example_13_classic grid trading.ipynb Primera celda de Markdown.

Esta estrategia es una estrategia clásica de comercio en red. La estrategia se ejecuta en la acción 000651.SZ Gree Electric. Cuando la estrategia se ejecuta por primera vez, compra 1000 acciones y las conserva. Al mismo tiempo, el precio de compra actual (redondeado a 0,1 yuanes) se establece como cuadrícula de referencia, y las cuadrículas de venta y compra se calculan de acuerdo con el tamaño de la cuadrícula. A continuación, la estrategia se ejecuta cada 5 minutos. Cuando el precio de las acciones toca la cuadrícula de compra o de venta, se genera una señal comercial y la cuadrícula se actualiza:

Por ejemplo:

  • Supongamos que la cuadrícula de referencia actual es de 30 yuanes, el tamaño de la cuadrícula es de 0,5 yuanes, la cuadrícula de venta es de 30,5 yuanes y la cuadrícula de compra es de 29,5 yuanes.

  • Cuando el precio toca la cuadrícula de venta de 30,5 yuanes, se genera una señal de venta, se venden 200 acciones y la cuadrícula de referencia se actualiza a 30,5 yuanes. Al mismo tiempo, se calcula la nueva cuadrícula de venta de 31 yuanes y la cuadrícula de compra de 30 yuanes.

Objetivo de backtesting: 000651.SZ Gree Electric

Período de backtesting: 1 de enero de 2023 al 1 de marzo de 2023

Tenga en cuenta que, dado que los parámetros de la cuadrícula de la estrategia se actualizarán después de cada operación, esta estrategia solo se puede probar de forma gradual. Para facilitar la generación de señales comerciales, la estrategia utiliza el tipo de señal VS

import qteasy as qt
import pandas as pd
import numpy as np
from qteasy import Parameter, StgData


class GridTrade(qt.RuleIterator):

    def __init__(self):
        super().__init__(
            name='GridTrade',
            description='网格交易策略,价格触发网格后交易并更新基准网格',
            pars=[
                Parameter((0.2, 2.0), name='grid_size', par_type='float', value=0.5),
                Parameter((100, 1000), name='trade_batch', par_type='int', value=200),
                Parameter((0.0, 10000.0), name='base_grid', par_type='float', value=0.0),
            ],
            data_types=StgData('close', freq='5min', asset_type='ANY', window_length=60),
            use_latest_data_cycle=False,
        )

    def realize(self):

        # 读取当前保存的策略参数,首次运行时base_grid参数为0,此时买入1000股并设置当前价格为基准网格
        grid_size, trade_batch, base_grid = self.get_pars('grid_size', 'trade_batch', 'base_grid')

        # 读取最新价格
        price = self.get_data('close_ANY_5min')[-1]

        # 计算当前价格与当前网格的偏离程度,判断是否产生交易信号
        if base_grid <= 0.01:
            # 基准网格尚未设置,此时为首次运行,首次买入1000股并设置基准网格为当前价格(精确到0.1元)
            result = float(trade_batch * 5)
            base_grid = np.round(price / 0.1) * 0.1
        elif price - base_grid > grid_size:
            # 触及卖出网格线,产生卖出信号
            result = -float(trade_batch)  # 交易信号等于交易数量,必须使用VS信号类型
            # 重新计算基准网格
            base_grid += grid_size
        elif base_grid - price > grid_size:
            # 触及买入网格线,产生买入信号
            result = float(trade_batch)
            # 重新计算基准网格
            base_grid -= grid_size
        else:
            result = 0.0

        # 使用新的基准网格更新交易参数
        self.par_values = (grid_size, trade_batch, base_grid)

        return result

alpha = GridTrade()

op = qt.Operator(alpha, signal_type='VS')  # 交易信号等于交易数量,必须使用VS信号类型
op.op_type = 'stepwise'  # 需要动态更新策略参数,必须使用'stepwise'交易类型
res = qt.run(op, mode=1,
       asset_type='E',
       asset_pool='000651.SZ',
       benchmark_asset='000651.SZ',
       trade_batch_size=100,
       sell_batch_size=1,
       trade_log=True,
       invest_start='20230101',
       invest_end='20230301',
       backtest_price_adj='none',
      )
print()

Los resultados del backtest son los siguientes:

     ====================================
     |                                  |
     |       BACK TESTING RESULT        |
     |                                  |
     ====================================

qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 0.0 ms
time consumption for operation back looping:  839.9 ms

investment starts on      2023-01-03 09:30:00
ends on                   2023-02-28 15:00:00
Total looped periods:     0.2 years.

-------------operation summary:------------
Only non-empty shares are displayed, call 
"loop_result["oper_count"]" for complete operation summary

          Sell Cnt Buy Cnt Total Long pct Short pct Empty pct
000651.SZ    13       8      21   93.0%      0.0%      7.0%   

Total operation fee:     ¥       63.36
total investment amount: ¥  100,000.00
final value:              ¥  104,070.64
Total return:                      inf% 
Avg Yearly return:                 inf%
Skewness:                          3.79
Kurtosis:                         52.19
Benchmark return:                 9.23% 
Benchmark Yearly return:         77.74%

------strategy loop_results indicators------ 
alpha:                              inf
Beta:                               inf
Sharp ratio:                       -inf
Info ratio:                       0.005
250 day volatility:               0.003
Max drawdown:                     0.80% 
    peak / valley:        2023-01-30 / 2023-02-06
    recovered on:         2023-02-20

===========END OF REPORT=============

png