8. Utilice estrategias integradas

qteasy es un conjunto de herramientas de análisis comercial cuantitativo para implementación y operación totalmente localizado, con las siguientes funciones:

  • Acceda, limpie, almacene, procese, visualice y utilice datos financieros

  • Cree estrategias comerciales cuantitativas y proporcione una gran cantidad de estrategias comerciales básicas integradas.

  • Backtesting de estrategias comerciales vectorizadas de alta velocidad y evaluación de resultados comerciales

  • Optimización y evaluación de parámetros de estrategia comercial.

  • Implementación y operación en vivo de estrategias comerciales.

Con esta serie de tutoriales, comprenderá completamente las funciones principales y el uso de qteasy a través de una serie de ejemplos prácticos.

8.1. Antes de empezar

Antes de comenzar este tutorial, asegúrese de dominar lo siguiente:

  • Instale y configure qteasy —— detalles, consulte QTEASY tutorial 1

  • Se ha configurado una fuente de datos local y ya se han descargado localmente suficientes datos históricos (incluido el calendario de operaciones; información básica sobre acciones/fondos/índices; datos de precios de acciones/fondos/índices; e indicadores financieros u otros datos financieros; consulte QTEASY Tutorial 2 para obtener más detalles).

  • Aprenda a crear un objeto comercial, utilice una estrategia comercial incorporada y realice una prueba retrospectiva de su rendimiento histórico, consulte el registro de prueba retrospectiva, comprenda cómo ajustar los parámetros en ejecución o los parámetros ajustables de la estrategia y mejore el rendimiento de la estrategia —— QTEASY tutorial 3

En la QTEASY documentación, también puede encontrar más contenido sobre cómo crear un objeto comercial para ejecutar estrategias, realizar pruebas retrospectivas de estrategias utilizando datos históricos, revisar registros comerciales de pruebas retrospectivas, modificar estrategias, etc. Si aún no está familiarizado con el uso básico de qteasy, puede ir allí para obtener explicaciones más detalladas.

8.2. Objetivo de este capítulo

En la sección del tutorial anterior, creamos un objeto comercial Operator y le hicimos ejecutar la primera estrategia comercial de selección de acciones. Sin embargo, en qteasy, un operador es capaz de hacer mucho más que simplemente ejecutar una única estrategia comercial. De hecho, el objeto Operator es como un operador real: puede gestionar y ejecutar simultáneamente cualquier número de estrategias comerciales. Estas estrategias pueden ejecutarse por separado en diferentes momentos y frecuencias, o muchas pueden ejecutarse juntas en un lote; y las estrategias que se ejecutan al mismo tiempo también se pueden “combinar” de cualquier manera especificada en la forma deseada.

Puedes imaginar a un comerciante como un pintor que sostiene una paleta con pinturas de diferentes colores. Pueden usar diferentes colores para dibujar líneas vívidas o mezclar varios colores para crear tonos de transición suaves. De esta manera, incluso si el pintor tiene sólo un puñado de pinturas, su pincel aún puede mezclar millones de colores que componen el vasto mundo.

Este es exactamente uno de los conceptos de diseño clave de qteasy: utilizando las dos herramientas siguientes, el objeto comercial Operator puede combinar y configurar estrategias comerciales muy simples en estrategias comerciales muy complejas, permitiendo así una funcionalidad compleja. Estas dos herramientas incluyen:

  • Grupo de estrategias: los operadores pueden ejecutar múltiples estrategias en grupos. Cada grupo de estrategias comerciales comparte la misma frecuencia de ejecución (por ejemplo, diaria, cada hora o cada minuto) y el mismo tiempo de ejecución (por ejemplo, al cierre diario o a las 10:30 todos los días), lo que permite un control flexible sobre cuándo se ejecutan las estrategias.

  • Mezclador de estrategias de Blender: las estrategias comerciales que se ejecutan simultáneamente dentro del mismo grupo necesariamente se ejecutarán al mismo tiempo. Cada estrategia generará un conjunto de señales comerciales de acuerdo con su propia lógica, pero este conjunto de señales debe «fusionarse» en un solo conjunto de alguna manera. Esta fusión la realiza el mezclador blender, que es específicamente responsable de combinar las señales comerciales generadas por múltiples estrategias en un solo conjunto. La lógica de fusión está completamente determinada por la cadena de composición blender string definida por el usuario, lo que le otorga al usuario control total.

En este capítulo, aprenderemos cómo usar más estrategias integradas en qteasy, cómo hacer que un operador ejecute múltiples estrategias comerciales al mismo tiempo y cómo usar el mezclador de estrategias blender para generar diferentes estrategias combinadas usando estrategias comerciales.

Actualmente, qteasy admite más de 70 estrategias comerciales integradas, todas las cuales están listas para usar. Para obtener una lista completa de las estrategias comerciales integradas, consulte los documentos de referencia:

Puede utilizar la API a continuación para obtener una lista de todas las estrategias comerciales integradas proporcionadas en qteasy:

import qteasy as qt
qt.built_ins()

La API anterior devolverá todas las estrategias comerciales integradas en qteasy:

