Estrategia de equilibrio dinámico basada en la moneda digital

El autor:- ¿ Por qué?, Creado: 2022-12-01 16:17:29, Actualizado: 2023-09-20 09:43:30

img

I. Resumen

Benjamin Graham, el mentor de Warren Buffett, ha mencionado un modo de negociación de balance dinámico de acciones y bonos en el libro The Intelligent Investor.

img

El modo de negociación es muy simple: - Invertir el 50% de los fondos en fondos de acciones y el 50% restante en fondos de bonos. - De acuerdo con el intervalo fijo o los cambios del mercado, realizar un reequilibrio de activos para restablecer la proporción de activos de acciones y activos de bonos a la proporción original de 1: 1. Esta es la lógica de toda la estrategia, incluyendo cuándo comprar y vender y cuánto comprar y vender.

II. Principio del equilibrio dinámico

En este método, la volatilidad de los fondos de bonos es muy pequeña en realidad, mucho menor que la volatilidad de las acciones, por lo que los bonos se utilizan como "anclajes de referencia" aquí, es decir, para medir si las acciones han aumentado demasiado o demasiado poco por los bonos. Si el precio de las acciones sube, el valor de mercado de las acciones será mayor que el valor de mercado de los bonos. Cuando la relación del valor de mercado de los dos exceda el umbral establecido, la posición total se reajustará, las acciones se venderán y los bonos se comprarán, de modo que la relación del valor de mercado de las acciones y los bonos volverá a la 1:1 original. Por el contrario, si el precio de las acciones disminuye, el valor de mercado de las acciones será menor que el valor de mercado de los bonos. De esta manera, podemos disfrutar de los frutos del crecimiento de las acciones y reducir la volatilidad de los activos equilibrando la proporción entre las acciones y los bonos dinámicamente. Como pionero de la inversión de valor, Graham nos ha proporcionado una buena idea.

III. La lógica de la estrategia

Estrategia de balance dinámico en el activo blockchain BTC

La lógica de la estrategia

  • De acuerdo con el valor actual de BTC, el saldo de la cuenta reserva un efectivo de ¥ 5000 y 0,1 BTC, es decir, la relación inicial de efectivo al valor de mercado de BTC es de 1: 1.
  • Si el precio de BTC aumenta a ¥6000, es decir, el valor de mercado de BTC es mayor que el saldo de la cuenta, y la diferencia entre ellos excede el umbral establecido, luego venda (6000-5000)/6000/2 monedas.
  • Si el precio de BTC disminuye a ¥4000, es decir, el valor de mercado de BTC es menor que el saldo de la cuenta, y la diferencia entre ellos excede el umbral establecido, entonces comprar (5000-4000)/4000/2 monedas.

De esta manera, no importa si BTC se aprecia o se deprecia, siempre mantenemos el saldo de la cuenta y el valor de mercado de BTC igual dinámicamente.

IV. Marco estratégico

Así que, ¿cómo implementarlo en código? Tomamos la plataforma de comercio de FMZ Quant como ejemplo, echemos un vistazo al marco de la estrategia primero:

// function to cancel orders
function CancelPendingOrders() {}

// function to place an order
function onTick() {}

// main function
function main() {
    // filter non-important information
    SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout");
    while (true) { // polling mode
        if (onTick()) { // execute onTick function
            CancelPendingOrders(); // cancel the outstanding pending orders
            Log(_C(exchange.GetAccount)); // print the current account information
        }
        Sleep(LoopInterval * 1000); // sleep
    }
}

En realidad, todo el marco de la estrategia es muy simple, incluyendo una función principal, una función de colocación de pedidos onTick, una función CancelPendingOrders y los parámetros necesarios.

V. Módulo de colocación de órdenes

