En la carga de los recursos... Cargando...

Sistema de pruebas de retroceso

Después de haber completado el diseño de una estrategia comercial cuantitativa, ¿cómo puede conocer la situación básica de su estrategia, como la lógica de la estrategia y la dirección de los retornos de la estrategia?

Modelo del sistema de pruebas de retroceso

FMZ Quant Trading Platform divide el sistema de backtest ennivel de botynivel de simulación. El nivel de bot es para backtest completamente de acuerdo con los datos históricos completos; mientras que el nivel de simulación backtest generatickLos resultados de las pruebas de retroceso se basan en los datos históricos reales, pero los datos a nivel de bot son más precisos y los resultados son más creíbles. Sin embargo, las pruebas de retroceso son solo el rendimiento de la estrategia según los datos históricos. Los datos históricos no pueden representar completamente el mercado futuro. El mercado histórico puede repetirse, o también puede conducir al Cisne Negro. Por lo tanto, los resultados de las pruebas de retroceso deben tratarse de manera racional y objetiva.

ElNivel de simulación Marcadogenera el simuladoDatos de las garrapatasEn el caso de las pruebas de retroceso, el valor de la prueba de retroceso se calcula en función del período de línea K subyacente, cada período de línea K subyacente generará un máximo de 12 puntos de tiempo de retroceso; mientras que el valor de retroceso se calcula en función del período de línea K subyacente.nivel de mercado realEl mecanismo de backtesting de FMZ Quant permite que la estrategia se negocie varias veces en una sola línea K, evitando la situación en la que la negociación solo se puede ejecutar al precio de cierre. Es más preciso teniendo en cuenta la velocidad de backtest.

Descripción del mecanismo del sistema de pruebas de retroceso

  • Tick de nivel de simulación ElNivel de simulación MarcadoSe basa en los datos de la línea K subyacentes del sistema de backtest, simulando los datos de tick para backtest dentro del marco de los valores del precio más alto, precio más bajo, precio de apertura y precio de cierre de una barra de línea K subyacente dada de acuerdo con un determinado algoritmo. Como datos de tick en tiempo real en la serie de tiempo de backtesting, se devuelve cuando el programa de estrategia llama a la interfaz. Para más detalles, consulte:Descripción del mecanismo de nivel de simulación del sistema de pruebas de retroceso.

  • Tick de nivel de bot La prueba de retroceso de nivel de bot es el nivel real de datos de tick en la serie de tiempo de Bar. Para las estrategias basadas en los datos de nivel de tick, usar el nivel real del mercado para backtest está más cerca de la realidad. En la prueba de retroceso de nivel de bot, los datos de tick son datos registrados reales, no simulados. Soporta datos de profundidad, reproducción de datos de registro de operaciones de mercado, profundidad personalizada y cada dato comercial individual. El tamaño máximo de la prueba de retroceso de datos de nivel de mercado real es de hasta un máximo de 50 MB, sin límite en el rango de tiempo de la prueba de retroceso dentro del límite superior del conjunto de datos. Si necesita ampliar el rango de tiempo de retroceso tanto como sea posible, puede reducir el valor de la configuración de la profundidad de la prueba de engranaje y no usar cada dato comercial individual para aumentar el rango de tiempo de prueba de retroceso.GetDepth, GetTradesEn un momento de los datos del mercado en la línea de tiempo, llamandoGetTicker, GetTrades, GetDepthyGetRecordsno empujará el tiempo varias veces cuando el tiempo se mueve en la línea de tiempo de backtest (lo que no desencadenará un salto al siguiente momento de datos del mercado). Las llamadas repetidas a una de las funciones anteriores empujarán el tiempo de backtest para moverse en la línea de tiempo de backtest (saltar al siguiente momento de datos del mercado). Cuando se utiliza el nivel real del mercado para backtest, no se recomienda elegir un tiempo anterior. Puede que no haya datos de nivel real del mercado en el período de tiempo prematuro.