{'crossline': qteasy.built_in.CROSSLINE,
 'macd': qteasy.built_in.MACD,
 'dma': qteasy.built_in.DMA,
 'trix': qteasy.built_in.TRIX,
 'cdl': qteasy.built_in.CDL,
 'bband': qteasy.built_in.BBand,
 's-bband': qteasy.built_in.SoftBBand,
 'sarext': qteasy.built_in.SAREXT,
 'ssma': qteasy.built_in.SCRSSMA,
 'sdema': qteasy.built_in.SCRSDEMA,
 'sema': qteasy.built_in.SCRSEMA,
 'sht': qteasy.built_in.SCRSHT,
 'skama': qteasy.built_in.SCRSKAMA,
 'smama': qteasy.built_in.SCRSMAMA,
 ...}

La siguiente lista enumera algunas de las estrategias comerciales integradas que están listas para usar en qteasy. Para obtener una lista completa, consulte documentos de referencia

ID

Nombre de la estrategia

Nota

crossline

TimingCrossline

Clase de estrategia de sincronización de líneas cruzadas, que utiliza el cruce de promedios móviles largos y cortos para determinar los estados largos y cortos
1. Cuando la media móvil corta está por encima de la media móvil larga y la distancia es mayor que l*m%, establezca la posición objetivo en 1
2. Cuando la media móvil corta está por debajo de la media móvil larga y la distancia es mayor que l*m%, establezca la posición objetivo en -1
3. Cuando la distancia entre las medias móviles largas y cortas no sea mayor que l*m%, establezca la posición objetivo en 0

macd

TimingMACD

Clase de estrategia de sincronización MACD, que utiliza la estrategia de media móvil MACD para generar el porcentaje de posición objetivo:
1. Cuando el valor MACD es mayor que 0, establezca la posición objetivo en 1
2. Cuando el valor MACD es inferior a 0, establezca la posición objetivo en 0

dma

TimingDMA

Estrategia de sincronización DMA
1. Cuando DMA está por encima de AMA, es un intervalo largo, es decir, después de que la línea DMA cruza la línea AMA de abajo hacia arriba, la salida es 1
2. Cuando DMA está por debajo de AMA, es un intervalo corto, es decir, después de que la línea DMA cruza la línea AMA de arriba a abajo, la salida es 0

trix

TimingTRIX

Estrategia de sincronización TRIX, utilizando el precio promedio móvil exponencial triple suavizado del precio de las acciones para juicios largos y cortos:
Calcule el precio promedio móvil exponencial triple suavizado TRIX del precio y luego calcule el promedio móvil del TRIX del día M:
1. Cuando TRIX está por encima de MATRIX, establezca la posición objetivo en 1
2. Cuando TRIX está por debajo de MATRIX, establezca la posición objetivo en -1

cdl

TimingCDL

Estrategia de sincronización CDL, encuentre el patrón cdldoji que cumpla con los requisitos en el gráfico de líneas K
Busque el patrón cdldoji que aparece en la ventana de datos históricos (entre 0 y 100), resúmalo/100, calcule la cantidad equivalente de cdldoji y use la cantidad coincidente como señal comercial.

bband

TimingBBand

Estrategia comercial de Bollinger Band, determine posiciones largas y cortas en función de la relación entre los precios de las acciones y las bandas superior e inferior de Bollinger Band, y genere señales comerciales cuando los precios crucen por encima o por debajo de las líneas de Bollinger Band. No se puede seleccionar el tipo de media móvil de la línea Banda de Bollinger
1. Cuando el precio cruza por encima de la banda superior, se genera una señal de compra de posición completa
2. Cuando el precio cruza por debajo de la banda inferior, se genera una señal de venta de posición completa.

s-bband

SoftBBand

La estrategia de negociación progresiva de las Bandas de Bollinger determina las posiciones largas y cortas en función de la relación entre los precios de las acciones y las bandas superior e inferior de las Bandas de Bollinger, y las señales comerciales no se generan todas a la vez, sino que se compran y venden gradualmente. Calcule BBAND, verifique si el precio excede la banda superior o inferior de BBAND:
1. Después de que el precio es mayor que la banda superior, se genera una señal de compra proporcional del 10% todos los días
2. Después de que el precio es inferior a la banda inferior, se genera una señal de venta proporcional del 33% todos los días.

sarext

TimingSAREXT

Estrategia SAR Parabólica extendida: la señal de compra se emite cuando el índice es mayor que 0 y la señal de venta se emite cuando el índice es menor que 0.

ssma

SCRSSMA

Estrategia cruzada de media móvil única —— Media móvil SMA (media móvil simple): establece el índice de posición de acuerdo con la posición relativa del precio de las acciones y la media móvil SMA

sdema

SCRSDEMA

Estrategia cruzada de media móvil única —— Media móvil DEMA (media móvil de suavizado exponencial doble): establece el índice de posición de acuerdo con la posición relativa del precio de las acciones y la media móvil DEMA

sema

SCRSEMA

Estrategia cruzada de media móvil única —— Media móvil EMA (media móvil de suavizado exponencial): establece el índice de posición de acuerdo con la posición relativa del precio de las acciones y la media móvil EMA

Lista completa de estrategias integradas, consulte documentos de referencia

Cada estrategia comercial integrada tiene su propio ID (por ejemplo, crossline, macd, dma, etc. en la tabla anterior). Los usuarios pueden utilizar este ID para obtener una instancia de una estrategia comercial integrada y agregarla a un objeto comercial para su uso. Por ejemplo:

stg = qt.get_built_in_strategy('dma')
stg.info()

Salida obtenida:

