Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Creado el: 2019-11-13 09:15:56, Actualizado el: 2024-12-15 16:02:09
comments   0
hits   2306

Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Artículo anteriorTe enseño a escribir estrategias paso a paso - trasplantar una estrategia de mi lenguajeEn el artículo, realizamos una prueba de trasplante en una estrategia de lenguaje Mai simple. Si se trata de una estrategia de lenguaje Mai un poco más compleja, ¿cómo trasplantarla al lenguaje JavaScript? ¿Cuáles son las técnicas para esto?

Veamos primero la estrategia que se va a trasplantar en esta ocasión:

(*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;

El comienzo de esta estrategia lingüística(*backtest...*)Es el código de configuración de la configuración de backtest. Para facilitar la comparación, se establece una configuración unificada de backtest. Esta estrategia también es una estrategia encontrada al azar, y no es demasiado complicada (en comparación con la del artículo anterior) y es una estrategia más representativa. Para trasplantar una estrategia de lenguaje Mai, primero debes leer el contenido de la estrategia. El código de la estrategia de lenguaje Mai es relativamente conciso y, básicamente, puedes tener una cierta comprensión de la estrategia general. Esta estrategia utiliza varias funciones de indicador.EMASMA

Primero construye una rueda

  • EMA Esta función de indicador tiene una función de biblioteca de indicadores lista para usar al escribir estrategias en lenguaje JavaScript en la plataforma FMZ. Ahora mismo:TA.MA

  • SMA Lo que tenemos que hacer esSMADescubrimos que la función del indicador SMA no es compatible con la biblioteca TA de FMZ. También existen diferencias entre el indicador SMA en la biblioteca talib y el del lenguaje Mai: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado) Como puede ver, además del parámetro de período, también hay un parámetro de peso en la parte de parámetros.

La descripción de la función del indicador SMA en la biblioteca talib en la documentación de la API de FMZ es: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

visibletalib.SMAEs un indicador de media móvil simple. De esta manera, solo puedes implementar uno por ti mismo.SMAComo desarrollador que escribe estrategias utilizando el lenguaje Javascript, esta también es una de las habilidades necesarias. Después de todo, si no hay ruedas ya hechas, el auto necesita ser conducido, así que simplemente construya una.

Para ser honesto, no hay mucha investigación sobre indicadores y cosas por el estilo. Por lo general, si no entiendo algo, simplemente busco información. Para SMA, encontramos lo siguiente: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Considero que el proceso del algoritmo descrito aquí es bastante confiable. Vamos a implementarlo:

  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
  }

Cómo escribir la sección de relleno

Uso del marco de políticasTe enseño a escribir estrategias paso a paso - trasplantar una estrategia de mi lenguajeEl mismo marco en el artículo llena principalmente dos partes: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

En primer lugar, realice el procesamiento de datos de mercado y el cálculo de indicadores. Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Trataremos las funciones del lenguaje Mai una por una:

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

Esta oración puede entenderse como sumar el precio más alto, el precio más bajo y el precio de cierre de cada BAR en los datos de la línea K y dividirlo por 3, calcular el promedio y luego almacenarlo como una matriz, que corresponde a cada BAR. por uno. Esto se puede manejar así:

  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 
  }

Simplemente llame a esta función en la función OnTick del bucle principal, por ejemplo:

  // 计算指标
  // AP
  var ap = CalcAP(records)
  • 2. Una vez completado el cálculo de AP, continúe con el cálculo.ESA:=EMA(AP,N1);:

Aquí necesitamos utilizar los datos de AP calculados en el paso anterior para calcular ESA. De hecho, este ESA es la “media móvil exponencial” de AP, es decir, el indicador EMA, por lo que utilizamos AP como dato y N1 como el parámetro del indicador EMA para calcular el 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);

Utilice el calculadoAPESACalcular datosD。 Puede consultar los comentarios del código aquí para obtener algunos consejos sobre los cálculos de 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 método de cálculo es similar al paso 1 y el código se publica 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); Simplemente calcule el indicador EMA para 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 utiliza la rueda que construimos anteriormente.SMAfunción.

  function CalcWT2 (wt1) {    // WT2:SMA(WT1,4,1);
      if (wt1.length <= 4) {
          return false 
      }  

      return SMA(wt1, 4, 1)   // 使用我们自己实现的SMA函数计算出wt1的SMA指标。
  }

El trasplante de señales comerciales es muy sencillo.

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

Al leer estas frases del código de lenguaje Mai, podemos saber que la señal de cruz dorada y cruz muerta de las dos líneas indicadoras WT1 y WT2 se utilizan como condiciones para abrir una posición. Cabe señalar que se utiliza la señal de cruz anterior. Probamos directamente la estrategia con el lenguaje del micrófono y observamos: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

A través del funcionamiento real de la estrategia del lenguaje Mai, se puede ver que cuando se detecta una señal en el punto de apertura, en realidad está detectando si la posición 2 BARRAS antes del punto de apertura es una cruz dorada. Esto se puede ver claramente en la figura anterior: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado) Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

El código de llenado de la parte de detección de señal 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í podemos pensar por qué las instrucciones SPK y BPK del lenguaje Mai se pueden implementar con el código anterior.

Prueba retrospectiva

Configuración de backtest: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Prueba retrospectiva de la versión en idioma Mai: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

Prueba retrospectiva de la versión de JavaScript: Te enseñaré cómo trasplantar una estrategia lingüística (avanzado) Te enseñaré cómo trasplantar una estrategia lingüística (avanzado)

El código que se encuentra al principio de la función OnTick se utiliza para acelerar el backtesting y ejecutar la estrategia en función del modelo de precio de cierre. Si te interesa, puedes 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
    }
    ...
    ..
    .

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

Gracias por leer