Tick a nivel de botyTick de nivel de simulaciónEn el caso de las transacciones que se realizan en el sistema de backtest, el mecanismo de correspondencia de transacciones del sistema de backtest: la correspondencia de transacciones de orden se lleva a cabo de acuerdo con el precio visto y se negocia el volumen completo.

El sistema de pruebas de retroceso admite varios lenguajes de programación

El sistema de backtesting admite estrategias de backtesting escritas y diseñadas por:JavaScript, TypeScript, Python, C++, PINE, MyLanguage, Blocklyla visualización. El backtest deJavaScript tambiényC++estrategias de negociación se lleva a cabo en el navegador, y el bot de mercado real oWexApp es una aplicaciónEn la actualidad, el mercado real de divisas emulado (es decir, elWexApp es una aplicaciónEmulado de intercambio de FMZ Quant Trading plataforma) se ejecuta sin instalar ningún otro software, bibliotecas o módulos. La prueba de retroceso dePythonLa operación de mercado real y la backtest se basan en el funcionamiento de la plataforma de comercio de FMZ.PythonSi se necesitan algunas bibliotecas, deben instalarse manualmente (solo las comunes)Pythonlas bibliotecas son compatibles con los servidores públicos de FMZ Quant).

ApoyaJavaScript tambiénDescomposición de la estrategia de backtesting en Chrome DevTools,Por favor, haga referencia a.

Intercambios admitidos en el sistema de pruebas de retroceso

  • Criptomonedas Intercambios spot y futuros de criptomonedas; admite datos sobre todo tipo de intercambios.
  • Valores de Futu Las acciones de Hong Kong, las acciones de EE.UU. y otros mercados.

Optimización de parámetros del sistema de pruebas posteriores

La función de optimización de parámetros del sistema de backtest de la Plataforma de Comercio Cuántico FMZ es establecer las combinaciones de parámetros de acuerdo con cada opción de optimización de parámetros durante la backtesting.Optimizaciónopción en el lado derecho del parámetro de estrategia para mostrar la configuración de optimización.

  • Valor mínimo: para limitar el valor inicial de los parámetros.
  • Valor máximo: para limitar el valor máximo de los parámetros después de cambios incrementales.
  • Tamaño del paso: el valor de la variable incremental de los parámetros.
  • Los hilos concurrentes: Durante la optimización de parámetros, establece el número de hilos para la ejecución simultánea de cada combinación de parámetros de backtest.JavaScript, PINE, yMy Language, y no admite la optimización de parámetros en plantillas.

Las combinaciones de parámetros se generan basándose en elminimum, maximum, ystep sizeEl sistema de backtesting se repite a través de estas combinaciones de parámetros para backtesting (es decir, backtesting de cada combinación de parámetros una vez).NúmeroEl sistema de backtesting puede optimizar el tipo de prueba.

Guardar las configuraciones de prueba de retroceso