================================ Strategy: DMA =================================
Strategy RULE-ITER(DMA)
Parameters: ['slow', 'long', 'diff'] = (12, 26, 9)                  
Date Types: close_ANY_d x 270                                       
----------------------------- Iteration Properties -----------------------------
Allow multi pars        True
Multi-parameter not set                      

Si necesita ver una explicación detallada de cada estrategia comercial incorporada, como el significado de los parámetros de la estrategia y las reglas de generación de señales, puede ver el doc-string de cada estrategia comercial:

Por ejemplo:

qt.built_in_doc('Crossline', print_out=True)

puedes ver

Init signature: qt.built_in.TimingCrossline(pars:tuple=(35, 120, 0.02))
Docstring:     
crossline择时策略类,利用长短均线的交叉确定多空状态

策略参数:
    s: int, 短均线计算日期;
    l: int, 长均线计算日期;
    m: float, 均线边界宽度(百分比);
信号类型:
    PT型:目标仓位百分比
信号规则:
    1,当短均线位于长均线上方,且距离大于l*m%时,设置仓位目标为1
    2,当短均线位于长均线下方,且距离大于l*mM时,设置仓位目标为-1
    3,当长短均线之间的距离不大于l*m%时,设置仓位目标为0

策略属性缺省值:
默认参数:(35, 120, 0.02)
数据类型:close 收盘价,单数据输入
采样频率:天
窗口长度:270
参数范围:[(10, 250), (10, 250), (0, 1)]
策略不支持参考数据,不支持交易数据
File:           ~/Library/CloudStorage/OneDrive-Personal/Projects/PycharmProjects/qteasy/qteasy/built_in.py
Type:           type
Subclasses:     

En entornos interactivos python como ipython, también puede utilizar ? para mostrar información detallada sobre estrategias comerciales integradas, por ejemplo:

>>> qt.built_in.SelectingNDayRateChange?

Puedes ver:

Init signature: qt.built_in.SelectingNDayRateChange(pars=(14,))
Docstring:     
基础选股策略:根据股票以前n天的股价变动比例作为选股因子

策略参数:
    n: int, 股票历史数据的选择期
信号类型:
    PT型:百分比持仓比例信号
信号规则:
    在每个选股周期使用以前n天的股价变动比例作为选股因子进行选股
    通过以下策略属性控制选股方法:
    *max_sel_count:     float,  选股限额,表示最多选出的股票的数量,默认值:0.5,表示选中50%的股票
    *condition:         str ,   确定股票的筛选条件,默认值'any'
                                'any'        :默认值,选择所有可用股票
                                'greater'    :筛选出因子大于ubound的股票
                                'less'       :筛选出因子小于lbound的股票
                                'between'    :筛选出因子介于lbound与ubound之间的股票
                                'not_between':筛选出因子不在lbound与ubound之间的股票
    *lbound:            float,  执行条件筛选时的指标下界, 默认值np.-inf
    *ubound:            float,  执行条件筛选时的指标上界, 默认值np.inf
    *sort_ascending:    bool,   排序方法,默认值: False,
                                True: 优先选择因子最小的股票,
                                False, 优先选择因子最大的股票
    *weighting:         str ,   确定如何分配选中股票的权重
                                默认值: 'even'
                                'even'       :所有被选中的股票都获得同样的权重
                                'linear'     :权重根据因子排序线性分配
                                'distance'   :股票的权重与他们的指标与最低之间的差值(距离)成比例
                                'proportion' :权重与股票的因子分值成正比

策略属性缺省值:
默认参数:(14,)
数据类型:close 收盘价,单数据输入
采样频率:月
窗口长度:150
参数范围:[(2, 150)]
策略不支持参考数据,不支持交易数据
File:           ~/Library/CloudStorage/OneDrive-Personal/Projects/PycharmProjects/qteasy/qteasy/built_in.py
Type:           type
Subclasses:    

8.3. Combinación de múltiples estrategias

En qteasy, un objeto comercial Operator puede ejecutar cualquier número de estrategias comerciales en grupos al mismo tiempo. Cuando se ejecuta, cada una de estas estrategias recupera por separado los datos históricos que necesita y genera de forma independiente diferentes señales comerciales. Luego, estas señales se combinan en un conjunto de señales comerciales y se ejecutan de manera unificada.

Los usuarios pueden utilizar esta función para ejecutar múltiples estrategias comerciales con diferentes enfoques en un objeto comercial al mismo tiempo. Por ejemplo, una estrategia comercial monitorea el precio de las acciones individuales y genera señales de selección basadas en el precio de las acciones, la segunda estrategia comercial es específicamente responsable de monitorear la tendencia del mercado en general y determina la posición general en función de la tendencia del mercado en general. La tercera estrategia comercial es específicamente responsable de detener las pérdidas y detener las ganancias, y detiene las pérdidas en momentos específicos. La señal comercial final se basa principalmente en la primera estrategia comercial, pero está restringida por la segunda estrategia y, cuando sea necesario, estará completamente controlada por la tercera estrategia.

O bien, los usuarios pueden formular fácilmente una estrategia de «comité», en la que múltiples estrategias toman decisiones comerciales de forma independiente en una estrategia integral, y la señal comercial final se determina mediante el voto del «comité» compuesto por todas las subestrategias. El método de votación puede ser mayoría simple, mayoría absoluta, resultados de votación ponderados, etc.

