La mano te enseña a trasplantar una estrategia de lenguaje (progreso)

El autor:Un sueño pequeño., Creado: 2019-11-13 09:15:56, Actualizado: 2023-10-17 21:23:21

img

La mano te enseña a trasplantar una estrategia de lenguaje (progreso)

En el artículo anteriorLa mano te enseñará a escribir estrategias -- una estrategia de mi lengua.¿Cómo se puede transferir una estrategia a JavaScript si es un poco más complejo? ¿Qué trucos hay aquí?

Para empezar, veamos la estrategia de este trasplante:

(*backtest
start: 2019-05-01 00:00:00
end: 2019-11-12 00:00:00
period: 1d
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
args: [["SlideTick",10,126961],["ContractType","quarter",126961]]
*)

N1:=10;
N2:=21;
AP:=(HIGH+LOW+CLOSE)/3;
ESA:=EMA(AP,N1);
D:=EMA(ABS(AP-ESA),N1);
CI:=(AP-ESA)/(0.015*D);
TCI:=EMA(CI,N2);
WT1:TCI;
WT2:SMA(WT1,4,1);
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

La primera parte de esta estrategia para el idioma maya(*backtest...*)Es el código de configuración de la configuración de retrospección, para facilitar la comparación, establecer una configuración de retrospección uniforme. Esta estrategia también es una estrategia de búsqueda aleatoria, no es demasiado compleja (relativamente más compleja que en el artículo anterior), es una estrategia más representativa.EMASMA

Una rueda hecha a mano.

  • El EMA La función de indicador, una función de la biblioteca de indicadores que está lista cuando la plataforma FMZ escribe la política en el lenguaje JavaScript, es:TA.MA

  • El SMA Lo que necesitamos hacer es:SMAEste indicador, que encontramos en la biblioteca TA de FMZ no tiene soporte para la función de indicador SMA, también hay diferencias entre el indicador SMA de la biblioteca talib y el de la lengua Maé:imgComo se puede ver, la parte de los parámetros tiene un parámetro de peso además del parámetro de ciclo.

    La descripción de la función de indicador SMA en la biblioteca talib en la API de FMZ es:img

    Se puede vertalib.SMALa media móvil es un simple indicador de media móvil. Así que sólo se puede empezar a hacer algo por sí mismo.SMAY, como desarrolladores que escriben estrategias en JavaScript, esta es una de las habilidades necesarias, después de todo, si no hay ruedas ya hechas, el coche todavía tiene que funcionar, hacer una es todo.

    La verdad es que hay muy poca investigación sobre los indicadores y en general no se entiende nada de buscar información.img

    El proceso de algoritmo parece ser bastante fiable, así que hazlo:

    function SMA (arr, n, m) {
        var sma = []
        var currSMA = null
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] && !isNaN(arr[i])) {
                if (!currSMA) {
                    currSMA = arr[i]
                    sma.push(currSMA)
                    continue
                }  
    
                // [M*C2+(N-M)*S1]/N
                currSMA = (m * arr[i] + (n - m) * currSMA) / n
                sma.push(currSMA)
            } else {
                sma.push(NaN)
            }
        }  
    
        return sma
    }
    

Escribir la parte de llenado

Uso del marco estratégicoLa mano te enseñará a escribir estrategias -- una estrategia de mi lengua.El mismo marco en el artículo, que se llena principalmente de dos partes:img

En primer lugar, procesar datos del sector, calcular indicadores.img