En elpágina de edición de estrategias, en la paginación de Backtest (es decir, el sistema de backtest), puede establecer opciones como configuraciones de backtest y parámetros de estrategia para backtestar la estrategia. Cuando estos parámetros se establecen, se puede seguir el conjunto de estrategia de backtesting, entonces, ¿cómo guardar la configuración de información establecida?

    1. Puede utilizar el botón Guardar configuraciones de prueba posterior en elPágina de edición de estrategiasregistrar toda la información de configuración de backtest (incluidas las configuraciones de backtest y las configuraciones de parámetros de estrategia) en el código fuente de la estrategia en forma de código.
    1. Cuando guarde una estrategia haciendo clic en el botón Guardar estrategia en la página de edición de estrategia, la plataforma registrará automáticamente la configuración actual de backtest, las configuraciones de parámetros de estrategia y otra información. ¿Cómo cargar la configuración de backtest en el sistema de backtest?
    1. Al actualizar la página de edición de la estrategia o al volver a abrir esta página de edición de la estrategia, la información de configuración de backtest registrada por el botón Guardar configuraciones de backtest se cargará automáticamente primero.
    1. Si no hay información de configuración de backtest registrada en el código de estrategia actual como comentariobacktest(guardado en el código de la estrategia a través del botón Guardar configuraciones de prueba posterior), el sistema de prueba posterior configura automáticamente las configuraciones de prueba posterior a la información de configuración de prueba posterior cuando se hizo clic en el botón Guardar estrategia por última vez para la estrategia actual.
    1. Si la información de configuración de backtest registrada en forma de comentarios al comienzo del código de estrategia se modifica en la página de edición de estrategia, debe sincronizar la información de configuración de backtest actualizada actualmente con la opción de interfaz de backtest de estrategia.backtesten el área de edición de estrategias.
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Haga clic en Guardar configuraciones de backtest, hay ligeras diferencias de formato enJavaScript/Python/C++/MyLanguage/PINEidiomas al guardar las configuraciones de backtest en el código de estrategia: Mi Lenguaje:

(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*)

Lenguaje PINE:

/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Fuente de datos personalizada

El sistema de backtesting de la Plataforma de Comercio Cuántico FMZ admite fuentes de datos personalizadas, el sistema de backtesting utiliza elGETmétodo para solicitar una URL personalizada (URL accesible públicamente) para obtener una fuente de datos externa para backtest.

Parámetro Significado Explicación
el símbolo Nombre del símbolo Datos del mercado al contado, tales como:BTC_USDT, datos del mercado de futuros, tales como:BTC_USDT.swap, datos de las tasas de financiación de contratos perpetuos de futuros, tales como:BTC_USDT.funding, los datos del índice de precios de los contratos perpetuos de futuros, tales como:BTC_USDT.index
el día Los intercambios En el caso de las entidades de garantía, el valor de la garantía será el valor de la garantía.
redondo Precisión de los datos True significa que la precisión específica se define en los datos suministrados por la fuente de datos personalizada.round=true
el período Período de datos de línea K (millisegundos) como por ejemplo:60000es un período de 1 minuto
profundidad Niveles de profundidad 1-20
las operaciones Si es necesario dividir datos verdadero (y) / falso (y)
desde Tiempo de inicio el tiempo de unix
En el El tiempo del fin el tiempo de unix
Detalle Datos solicitados para los detalles del símbolo La solicitud enviada por el sistema de pruebas de retroceso de la plataforma de negociación cuántica FMZ al origen de datos personalizado se fija como:detail=true
de costumbre Este parámetro puede ignorarse

Cuando la fuente de datos de los objetos de intercambio al contado y de intercambio de futuros esté configurada en una fuente de datos personalizada (feeder), el sistema de backtesting envía una solicitud al servicio de fuente de datos personalizada:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Bitget&from=1351641600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_OKX&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=1

Formato de datos

El formato devuelto debe ser uno de los dos formatos siguientes (que serán reconocidos automáticamente por el sistema):

  • Nivel de simulación Tick, el siguiente es un ejemplo de datos JSON:

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "open", "high", "low", "close", "vol"],
        "data":[
            [1564315200000, 9531300, 9531300, 9497060, 9497060, 787],
            [1564316100000, 9495160, 9495160, 9474260, 9489460, 338]
        ]
    }
    
  • Marque el nivel de bot, el siguiente es un ejemplo de datos JSON: Los datos de backtest a nivel de tick (contienen información sobre la profundidad del mercado, y el formato de profundidad es una matriz de[price, volume]Puede tener múltiples niveles de profundidad,askspara el orden ascendente de precios,bidspara el orden decreciente de precios).

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "asks", "bids", "trades", "close", "vol"],
        "data":[
            [1564315200000, [[9531300, 10]], [[9531300, 10]], [[1564315200000, 0, 9531300, 10]], 9497060, 787],
            [1564316100000, [[9531300, 10]], [[9531300, 10]], [[1564316100000, 0, 9531300, 10]], 9497060, 787]
        ]
    }
    