En las estrategias comerciales combinadas anteriores, cada estrategia comercial individual es muy simple y fácil de definir, pero combinarlas puede producir un efecto mayor. Al mismo tiempo, cada subestrategia es independiente y puede combinarse libremente en estrategias comerciales complejas e integrales. Esto evita desarrollar repetidamente estrategias desde cero: solo necesita reorganizar y recombinar las subestrategias y redefinir cómo se combinan para construir rápidamente una serie de estrategias comerciales complejas e integrales. Esto puede mejorar en gran medida la eficiencia de la creación de estrategias comerciales y acortar el ciclo. El tiempo es dinero.

Mezclar señales comerciales se refiere a realizar varias operaciones o funciones en señales comerciales. Esto puede variar desde operaciones lógicas simples y sumas/restas hasta funciones personalizadas complejas. Cualquier función que se pueda aplicar a un ndarray se puede utilizar para mezclar señales comerciales, siempre que la señal comercial de salida final sea significativa.

Definir el método de combinación de estrategias blender

En un objeto comercial Operator, todas las estrategias comerciales deben asignarse a un grupo de estrategias. Si hay más de una estrategia en un grupo, se debe definir un ⟦CÓDIGO1⟧. Si no se define explícitamente ningún blender y el número de estrategias excede 1, qteasy creará un blender predeterminado al ejecutar el Operator. Sin embargo, para que las configuraciones de múltiples estrategias se ejecuten correctamente, los usuarios deben definir el blender ellos mismos.

blender_str es una expresión combinada definida por el usuario. Los usuarios utilizan esta expresión para determinar cómo se combinan las diferentes estrategias comerciales. Esta expresión combinada utiliza operadores aritméticos, operadores lógicos, funciones y otros símbolos para especificar cómo se combinan las señales estratégicas. La expresión blender puede incluir los siguientes elementos:

Los símbolos admitidos en la expresión blender son los siguientes:

Elemento

Ejemplo

Nota

Número de estrategia

s0, s1...

Una cadena que comienza con s y termina con un número. El número es el índice de la estrategia en Group y representa la señal comercial generada por esa estrategia.

Números

-1.35

Cualquier número legal, el número involucrado en la operación de expresión.

Operadores

+

Operadores numéricos incluido + - * / ^

Operadores lógicos

and

Se admiten operadores lógicos como &/~ y and/or/not

Funciones

sum()

Las funciones admitidas se pueden ver en la siguiente tabla

Paréntesis

()

Operación grupal

Ejemplo de blender

Si hay tres estrategias comerciales en un objeto Operator (con números de serie s0/s1/s2), el blender definido de las siguientes maneras es legal y está disponible, y use Operator.set_blender() para configurar el blender:

Expresión de Blender definida mediante operadores aritméticos

's0 + s1 + s2'

En este caso, las señales comerciales generadas por las tres estrategias comerciales se sumarán para convertirse en la señal comercial final. Si el resultado de la estrategia 0 es comprar el 10%, el resultado de la estrategia 1 es comprar el 10% y el resultado de la estrategia 2 es comprar el 30%, entonces el resultado final es comprar el 50%.

Expresión de Blender definida mediante operadores lógicos:

's0 and s1 and s2'

En este caso, la señal comercial final solo se formará cuando las estrategias comerciales 1, 2 y 3 generen señales comerciales. Por ejemplo, si el resultado de la estrategia 1 es comprar, el resultado de la estrategia 2 es comprar y la estrategia 3 no tiene señal comercial, entonces el resultado final no es ninguna señal comercial.

Las expresiones de Blender también pueden incluir paréntesis y algunas funciones:

'max(s0, s1) + s2'

Es decir, la suma del valor máximo de los resultados de las estrategias 1 y 2 y el resultado de la estrategia 3 se convierte en la señal comercial final. Si el resultado de la estrategia 1 es comprar el 10%, el resultado de la estrategia 2 es comprar el 20% y el resultado de la estrategia 3 es comprar el 30%, el resultado final es comprar el 50%

Una estrategia puede aparecer más de una vez en la expresión de Blender y también se admiten números puros:

'(0.5 * s0 + 1.0 * s1 + 1.5 * s2) / 3 * min(s0, s1, s2)'

La expresión anterior blender significa: primero calcule el promedio ponderado de las tres señales de la estrategia (los pesos son 0,5, 1,0, 1,5 respectivamente) y luego multiplíquelo por el valor mínimo de las tres señales.

Los parámetros de función en la expresión de Blender se definen en el nombre de la función:

'clip_-0.5_0.5(s0 + s1 + s2) + pos_2_0.2(s0, s1, s2)'

La expresión anterior blender define dos operaciones de función diferentes y el resultado final se obtiene sumando los resultados. La primera función es el recorte de rango, después de sumar los tres conjuntos de señales de estrategia, los valores de señal menores que -0,5 y mayores que 0,5 se recortan y se obtiene el resultado del cálculo; la segunda función es la función de juicio de posición, que cuenta los períodos de tiempo en los tres conjuntos de señales con una posición superior a 0,2, las define como «posiciones largas» y luego cuenta el número de recomendaciones de posiciones largas en las tres estrategias en cada período de tiempo. Si más de dos estrategias contienen recomendaciones de posiciones largas, se genera la posición larga completa; de lo contrario, se genera la posición vacía.

Las siguientes funciones son compatibles con la expresión blender:

Funciones

Ejemplo de expresión

Nota

abs

abs(s0)