En este artículo, vamos a analizar las funciones de esta parte de la lengua maya, una por una:

  • 1、AP:=(HIGH+LOW+CLOSE)/3;

    Esto se puede entender como sumar el precio más alto, el precio más bajo y el precio de cierre de cada BAR en la línea K de datos, dividirlo por 3, calcular el promedio y almacenarlo como una matriz, y corresponder a cada BAR. Esto es lo que se puede hacer:

    function CalcAP (r) {   // AP:=(HIGH+LOW+CLOSE)/3;
        var arrAP = []      // 声明一个空数组
    
        for (var i = 0; i < r.length; i++) {      // r为传入的K线数据,是一个数组,用for遍历这个数组
            v = (r[i].High + r[i].Low + r[i].Close) / 3      // 计算 平均值
            arrAP.push(v)                                    // 添加在 arrAP数组的尾部,arrAP是空的时候尾部就是第一个。
        }  
    
        return arrAP     // 返回 这个平均值数组,即麦语言中计算的 AP 
    }
    

    Se puede llamar a esta función en la función OnTick del ciclo principal, por ejemplo:

    // 计算指标
    // AP
    var ap = CalcAP(records)
    
  • 2, AP después de que el cálculo se ha completado, el cálculo continúaESA:=EMA(AP,N1);:

    Para calcular el ESA, usamos los datos de AP que hemos calculado en el paso anterior, que en realidad son las "medias móviles del índice" de AP, es decir, los indicadores EMA, por lo que podemos calcular los indicadores EMA con AP como datos y N1 como parámetros del indicador EMA.

    function CalcESA (ap, n1) {   // ESA:=EMA(AP,N1);
        if (ap.length <= n1) {    // 如果AP的长度小于指标参数,是无法计算出有效数据的,这个时候让函数返回false。
            return false
        }  
    
        return TA.EMA(ap, n1)
    }
    
  • 3、D:=EMA(ABS(AP-ESA),N1);

    Se calcula conAPESADatos de cálculoD¿Qué es esto? Aquí puedes ver las notas de código y algunas técnicas para calcular los indicadores.

    function CalcD (ap, esa, n1) {    // D:=EMA(ABS(AP-ESA),N1);
        var arrABS_APminusESA = []
        if (ap.length != esa.length) {
            throw "ap.length != esa.length"
        }  
    
        for (var i = 0; i < ap.length; i++) {
            // 计算指标数值时,必须判断一下数据的有效性,因为前几次EMA计算可能数组中的开始部分的数据是NaN,或者null
            // 所以必须判断,参与计算的数据都是有效数值才能进行,如果有任何无效数值,就用NaN向arrABS_APminusESA填充
            // 这样计算得到的数据,每个位置和之前的数据都是一一对应的,不会错位。
            if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) {
                v = Math.abs(ap[i] - esa[i])     // 根据ABS(AP-ESA) , 具体计算数值,然后放入arrABS_APminusESA数组
                arrABS_APminusESA.push(v)
            } else {
                arrABS_APminusESA.push(NaN)
            }
        }  
    
        if (arrABS_APminusESA.length <= n1) {
            return false
        }  
    
        return TA.EMA(arrABS_APminusESA, n1)    // 计算数组arrABS_APminusESA的EMA指标,得到数据D(数组结构)
    }
    
  • 4、CI:=(AP-ESA)/(0.015*D);Este cálculo es similar al paso 1, y se emite el código directamente.

    function CalcCI (ap, esa, d) {    // CI:=(AP-ESA)/(0.015*D);
        var arrCI = []
        if (ap.length != esa.length || ap.length != d.length) {
            throw "ap.length != esa.length || ap.length != d.length"
        }
        for (var i = 0; i < ap.length; i++) {
            if (ap[i] && esa[i] && d[i] && !isNaN(ap[i]) && !isNaN(esa[i]) && !isNaN(d[i])) {
                v = (ap[i] - esa[i]) / (0.015 * d[i])
                arrCI.push(v)
            } else {
                arrCI.push(NaN)
            }
        }  
    
        if (arrCI.length == 0) {
            return false
        }  
    
        return arrCI
    }
    
  • TCI: = EMA ((CI, N2)); Solo se calcula el indicador EMA de la matriz CI.

    function CalcTCI (ci, n2) {   // TCI:=EMA(CI,N2);
        if (ci.length <= n2) {
            return false
        }  
    
        return TA.EMA(ci, n2)
    }
    
  • WT2:SMA(WT1,4,1);

    Este último paso, con las ruedas que hemos construido antes.SMALa función.

    function CalcWT2 (wt1) {    // WT2:SMA(WT1,4,1);
        if (wt1.length <= 4) {
            return false 
        }  
    
        return SMA(wt1, 4, 1)   // 使用我们自己实现的SMA函数计算出wt1的SMA指标。
    }
    

La transferencia de señales de transacción es muy sencilla.

AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

Al leer estas frases del código de la lengua maya, se puede ver que el golden fork, el forcado muerto de las dos líneas de indicadores WT1 y WT2 se juzgan como condiciones para abrir una operación. En la actualidad, la mayoría de las personas que hablan la lengua maya hablan el idioma de sus padres, y la mayoría de las personas que hablan el idioma de sus padres hablan el idioma de sus padres.img

Se puede observar mediante la práctica ejecución de la estrategia del lenguaje de Mac, que cuando se detecta la señal en el punto de apertura, en realidad se detecta si la posición de este punto de apertura BAR antes de los 2 BAR es una horquilla de oro. Se puede ver claramente en el gráfico anterior:img img

El código de relleno de la sección de detección de señales se puede escribir como:

if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENLONG
        Log("OPENLONG")    // 测试
    }
    if (_State == SHORT) {
        _State = COVERSHORT
        Log("COVERSHORT")  // 测试
    }
    isOK = false  
}

if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENSHORT
        Log("OPENSHORT")  // 测试
    }
    if (_State == LONG) {
        _State = COVERLONG
        Log("COVERLONG")  // 测试
    }
    isOK = false   
}

Aquí se puede pensar en por qué las instrucciones SPK, BPK de Mac pueden implementarse con este código.

Las pruebas

Configuración de las pruebas de retraso:img

La versión en Ma traduce:img

Versión de Javascript de nuevo:img img

El código de la parte inicial de la función OnTick, que se utiliza para acelerar un poco la recuperación, es para que la política funcione en un modelo de precio de cierre, y es de interés analizarlo en detalle.

function OnTick(){
    // 驱动策略的行情处理部分
    var records = _C(exchange.GetRecords)
    if (records[records.length - 1].Time == preTime) {
        if (isOK) {
            Sleep(500)
            return 
        }
    } else {
        preTime = records[records.length - 1].Time
    }
    ...
    ..
    .

El código completo de la estrategia de enseñanza:https://www.fmz.com/strategy/174457

Gracias por leer.


Relacionados

Más.