El campo Descripción
Detalle Información detallada sobre el tipo de datos solicitado.

incluido el nombre de la moneda denominada, el nombre de la moneda de comercio, la precisión, la cantidad mínima de pedido, etc. Esquema especifica los atributos de las columnas en los datos matriz, que es sensible a mayúsculas y está limitada sólo al tiempo, abierto, alto, bajo, cerrado, vol, pide, ofrece, negociaciones Datos La estructura de columnas, datos registrados de acuerdo con el esquema Configuración.

campo de detalles

El campo Descripción
el día Exchange Id, tenga en cuenta que el spot y los futuros de un
Ciertos intercambios tienen diferentes efectos.
el símbolo Código del producto de negociación
Alias El símbolo en el intercambio correspondiente al actual
Código del producto de comercio
Cuota de mercado Moneda de negociación
cotizaciónMoneda Moneda denominada
MargenValuta Moneda de margen
basePrecisión Precisión de la moneda de la transacción
Citación Precisión Precisión de las monedas
el número de Cantidad mínima de pedido
Cuota máxima Cantidad máxima de pedido
Min Nocional Número mínimo de pedido
max Nocional Cuota máxima de la orden
precioTick Salto de precios
volumenMarcar Valor mínimo de cambio de la cantidad de pedido (un salto en
cantidad de pedido)
Margen y nivel Valor de apalancamiento de los futuros
ContratoTipo En el caso de los contratos perpetuos:swap, el

el sistema de backtest continuará enviando tasa de financiación e índice de precios las peticiones.

Atributos especiales de columnaasks, bids, trades:

El campo Descripción Las observaciones
Pide / ofrece [precio, volumen],...] Por ejemplo, los datos en

ElLive Trading Level TickEjemplo de datos:[[9531300, 10]]¿Qué es eso? Las operaciones. El tiempo, la dirección, el precio, el volumen... Por ejemplo, los datos en elLive Trading Level TickEjemplo de datos:[[1564315200000, 0, 9531300, 10]] |

Cuando se realizan pruebas de retroceso de contratos perpetuos en las bolsas de futuros, las Las fuentes de datos también requieren datos adicionales sobre la tasa de financiación y el precio El sistema de backtesting continuará enviando las solicitudes para las tasas de financiación únicamente cuando se devuelvan los datos de mercado solicitados y el campo de detalles en la estructura devuelta contiene el"contractType": "swap"el par clave-valor.

Cuando el sistema de backtesting reciba datos sobre las tasas de financiación, seguir enviando solicitudes de datos sobre el índice de precios.

La estructura de los datos de las tasas de financiación es la siguiente:

{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.funding",
        "alias": "BTC_USDT.funding",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "marginCurrency": "",
        "basePrecision": 8,
        "quotePrecision": 8,
        "minQty": 1,
        "maxQty": 10000,
        "minNotional": 1,
        "maxNotional": 100000000,
        "priceTick": 1e-8,
        "volumeTick": 1e-8,
        "marginLevel": 10
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [
            1584921600000,
            -16795,
            -16795,
            -16795,
            -16795,
            0
        ],
        [
            1584950400000,
            -16294,
            -16294,
            -16294,
            -16294,
            0
        ]
        // ...
    ]
}
  • El intervalo entre los períodos contiguos es de 8 horas
  • Por ejemplo, la tasa de financiación de Binance se actualiza cada 8 horas. ¿Son los datos de la tasa de financiación -16795? Debido a que al igual que los datos de línea K, para evitar la pérdida de precisión de punto flotante durante la transmisión de la red, los datos utilizan el tipo entero; los datos de la tasa de financiación también pueden ser negativos.

Ejemplo de solicitud de datos de tasas de financiación de las pruebas de retroceso el sistema es:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.funding&to=1611244800&trades=0