Función de valor absoluto
Calcula el valor absoluto de todas las señales comerciales
Solo se puede ingresar una señal comercial

avg

avg(s0, s1, ...)

Función de valor promedio
Calcular el valor promedio de todas las señales comerciales
El número de señales de entrada es ilimitado

avgpos

avgpos_N_T(s0, s1, ...)

Función acumulativa promedio
Cuando la señal comercial es una señal de posición objetivo, cuente el número de señales de posición no vacías (valor absoluto de la señal de salida > T) generadas al mismo tiempo. Cuando el número de señales cortas/largas es mayor que N, genera el valor promedio de todas las señales cortas/largas; de lo contrario, genera 0.
El número de señales de entrada es ilimitado

ceil

ceil(s0)

Función de techo
Redondeo de señales comerciales hacia arriba
Solo se puede ingresar una señal comercial

clip

clip_U_L(s0)

Función de recorte
Recorte el valor de la señal que excede el rango y defina los rangos superior e inferior en el nombre de la función
Solo se puede ingresar una señal comercial

combo

combo(s0, s1, ...)

Función de valor combinado
Emite la suma de todas las señales comerciales
El número de señales de entrada es ilimitado

committee

cmt_N_T(s0, s1, ...)

Función de comité (equivalente a la función de posición acumulativa pos))
Cuando la señal comercial es una señal de posición objetivo, cuente cuántas señales de posición no vacías (valor absoluto de la señal de salida > T) se generan al mismo tiempo. Cuando el número de señales largas/cortas es mayor que N, genera -1/1; de lo contrario, salida 0.
El número de señales de entrada es ilimitado

exp

exp(s0)

Función exp
Calcular la potencia de la señal de e
Solo se puede ingresar una señal comercial

floor

floor(s0)

Función de piso
Señal comercial redondeando hacia abajo
Solo se puede ingresar una señal comercial

log

log(s0)

Función logaritmo
Calcule el valor del logaritmo con e como base
Solo se puede ingresar una señal comercial

log10

log10(s0)

Función de logaritmo basada en 10
Calcule el valor del logaritmo con 10 como base
Solo se puede ingresar una señal comercial

max

max(s0, s1, ...)

Función de valor máximo
Calcule el valor máximo de todas las señales comerciales
El número de señales de entrada es ilimitado

min

min(s0, s1, ...)

Función de valor mínimo
Calcular el valor mínimo de todas las señales comerciales
El número de señales de entrada es ilimitado

pos

pos_N_T(s0, s1, ...)

Función de posición acumulada
Cuando la señal comercial es una señal de posición objetivo, cuente el número de señales de posición no vacías (valor absoluto de la señal de salida > T) generadas al mismo tiempo. Cuando el número de señales largas/cortas es mayor que N, genera -1/1, de lo contrario genera 0.
El número de señales de entrada es ilimitado

position

position_N_T(s0, s1, ...)

Función de posición acumulada
Cuando la señal comercial es una señal de posición objetivo, cuente el número de señales de posición no vacías (valor absoluto de la señal de salida > T) generadas al mismo tiempo. Cuando el número de señales largas/cortas es mayor que N, genera -1/1, de lo contrario genera 0.
El número de señales de entrada es ilimitado

pow

pow(s0, s1)

Función de potencia
Calcule la potencia de la segunda señal de la primera señal comercial, es decir, sig0^sig1
El número de señales de entrada solo puede ser dos

power

power(s0, s1)

Función de potencia
Calcule la potencia de la segunda señal de la primera señal comercial, es decir, sig0^sig1
El número de señales de entrada solo puede ser dos

sqrt

sqrt(s0)

Función de raíz cuadrada
Raíz cuadrada de la señal comercial
Solo se puede ingresar una señal comercial

str

str_T(s0, s1, ...)

Función acumulativa de fuerza
Suma todas las señales comerciales, genera 1 cuando la intensidad de la señal excede T, de lo contrario genera 0
El número de señales de entrada es ilimitado

strength

strength_T(s0, s1, ...)

Función acumulativa de fuerza
Suma todas las señales comerciales, genera 1 cuando la intensidad de la señal excede T, de lo contrario genera 0
El número de señales de entrada es ilimitado

sum

sum(s0, s1, ...)

Función de valor combinado
Emite la suma de todas las señales comerciales
El número de señales de entrada es ilimitado

unify

unify(s0)

Función uniforme
Normaliza las señales comerciales, escala las señales comerciales en la misma fila proporcionalmente para que la suma de cada fila sea 1
Solo se puede ingresar una señal comercial

vote

vote_N_T(s0, s1, ...)

Función de voto (equivalente a la función de posición acumulativa)
Cuando la señal comercial es una señal de posición objetivo, cuente el número de señales de posición no vacías (señal de salida valor absoluto > T) generadas al mismo tiempo. Cuando el número de señales largas/cortas es mayor que N, genera -1/1, de lo contrario genera 0.
El número de señales de entrada es ilimitado

Se pueden utilizar los siguientes métodos para configurar u obtener el blender de la estrategia

operator.set_blender(blender_str=None, group_id=None)

Para configurar el blender, pase una expresión blender_str directamente. Esta expresión se analizará y utilizará automáticamente para combinar estrategias comerciales. Al usar set_blender(), puede usar el parámetro group_id para especificar para qué grupo de estrategias es este blender. Si no se especifica group_id, este blender se utiliza para todos los grupos de estrategias de forma predeterminada.

