Diseño de estrategias de cobertura de efectivo para monedas digitales (2)

El autor:Un sueño pequeño., Creado: 2021-07-30 16:36:48, Actualizado: 2023-09-20 10:36:43

img

Diseño de estrategias de cobertura de efectivo para monedas digitales (2)

En el artículo anterior, hemos implementado una estrategia de cobertura simple, y ahora vamos a aprender cómo mejorar esta estrategia. Los cambios en la estrategia no son grandes, pero los detalles de los cambios requieren atención. Las definiciones en algunos lugares del código y los cambios anteriores requieren una comprensión crítica.

La necesidad de actualizar esta estrategia

  • Modelo de apalancamiento de los objetos de los intercambios de efectivo Este cambio se refiere solo a discos físicos, y algunas operaciones de contado incluyen todas las interfaces de apalancamiento de contado, que también se envuelven en FMZ.
  • Se muestra el gráfico de diferencias aumentadas La diferencia de aumento en el gráfico muestra, ya que es sólo dibujarA交易所->B交易所B交易所->A交易所La línea horizontal que desencadena la diferencia.画线类库La ventaja es que es sencillo y fácil de usar, y aquí también aprendemos a usar FMZ.模版类库La función.
  • Función de cobertura unilateral Este cambio es muy importante, ya que es difícil invertir completamente la diferencia entre los dos intercambios en el momento de realizar operaciones de cobertura específica. La mayor parte del tiempo, el precio de un intercambio continúa siendo más alto que el precio del otro intercambio. En este momento, si nuestros activos están completamente cubiertos (es decir, todos los billetes están en el intercambio de precios bajos, todo el dinero está en el intercambio de precios altos). La cobertura está estancada y ya no puede depender de la rentabilidad de la fluctuación de los precios.
  • Parámetros como la línea de diferenciación de cobertura de modificación interactiva Se ha añadido funcionalidad de interacción a las políticas, lo que permite modificar en tiempo real las líneas de disparidad.
  • Ordena la información de la barra de estado, mostrándola en forma de tabla Los datos que se necesitan para mostrarlos se organizan para que sean fáciles de observar.

A continuación, vamos a implementar estos diseños uno por uno.

Modelo de apalancamiento de los objetos de los intercambios de efectivo

Usar el código para cambiar al modo de apalancamiento en efectivo, como en el caso del disco real de bitcoins.exchanges[i].IO, el parámetro de entradatrade_normalCambiar a palanca por posición, pasar atrade_super_marginCambiar a toda la posición del palanca, retraso no es compatible. Esto sólo se utiliza en el disco real.

En elmainAumenta la fase de preparación para el inicio de la función:

    // 切换杠杆模式
    for (var i = 0 ; i < exchanges.length ; i++) {   // 遍历检测所有添加的交易所对象
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // 如果当前i索引代表的交易所对象是币安现货,并且策略界面参数marginType选择的不是「普通币币」选项,执行切换
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "设置为杠杆逐仓")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "设置为杠杆全仓")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

Aquí, la política sólo añade el código para el modo de apalancamiento de la moneda de cambio de divisas en efectivo, por lo que la configuración de cambio en los parámetros de la política solo es válida para divisas en efectivo.

Se muestra el gráfico de diferencias aumentadas

Es muy sencillo usar una plantilla de dibujo ya envuelta.画线类库También se puede buscar directamente en la plataforma de estrategias de FMZ.

img

En la página de Facebook de la red social Twitter, se puede ver el siguiente enlace:https://www.fmz.com/strategy/27293En la página de copias de este modelo.

img

El botón puede copiar esta librería de modelos en su propia librería de políticas.

img

Luego, en la página de edición de la política, en la barra de modelos, puede seleccionar la librería de modelos que desea usar. Si selecciona la barra de modelos después de guardar la política, la política se referirá a esta plantilla. Esto es solo una breve descripción del uso de la biblioteca de modelos, la política ya se ha referido a esta plantilla, por lo que no es necesario repetir la operación.画线类库En el blog de la organización, se ha citado el artículo "El mundo está cambiando".

Lo que hacemos es aprender a usarlos.画线类库La función para dibujar el gráfico.

img

Estamos planeandoA->BEl precio de los productos es muy bajo.B->APara obtener la diferencia, se dibujan dos líneas de diferenciación. Se necesitan dos curvas (la diferencia actual de A a B y B a A) y dos líneas horizontales (la diferencia de diferenciación), como en el gráfico anterior.

En el caso de las empresas de seguros, el riesgo es muy bajo.A->ByB->AEn el artículo anterior, el diseño de la línea de disparo no fue el mismo. En el artículo anterior:

      var targetDiffPrice = hedgeDiffPrice
      if (diffAsPercentage) {
          targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
      }

Sólo un disparador.targetDiffPrice¿Qué es esto? Así que aquí vamos a cambiar el código, primero cambiar los parámetros.

img

En la página de Facebook de la empresa, se muestra el código:

        var targetDiffPriceA2B = hedgeDiffPriceA2B
        var targetDiffPriceB2A = hedgeDiffPriceB2A
        if (diffAsPercentage) {
            targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
            targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
        }

