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?
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 generatick
Los 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
, GetTrades
En un momento de los datos del mercado en la línea de tiempo, llamandoGetTicker
, GetTrades
, GetDepth
yGetRecords
no 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 backtesting admite estrategias de backtesting escritas y diseñadas por:JavaScript
, TypeScript
, Python
, C++
, PINE
, MyLanguage
, Blockly
la 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.
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.
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 size
El 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.
En elpágina de edición de estrategias, en la paginación de
backtest
(guardado en el código de la estrategia a través del botón backtest
en 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 JavaScript
/Python
/C++
/MyLanguage
/PINE
idiomas 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"}]
*/
El sistema de backtesting de la Plataforma de Comercio Cuántico FMZ admite fuentes de datos personalizadas, el sistema de backtesting utiliza elGET
mé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:60000 es 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
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,asks
para el orden ascendente de precios,bids
para 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 Tick
Ejemplo 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 Tick
Ejemplo 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
]
// ...
]
}
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
Especificar la dirección de la fuente de datos, por ejemplo,http://120.24.2.20:9090/data
El 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 ensayoJavaScript
Ejemplo:
/*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)
}
FMZ Quant Trading Platform ha abierto el código fuente para elJavaScript
La lengua y elPython
lenguaje del motor local de backtest, que admite la configuración del período de línea K subyacente durante la backtest.
tecla de acceso directo para cambiar entre la página de estrategia Ctrl +,
para volver a la página Ctrl
Presiona la tecla.,
.
Clave de acceso directo para la estrategia de ahorro
Usa la llave.Ctrl + s
para salvar estrategias.
Atajo para iniciar la estrategia backtest
Usa la llave.Ctrl + b
para permitir
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