La estructura de los datos del índice de precios es la siguiente:


{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.index",
        "alias": "BTCUSDT",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "index",
        "marginCurrency": "USDT",
        "basePrecision": 3,
        "quotePrecision": 1,
        "minQty": 0.001,
        "maxQty": 1000,
        "minNotional": 0,
        "maxNotional": 1.7976931348623157e+308,
        "priceTick": 0.1,
        "volumeTick": 0.001,
        "marginLevel": 10,
        "volumeMultiple": 1
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [1584921600000, 58172, 59167, 56902, 58962, 0],
        [1584922500000, 58975, 59428, 58581, 59154, 0],
        // ...
    ]
}

Ejemplo de solicitud de datos de índice de precios enviada por el backtesting el sistema es:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.index&to=1611244800&trades=0

Ejemplo de fuente de datos personalizada

Especificar la dirección de la fuente de datos, por ejemplo,http://120.24.2.20:9090/dataEl programa de servicio de fuente de datos personalizado está escrito usandoGolang:

package main

import (
    "fmt"
    "net/http"
    "encoding/json"
)

func Handle (w http.ResponseWriter, r *http.Request) {
    // e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data

    // request: GET http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=OKX&from=1584921600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
    //              http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1599958800&period=3600000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=0
    fmt.Println("request:", r)

    // response
    defer func() {
        // response data
        /* e.g. data
        {
            "detail": {
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10
            },
            "schema": [
                "time",
                "open",
                "high",
                "low",
                "close",
                "vol"
            ],
            "data": [
                [1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151],
                [1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738],
                [1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875],
                [1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777],
                [1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292],
                [1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666],
                [1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405],
                [1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768],
                [1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797],
                [1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692]
            ]
        }
        */
        
        // /* Simulation level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time","open","high","low","close","vol"},
            "data": []interface{}{
                []int64{1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151},  // 1610755200000 : 2021-01-16 08:00:00
                []int64{1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738},  // 1610841600000 : 2021-01-17 08:00:00
                []int64{1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875},
                []int64{1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777},
                []int64{1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292},
                []int64{1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666},
                []int64{1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405},
                []int64{1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768},
                []int64{1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797},
                []int64{1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692},
            },
        }
        // */

        /* Bot level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time", "asks", "bids", "trades", "close", "vol"},
            "data": []interface{}{
                []interface{}{1610755200000, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{1610755200000, 0, 9531300, 10}}, 9497060, 787},
                []interface{}{1610841600000, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{1610841600000, 0, 9531300, 11}}, 9497061, 789},                
            },
        }
        */

        b, _ := json.Marshal(ret)
        w.Write(b)
    }()
}
func main () {
    fmt.Println("listen http://localhost:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe(":9090", nil)
}

Estrategia de ensayoJavaScriptEjemplo:

/*backtest
start: 2021-01-16 08:00:00
end: 2021-01-22 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
args: [["number",2]]
*/

function main() {
    var ticker = exchange.GetTicker()
    var records = exchange.GetRecords()
    Log(exchange.GetName(), exchange.GetCurrency())
    Log(ticker)
    Log(records)
}

Motor de pruebas de retroceso local

FMZ Quant Trading Platform ha abierto el código fuente para elJavaScriptLa lengua y elPythonlenguaje del motor local de backtest, que admite la configuración del período de línea K subyacente durante la backtest.

teclas de acceso directo de la página de prueba posterior

  • tecla de acceso directo para cambiar entre la página de estrategia Edición y la página Backtesting Usa la llave.Ctrl +,para volver a la página Backtest y Edit Strategy.CtrlPresiona la tecla.,.

  • Clave de acceso directo para la estrategia de ahorro Usa la llave.Ctrl + spara salvar estrategias.

  • Atajo para iniciar la estrategia backtest Usa la llave.Ctrl + bpara permitir Comenzar la prueba de retroceso.

Descarga de datos de pruebas de retroceso

  • Descarga de datos del registro del sistema de pruebas de retroceso Abre la estrategia específica y cambia a la página de prueba de retroceso para probar la estrategia. En la columna de información de estado de la estrategia que se muestra después de la prueba de retroceso, hay un botón de descarga de la tabla en la esquina superior derecha. Haz clic en él para descargar un archivo CSV de los datos de la columna de estado al final de la prueba de retroceso.
  • Backtesting descarga de datos de la barra de estado del sistema Abre la estrategia específica y cambia a la página de prueba de retroceso para probar la estrategia. En la columna de información de registro de la estrategia que se muestra después de la prueba de retroceso, hay un botón de descarga de la tabla en la esquina superior derecha. Haz clic en él para descargar el archivo en formato CSV de los datos de registro de prueba de retroceso.

Algoritmo de Sharpe en el sistema de pruebas de retroceso

El código fuente del algoritmo Sharpe en el sistema de backtesting:

function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
    // force by days
    period = 86400000
    if (profits.length == 0) {
        return null
    }
    var freeProfit = 0.03 // 0.04
    var yearRange = yearDays * 86400000
    var totalReturns = profits[profits.length - 1][1] / totalAssets
    var annualizedReturns = (totalReturns * yearRange) / (te - ts)

    // MaxDrawDown
    var maxDrawdown = 0
    var maxAssets = totalAssets
    var maxAssetsTime = 0
    var maxDrawdownTime = 0
    var maxDrawdownStartTime = 0
    var winningRate = 0
    var winningResult = 0
    for (var i = 0; i < profits.length; i++) {
        if (i == 0) {
            if (profits[i][1] > 0) {
                winningResult++
            }
        } else {
            if (profits[i][1] > profits[i - 1][1]) {
                winningResult++
            }
        }
        if ((profits[i][1] + totalAssets) > maxAssets) {
            maxAssets = profits[i][1] + totalAssets
            maxAssetsTime = profits[i][0]
        }
        if (maxAssets > 0) {
            var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
            if (drawDown > maxDrawdown) {
                maxDrawdown = drawDown
                maxDrawdownTime = profits[i][0]
                maxDrawdownStartTime = maxAssetsTime
            }
        }
    }
    if (profits.length > 0) {
        winningRate = winningResult / profits.length
    }
    // trim profits
    var i = 0
    var datas = []
    var sum = 0
    var preProfit = 0
    var perRatio = 0
    var rangeEnd = te
    if ((te - ts) % period > 0) {
        rangeEnd = (parseInt(te / period) + 1) * period
    }
    for (var n = ts; n < rangeEnd; n += period) {
        var dayProfit = 0.0
        var cut = n + period
        while (i < profits.length && profits[i][0] < cut) {
            dayProfit += (profits[i][1] - preProfit)
            preProfit = profits[i][1]
            i++
        }
        perRatio = ((dayProfit / totalAssets) * yearRange) / period
        sum += perRatio
        datas.push(perRatio)
    }

    var sharpeRatio = 0
    var volatility = 0
    if (datas.length > 0) {
        var avg = sum / datas.length;
        var std = 0;
        for (i = 0; i < datas.length; i++) {
            std += Math.pow(datas[i] - avg, 2);
        }
        volatility = Math.sqrt(std / datas.length);
        if (volatility !== 0) {
            sharpeRatio = (annualizedReturns - freeProfit) / volatility
        }
    }

    return {
        totalAssets: totalAssets,
        yearDays: yearDays,
        totalReturns: totalReturns,
        annualizedReturns: annualizedReturns,
        sharpeRatio: sharpeRatio,
        volatility: volatility,
        maxDrawdown: maxDrawdown,
        maxDrawdownTime: maxDrawdownTime,
        maxAssetsTime: maxAssetsTime,
        maxDrawdownStartTime: maxDrawdownStartTime,
        winningRate: winningRate
    }
}
Editor de estrategias Funciones de entrada de la estrategia