La diferencia de precios es el desencadenante de la diferencia de precios.targetDiffPriceUno se convierte en dos.targetDiffPriceA2BtargetDiffPriceB2A¿Qué es esto? A continuación, se puede usar la función de dibujo de línea de la biblioteca de clases de dibujo para dibujar este dato en el gráfico.

        // 画图
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // 该函数第一个参数是水平线在Y轴方向上的值,第二个参数是显示文本
        $.PlotHLine(targetDiffPriceB2A, "B->A")

La estrategia se pone en marcha con un gráfico como este.

img

A continuación, se dibujan las curvas de diferenciación en tiempo real, para evitar excesos. El código de las curvas de diferenciación de datos en tiempo real se coloca en la prueba de equilibrio.

        if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
            nowAccs = _C(updateAccs, exchanges)
            var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
            cancelAll()
            if (isBalance) {
                lastKeepBalanceTS = ts
                if (isTrade) {
                    var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
                    isTrade = false 
                }                
            }

            $.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price)  // 画实时差价曲线
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // 第一个参数是曲线名称,第二个参数是曲线当前时刻的值,即当前时刻Y轴方向上的值
        }

Esto permite que la política se muestre en gráficos mientras se ejecuta, con solo 4 líneas de código gráfico.

Función de cobertura unilateral

En el artículo anterior se menciona que la línea de disparador de la diferencia se ha convertido en dos líneas, respectivamente controladas.A->BEl hecho de que el gobierno de los Estados Unidos no haya hecho nada para ayudar a los refugiados es un hecho.B->AEl precio de compra de los precios de los precios de los precios de los precios de los precios de los precios de los precios de los precios de los precios de los precios de los precios de los precios.

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B 盘口条件满足            
            var priceSell = depthA.Bids[0].Price - slidePrice
            var priceBuy = depthB.Asks[0].Price + slidePrice
            var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
            if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
                Log("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // 提示信息
                hedge(exB, exA, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B -> A 盘口条件满足
            var priceBuy = depthA.Asks[0].Price + slidePrice
            var priceSell = depthB.Bids[0].Price - slidePrice
            var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
            if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
                Log("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // 提示信息
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Si el precio de venta está separado de los precios de compra, entonces el valor de la función de cobertura es el valor de la función de cobertura.hedgeTambién necesita ser modificado.

function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
    var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
    var sellRoutine = sellEx.Go("Sell", priceSell, amount)
    Sleep(500)
    buyRoutine.wait()
    sellRoutine.wait()
}

También hay algunos ajustes mínimos basados en estos cambios, que no se describen aquí, pero pueden verse en el código.

Parámetros como la línea de diferenciación de cobertura de modificación interactiva

Aumentar la interacción con las estrategias para que las estrategias puedan modificar las líneas de disparidad en tiempo real. Esta es una necesidad de diseño de estrategias semiautomáticas, que también se implementan aquí como una demostración de enseñanza. El diseño de la interacción de la política también es muy sencillo, primero añade controles de interacción a la política en la página de edición de la política.

img

Se añaden dos controles, uno llamado A2B y otro llamado B2A. Cuando se introduce un número en el cuadro de entrada del control, se hace clic en el botón de entrada a la derecha.123¿Qué es esto?A2BEste botón envía instrucciones a la política inmediatamente.

A2B:123

Detección de interacción en el diseño y procesamiento de código en el código estratégico.

        // 交互
        var cmd = GetCommand()   // 每次循环执行到这里时,都检测有没有交互指令过来,没有则返回空字符串
        if (cmd) {               // 检测到有交互指令,例如:A2B:123
            Log("接收到命令:", cmd)
            var arr = cmd.split(":")   // 拆分出交互控件名称和输入框中的值,arr[0]就是A2B,arr[1]就是123
            if (arr[0] == "A2B") {     // 判断触发的交互控件是不是A2B
                Log("修改A2B的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // 修改触发差价线
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // 修改触发差价线
                }
            } else if (arr[0] == "B2A") {           // 检测到触发的控件是B2A     
                Log("修改B2A的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Ordena la información de la barra de estado, mostrándola en forma de tabla

Para que los datos de las barras de estado se muestren con más regularidad y facilidad de observación.

        var tbl = {
            "type" : "table", 
            "title" : "数据", 
            "cols" : ["交易所", "币", "冻结币", "计价币", "冻结计价币", "触发差价", "当前差价"], 
            "rows" : [], 
        }
        tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
        tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")

img

Las pruebas

La repetición es solo una estrategia de prueba, una función de detección inicial, y muchos BUG pueden probarse en la etapa de repetición. No es necesario preocuparse demasiado por los resultados de la repetición, la estrategia final todavía requiere una bala real de pistola en el entorno real.

img

img

El código fuente de la estrategia:https://www.fmz.com/strategy/302834


Relacionados

Más.

15570686905Esta estrategia de negociación se suma a la función de contrato, lo que es bueno es añadir contratos permanentes, contratos de intercambio.

Nube ligera- TipoError: No puede leer la propiedad 'SetPrecision' de undefined Estrategias de cobertura de divisas con diferentes divisas Ver 1.1

Un sueño pequeño.Bien, tenemos la oportunidad de dar una lección.

Nube ligeraYa lo entiendo, gracias muchachos.

Un sueño pequeño.Para añadir dos objetos de intercambio.