operator.view_blender()

Vea el blender. Tenga en cuenta que, para facilitar la lectura, los códigos de estrategia s0, s1 y s2 en la expresión de Blender se reemplazarán automáticamente con los ID de estrategia específicos, como se muestra en el siguiente ejemplo:

>>> op = qt.Operator('dma, macd, trix')
>>> op.set_blender('(0.5 * s0 + 1.0 * s1 + 1.5 * s2) / 3 * min(s0, s1, s2)', group_id='Group_1')
>>> op.view_blender()

operator.view_blender() genera un diccionario donde las claves son ID de grupos de estrategias y los valores son expresiones de Blender. En la expresión de Blender, s0, s1 y s2 ya han sido reemplazados con los ID de estrategia específicos:

El resultado es el siguiente:

{'Group_1': '(0.5 * dma + 1.0 * macd + 1.5 * trix) / 3 * min(dma, macd, trix)'}

Si especifica el parámetro group_id al llamar a view_blender(), solo generará la expresión de Blender para ese grupo de estrategias:

>>> op.view_blender(group_id='Group_1')

El resultado es el siguiente:

'(0.5 * dma + 1.0 * macd+ 1.5 * trix) / 3 * min(dma, macd, trix)'

El ejemplo anterior s0,s1,s2 se reemplaza por dma, macd, trix, pero si Operator contiene varias estrategias idénticas, se les asignarán automáticamente diferentes ID de estrategia para distinguirlas:

>>> op = qt.Operator('dma, dma, dma')
>>> op.set_blender('(0.5 * s0 + 1.0 * s1 + 1.5 * s2) / 3 * min(s0, s1, s2)')
>>> op.view_blender('Group_1')

El resultado es el siguiente:

'(0.5 * dma_0 + 1.0 * dma_1 + 1.5 * dma_2) / 3 * min(dma_0, dma_1, dma_2)'

Ejemplo de uso de blender

A continuación se utiliza un ejemplo para demostrar cómo funciona blender:

Generamos un objeto comercial y ejecutamos cinco estrategias comerciales DMA al mismo tiempo, pero las cinco estrategias comerciales tienen diferentes parámetros ajustables. En este momento, podemos entender que el comerciante ejecuta cinco lógicas comerciales iguales al mismo tiempo, pero estas cinco lógicas comerciales están configuradas con diferentes parámetros, por lo que bajo las mismas condiciones de entrada, se generan diferentes señales comerciales, lo que significa que las cinco estrategias comerciales tienen su propio énfasis, algunas son buenas para capturar variables a largo plazo y otras son buenas para rastrear tendencias a corto plazo.

Ahora, las mismas cinco estrategias comerciales, pero usaremos tres ejemplos diferentes para mostrar tres métodos de combinación diferentes, para mostrarle que incluso si la misma estrategia comercial y parámetros comerciales, en el mismo intervalo histórico, diferentes métodos de combinación también pueden afectar los resultados comerciales finales.

Primer método de mezcla: mezcla media ponderada

El primer método de combinación toma un promedio ponderado de los resultados de las cinco estrategias comerciales. Los pesos para cada estrategia comercial son los siguientes:

  • s0: peso 0,8

  • s1: peso 1,2

  • s2: peso 2,0

  • s3: peso 0,5

  • s4: peso 1,5

Para lograr la combinación de promedio ponderado anterior, podemos definir la siguiente expresión blender. Significa: primero multiplique los resultados de las cinco estrategias comerciales por sus respectivas ponderaciones, luego divida por la suma de las ponderaciones (es decir, 5) para obtener el resultado promedio ponderado:

(0.8*s0+1.2*s1+2*s2+0.5*s3+1.5*s4)/5

A continuación, configuramos esta expresión blender en el objeto comercial, ejecutamos las estrategias y obtenemos los resultados de la prueba retrospectiva:

# 创建一个交易员对象,同时运行五个相同的dma交易策略,这些交易策略运行方式相同,但是设置不同的参数后,会产生不同的交易信号。我们通过不同的策略组合方式,得到不同的回测结果
op = qt.Operator('dma, dma, dma, dma, dma')
# 分别给五个不同的交易策略设置不同的策略参数,使他们产生不同的交易信号
op.set_parameter(stg_id=0, par_values=(132, 200, 24))
op.set_parameter(stg_id=1, par_values=(124, 187, 51))
op.set_parameter(stg_id=2, par_values=(103, 81, 16))
op.set_parameter(stg_id=3, par_values=(48, 111, 148))
op.set_parameter(stg_id=4, par_values=(104, 127, 58))

op.set_blender('(0.8*s0+1.2*s1+2*s2+0.5*s3+1.5*s4)/5')

# 运行策略
res = qt.run(op, mode=1, invest_start='20160405', invest_end='20210201')

El informe de backtest resultante es el siguiente: rentabilidad anualizada del 5,51%, ratio de Sharpe del 0,44. Para saber cómo interpretar el informe de backtest, consulte el contenido relevante en la [Sección 3 del tutorial] (…/tutorials/3-start-first-strategy.md).

Aquí no nos centramos en cómo mejorar el rendimiento de las estrategias comerciales. En cambio, nos centramos en cómo las mismas estrategias comerciales producen diferentes resultados de backtest bajo diferentes métodos de combinación, y estas diferencias en los resultados de backtest provienen completamente de los diferentes métodos de combinación.