// order-placing function
function onTick() {
    var acc = _C(exchange.GetAccount); // obtain account information
    var ticker = _C(exchange.GetTicker); // obtain Tick data
    var spread = ticker.Sell - ticker.Buy; // obtain bid ask spread of Tick data
    // 0.5 times of the difference between the account balance and the current position value
    var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2;
    var ratio = diffAsset / acc.Balance; // diffAsset / account balance
    LogStatus('ratio:', ratio, _D()); // Print ratio and current time
    if (Math.abs(ratio) < threshold) { // If the absolute value of the ratio is less than the specified threshold
        return false; // return false
    }
    if (ratio > 0) { // if ratio > 0
        var buyPrice = _N(ticker.Sell + spread, ZPrecision); // Calculate the price of an order
        var buyAmount = _N(diffAsset / buyPrice, XPrecision); // Calculate the order quantity
        if (buyAmount < MinStock) { // If the order quantity is less than the minimum transaction quantity
            return false; // return false
        }
        exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // Purchase order
    } else {
        var sellPrice = _N(ticker.Buy - spread, ZPrecision); // Calculate the price of an order
        var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // Calculate the order quantity
        if (sellAmount < MinStock) { // If the order quantity is less than the minimum transaction quantity
            return false; // return false
        }
        exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // Sell and place an order
    }
    return true; // return true
}

La lógica de negociación de órdenes está bien organizada, y todos los comentarios han sido escritos en el código.

El proceso principal es el siguiente:

  • Obtener información de la cuenta.
  • Obtenga los datos de Tick.
  • Calcular la propagación de la oferta y la demanda de los datos de Tick.
  • Calcular la diferencia entre el saldo de la cuenta y el valor de mercado de BTC.
  • Calcular las condiciones de compra y venta, el precio del pedido y la cantidad del pedido.
  • Ponga un pedido y devuelva verdad.

VI. Módulo de retirada

// Withdrawal function
function CancelPendingOrders() {
    Sleep(1000); // Sleep for 1 second
    var ret = false;
    while (true) {
        var orders = null;
        // Obtain the unsettled order array continuously. If an exception is returned, continue to obtain
        while (!(orders = exchange.GetOrders())) {
            Sleep(1000); // Sleep for 1 second
        }
        if (orders.length == 0) { // If the order array is empty
            return ret; // Return to order withdrawal status
        }
        for (var j = 0; j < orders.length; j++) { // Iterate through the array of unfilled orders
            exchange.CancelOrder(orders[j].Id); // Cancel unfilled orders in sequence
            ret = true;
            if (j < (orders.length - 1)) {
                Sleep(1000); // Sleep for 1 second
            }
        }
    }
}

El módulo de retiro es más sencillo.

  • Espera un segundo antes de cancelar el pedido.
  • Obtener continuamente la matriz de orden no resuelta. Si se devuelve una excepción, continúa obteniendo.
  • Si la matriz de órdenes no resueltas está vacía, el estado de retirada se devolverá inmediatamente.
  • Si hay una orden no resuelta, toda la matriz se atraviesa y la orden se cancela de acuerdo con el número de orden.

VII. Código fuente completo de la estrategia