====================================
|                                  |
|         BACKTEST REPORT          |
|                                  |
====================================
qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 171.1 ms
time consumption for operation back testing:  3.2 ms
investment starts on      2016-04-05 15:00:00
ends on                   2021-01-29 15:00:00
Total looped periods:     4.8 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
000300.SH   370      354    724   88.1%     -0.0%     11.9%  

Total operation fee:     ¥    3,847.81
total investment amount: ¥  100,000.00
final value:              ¥  129,535.45
Total return:                    29.54% 
Avg Yearly return:                5.51%
Skewness:                         -0.90
Kurtosis:                         12.22
Benchmark return:                63.94% 
Benchmark Yearly return:         10.80%

------strategy loop_results indicators------ 
alpha:                           -0.060
Beta:                             1.311
Sharp ratio:                      0.440
Info ratio:                      -0.041
250 day volatility:               0.125
Max drawdown:                    18.49% 
    peak / valley:        2018-01-26 / 2019-01-03
    recovered on:         2019-03-05


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

png

Examine cuidadosamente el gráfico de la curva de ganancias de arriba y notará que el fondo del gráfico está dibujado con diferentes tonos de franjas verdes. Estas franjas representan el ratio de posición en ese período de tiempo. El blanco representa una posición vacía, es decir, no poseer ninguna acción en absoluto, y el verde más oscuro representa el 100% de poseer acciones. El verde en el medio representa la relación de posición entre 0 y 100%, y cuanto mayor sea la relación de posición, más oscuro será el color de las franjas.

Debido a que los resultados de las cinco estrategias comerciales se combinan como un promedio ponderado, cualquier cambio en el resultado de cualquier estrategia hará que cambie la señal comercial final. Esto también hace que el número de operaciones durante todo el período de backtest sea muy frecuente (un total de 370 operaciones de venta y 354 operaciones de compra), y el ratio de posición también fluctúa frecuentemente entre el 0% y el 100%.

Puede ver en el gráfico que hay diferentes tonos de verde en todo el intervalo del historial comercial. Si examina cada intervalo de tenencia con atención, encontrará que el índice de tenencia de estos intervalos corresponde exactamente a los resultados combinados de las cinco estrategias comerciales en ese momento: cuando todas las estrategias comerciales «deciden por unanimidad» comprar la posición completa, el resultado promedio ponderado es 100% de compra, pero siempre que una o más estrategias decidan mantener una posición vacía, el resultado promedio ponderado final es mantener un cierto porcentaje de acciones, que es igual al resultado promedio ponderado de las cinco señales de la estrategia. El resultado final es que la relación de posición fluctúa entre 0% y 100%, y el tiempo entre una posición completamente vacía y una posición completamente llena no es largo.

Eso también significa que no podemos evitar por completo la caída unidireccional del mercado mediante una posición vacía, pero mantener siempre una determinada posición puede captar mejor el canal ascendente.

Mientras tanto, también debería poder observar que debido a que la posición se ajusta de manera flexible, la posición (la profundidad del verde) en el mercado descendente unidireccional es obviamente menor, y la posición en el mercado en alza es mayor, que es exactamente lo que esperamos.

A continuación, echemos un vistazo a un método de mezcla completamente diferente:

Segundo método de mezcla: votación en comité

Este mezclador permite que las mismas cinco estrategias comerciales formen un «comité» para determinar la posición mediante votación equitativa, y la posición debe ser uno de los dos resultados de «no blanco o negro»: posición completa o posición vacía. La expresión es la siguiente:

En este punto necesitamos usar la función especial soportada por blender_str, la “función de comité”, cmt_N_T(s0, s1, ...). Esta función significa: cuando el número de estrategias que generan simultáneamente una señal no plana (con valor de señal absoluto > T) es mayor que N, salida totalmente invertida en largo (1) o totalmente invertida en corto (-1); de lo contrario, salida plana (0). Por tanto, cuando N=3 y T=0, la expresión es la siguiente:

cmt_3_0(s0, s1, s2, s3, s4)

Esto equivale a crear un comité que consta de cinco estrategias comerciales: sólo cuando al menos tres estrategias recomiendan simultáneamente una posición larga totalmente invertida, el comité generará una recomendación larga totalmente invertida; de lo contrario, genera una recomendación plana (sin posición).

Entonces, el resultado final es que el índice de posición es 100% (cuando tres o más estrategias generan una recomendación totalmente invertida) o 0% (cuando menos de tres estrategias generan una recomendación totalmente invertida). En un mercado unidireccional a la baja, el ratio de posición es del 100% o del 0%, sin ningún estado intermedio. El comerciante Operator esencialmente está ejecutando una estrategia comercial que determina la posición en función del voto de un comité de inversiones de cinco miembros. Cada miembro del comité tiene su propia opinión (porque sus parámetros difieren), pero la decisión final la determina la mayoría.

op.set_blender('cmt_3_0(s0, s1, s2, s3, s4)')  # 将委员会混合函数设置为blender表达式
# 运行策略
res = qt.run(op, mode=1)

Los resultados son los siguientes: rentabilidad anualizada 6,43, ratio de Sharpe 0,487

====================================
|                                  |
|         BACKTEST REPORT          |
|                                  |
====================================
qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 179.3 ms
time consumption for operation back testing:  3.2 ms
investment starts on      2016-04-05 15:00:00
ends on                   2021-01-29 15:00:00
Total looped periods:     4.8 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
000300.SH    10       9      19   57.2%     -0.0%     42.8%  