// Backtest environment
/*backtest
start: 2018-01-01 00:00:00
end: 2018-08-01 11:00:00
period: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/



// Order withdrawal function
function CancelPendingOrders() {
    Sleep(1000); // Sleep for 1 second
    var ret = false;
    while (true) {
        var orders = null;
        // Obtain the unsettled order array continuously. If an exception is returned, continue to obtain
        while (!(orders = exchange.GetOrders())) {
            Sleep(1000); // Sleep for 1 second
        }
        if (orders.length == 0) { // If the order array is empty
            return ret; // Return to order withdrawal status
        }
        for (var j = 0; j < orders.length; j++) { // Iterate through the array of unfilled orders
            exchange.CancelOrder(orders[j].Id); // Cancel unfilled orders in sequence
            ret = true;
            if (j < (orders.length - 1)) {
                Sleep(1000); // Sleep for 1 second
            }
        }
    }
}

// Order function
function onTick() {
    var acc = _C(exchange.GetAccount); // obtain account information
    var ticker = _C(exchange.GetTicker); // obtain Tick data
    var spread = ticker.Sell - ticker.Buy; // obtain bid ask spread of Tick data
    // 0.5 times of the difference between the account balance and the current position value
    var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2;
    var ratio = diffAsset / acc.Balance; // diffAsset / account balance
    LogStatus('ratio:', ratio, _D()); // Print ratio and current time
    if (Math.abs(ratio) < threshold) { // If the absolute value of ratio is less than the specified threshold
        return false; // return false
    }
    if (ratio > 0) { // if ratio > 0
        var buyPrice = _N(ticker.Sell + spread, ZPrecision); // Calculate the order price
        var buyAmount = _N(diffAsset / buyPrice, XPrecision); // Calculate the order quantity
        if (buyAmount < MinStock) { // If the order quantity is less than the minimum trading quantity
            return false; // return false
        }
        exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // buy order
    } else {
        var sellPrice = _N(ticker.Buy - spread, ZPrecision); // Calculate the order price
        var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // Calculate the order quantity
        if (sellAmount < MinStock) { // If the order quantity is less than the minimum trading quantity
            return false; // return false
        }
        exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // sell order
    }
    return true; // return true
}

// main function
function main() {
    // Filter non-important information
    SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout");
    while (true) { // Polling mode
        if (onTick()) { // Execute onTick function
            CancelPendingOrders(); // Cancel pending orders
            Log(_C(exchange.GetAccount)); // Print current account information
        }
        Sleep(LoopInterval * 1000); // sleep
    }
}

Parámetros externos

img

VIII. Pruebas de retroceso de la estrategia

A continuación, vamos a probar esta simple estrategia de equilibrio dinámico para ver si funciona.

Entorno de pruebas de retrocesoimg

Desempeño de las pruebas de retrocesoimg

Curva de pruebas de retrocesoimg

Durante el período de backtest, BTC ha continuado disminuyendo durante hasta 8 meses, incluso con una disminución máxima de más del 70%, lo que hizo que muchos inversores perdieran la confianza en los activos de blockchain.

Obtener el código fuente de la estrategia

El código fuente de la estrategia se ha publicado en el sitio web oficial de FMZ Quant:https://www.fmz.com/strategy/110545No hay necesidad de configurar, se puede backtesting en línea directamente.

X. Resumen

La estrategia de equilibrio dinámico en este artículo tiene solo un parámetro central (umbral), que es un método de inversión muy simple. Lo que persigue no es un rendimiento excesivo, sino un rendimiento constante. Contrariamente a la estrategia de tendencia, la estrategia de equilibrio dinámico es contra la tendencia. Pero la estrategia de equilibrio dinámico es justo lo contrario. Cuando el mercado es popular, reducir la posición, mientras que cuando el mercado es impopular, escalar en la posición, que es similar a la regulación macroeconómica.

De hecho, la estrategia de balance dinámico es un artefacto que hereda el concepto de precios impredecibles y captura las fluctuaciones de precios al mismo tiempo. El núcleo de la estrategia de balance dinámico es establecer y ajustar la relación de asignación de activos, así como el umbral de activación. En vista de la longitud, un artículo no puede ser completo. Debes saber que más allá de las palabras, hay un corazón. La parte más importante de la estrategia de balance dinámico es la idea de inversión. Incluso puedes reemplazar los activos individuales de BTC en este artículo con una cesta de carteras de activos blockchain.

Finalmente, cerremos este artículo con las famosas palabras de Benjamin Graham en el libro The Intelligent Investor: El mercado de valores no es una máquina de pesar que pueda medir el valor con precisión, sino más bien una máquina de voto. Las decisiones tomadas por innumerables personas son una mezcla de racionalidad y sensibilidad. Muchas veces estas decisiones están lejos de juicios de valor racionales. El secreto de la inversión es invertir cuando el precio es mucho más bajo que el valor intrínseco, y creer que la tendencia del mercado se recuperará. Benjamin Graham El inversionista inteligente


Relacionados

Más.