Total operation fee:     ¥      452.82
total investment amount: ¥  100,000.00
final value:              ¥  135,022.14
Total return:                    35.02% 
Avg Yearly return:                6.43%
Skewness:                         -0.74
Kurtosis:                         11.60
Benchmark return:                63.94% 
Benchmark Yearly return:         10.80%

------strategy loop_results indicators------ 
alpha:                           -0.034
Beta:                             1.001
Sharp ratio:                      0.487
Info ratio:                      -0.026
250 day volatility:               0.138
Max drawdown:                    22.60% 
    peak / valley:        2019-04-19 / 2020-07-24
    recovered on:         Not recovered!


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

png

Debes haber notado que esta vez el resultado es muy diferente al anterior: en el último backtest el ratio de posición cambió gradualmente (el tono de las bandas verdes en el fondo del gráfico de retorno representa el ratio de posición), mientras que esta vez es blanco o negro (ya sea totalmente invertido o plano) y el número de operaciones también se reduce considerablemente, con sólo nueve compras y diez ventas en total. Si analiza el registro comercial detenidamente, encontrará que se invierte por completo sólo cuando tres estrategias comerciales votan a favor de invertirlo por completo; el resto del tiempo permanece plano. Por lo tanto, en un mercado descendente unidireccional, la curva de acciones es una línea recta. Pero cuando se invierte completamente, si las acciones caen, no hay forma de reducir las pérdidas recortando adecuadamente la posición.

A continuación, todavía utilizamos este comité, pero ahora, siempre que se emitan dos votos para la posición plena, la posición final será la posición plena:

Tercer método de mezcla: votación en comité

El tercer método de construcción de cartera: sigue siendo una estrategia de comité, pero el umbral de votación para generar una posición larga totalmente invertida se cambia a 2 votos, es decir, siempre que dos estrategias piensen que debería generar una posición larga, lo harán.

op.set_blender('pos_2_0(s0, s1, s2, s3, s4)')
# 运行策略
res = qt.run(op, mode=1)

Los resultados son los siguientes: rentabilidad anualizada 8,46%, ratio de Sharpe 0,612

====================================
|                                  |
|         BACKTEST REPORT          |
|                                  |
====================================
qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 180.0 ms
time consumption for operation back testing:  3.5 ms
investment starts on      2016-04-05 15:00:00
ends on                   2021-01-29 15:00:00
Total looped periods:     4.8 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
000300.SH    12       10     22   71.5%     -0.0%     28.5%  

Total operation fee:     ¥      548.27
total investment amount: ¥  100,000.00
final value:              ¥  147,914.95
Total return:                    47.91% 
Avg Yearly return:                8.46%
Skewness:                         -0.64
Kurtosis:                          8.61
Benchmark return:                63.94% 
Benchmark Yearly return:         10.80%

------strategy loop_results indicators------ 
alpha:                           -0.018
Beta:                             1.001
Sharp ratio:                      0.612
Info ratio:                      -0.018
250 day volatility:               0.154
Max drawdown:                    22.34% 
    peak / valley:        2019-04-19 / 2020-07-24
    recovered on:         Not recovered!


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

png

Compare el segundo gráfico y el tercer gráfico, encontrará que el intervalo de posición completa obviamente se ha vuelto más largo, esto se debe a que la estrategia que solía requerir tres votos para estar completamente posicionada, ahora solo necesita dos votos, por lo que es más fácil lograr la posición completa.

8.4. Resumen

Muy bien, a estas alturas ya debería tener una comprensión preliminar de cómo se pueden combinar las estrategias comerciales. Nuestro tutorial continuará: qteasy ofrece aún más formas de implementar las estrategias comerciales que desea. De hecho, aunque el núcleo de qteasy está diseñado como un motor de estrategia vectorizado que favorece la realización de pruebas retrospectivas y la ejecución de alta velocidad, todavía tiene en cuenta suficiente flexibilidad. En teoría, puedes implementar cualquier tipo de estrategia comercial que puedas imaginar.

Mientras tanto, el marco de backtesting de qteasy también ha creado muchos diseños especiales, que pueden evitar por completo que usted importe «funciones futuras» inadvertidamente a la estrategia comercial, asegurando que su estrategia comercial se base completamente en datos pasados ​​durante el backtesting. Al mismo tiempo, se utilizan muchas técnicas de preprocesamiento y técnicas JIT para compilar las funciones clave del kernel para lograr una velocidad de ejecución no menor que la del lenguaje C.

Sin embargo, para lograr estrategias comerciales teóricamente infinitas posibles, puede que no sea suficiente utilizar únicamente estrategias comerciales integradas y combinación de estrategias. Algunas estrategias comerciales específicas o algunas estrategias comerciales particularmente complejas no se pueden crear mediante la combinación de estrategias incorporada. Esto requiere que utilicemos la clase base Strategy proporcionada por qteasy para crear una estrategia comercial personalizada basada en ciertas reglas.

En la siguiente sección del tutorial qteasy, usaremos un ejemplo para presentar cómo crear una estrategia comercial personalizada, cómo definir los parámetros básicos de la estrategia, cómo definir los tipos de datos requeridos por la estrategia, cómo configurar la lógica para generar señales comerciales…