Estratégia de equilíbrio dinâmico baseada na moeda digital

Autora:Lydia., Criado: 2022-12-01 16:17:29, Atualizado: 2023-09-20 09:43:30

img

I. Resumo

Benjamin Graham, mentor de Warren Buffett, mencionou um modo de negociação de balanço dinâmico de ações e títulos no livro The Intelligent Investor.

img

O modo de negociação é muito simples: - Inverter 50% dos fundos em fundos de acções e os restantes 50% em fundos de obrigações, ou seja, as acções e as obrigações representam metade uma da outra. - De acordo com o intervalo fixo ou as alterações do mercado, realizar um reequilíbrio de activos para restabelecer a proporção de activos de acções e activos de obrigações para a proporção original de 1:1. Esta é a lógica de toda a estratégia, incluindo quando comprar e vender e quanto comprar e vender.

II. Princípio do equilíbrio dinâmico

Neste método, a volatilidade dos fundos de obrigações é muito pequena, na verdade, muito menor do que a volatilidade das ações, de modo que as obrigações são usadas como ancoras de referência aqui, isto é, para medir se as ações subiram muito ou muito pouco por obrigações. Se o preço das ações subir, o valor de mercado das ações será maior do que o valor de mercado dos títulos. Quando a relação do valor de mercado dos dois exceder o limiar estabelecido, a posição total será reajustada, as ações serão vendidas e os títulos serão comprados, de modo que a relação do valor de mercado das ações e títulos retornará ao original de 1: 1. Em contrapartida, se o preço das ações diminuir, o valor de mercado das ações será menor do que o valor de mercado dos títulos. Quando a relação do valor de mercado dos dois exceder o limiar estabelecido, a posição total será reajustada, as ações serão compradas e os títulos serão vendidos, de modo que a relação do valor de mercado das ações e títulos retornará ao original de 1: 1. Desta forma, podemos desfrutar dos frutos do crescimento das ações e reduzir a volatilidade dos ativos equilibrando a proporção entre ações e títulos dinamicamente. Como pioneiro do investimento de valor, Graham nos forneceu uma boa ideia.

III. Lógica estratégica

Estratégia de equilíbrio dinâmico no ativo blockchain BTC

Estratégia lógica

  • De acordo com o valor atual de BTC, o saldo da conta reserva um dinheiro de ¥5000 e 0,1 BTC, ou seja, a relação inicial de dinheiro para o valor de mercado de BTC é de 1: 1.
  • Se o preço do BTC aumenta para ¥6000, ou seja, o valor de mercado do BTC é maior do que o saldo da conta, e a diferença entre eles excede o limite estabelecido, então venda (6000-5000)/6000/2 moedas.
  • Se o preço do BTC diminuir para ¥4000, ou seja, o valor de mercado do BTC é menor que o saldo da conta, e a diferença entre eles excede o limite estabelecido, então compre (5000-4000)/4000/2 moedas.

Desta forma, não importa se o BTC se valoriza ou se deprecia, sempre mantemos o saldo da conta e o valor de mercado do BTC igual dinamicamente.

IV. Quadro estratégico

Então, como implementá-lo em código? Tomamos a plataforma de negociação FMZ Quant como exemplo, vamos dar uma olhada no quadro de estratégia primeiro:

// 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
    }
}

A estrutura da estratégia é realmente muito simples, incluindo uma função principal, uma função de colocação de ordens onTick, uma função CancelPendingOrders e os parâmetros necessários.

V. Módulo de colocação de ordens

// 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
}

A lógica de negociação de ordens está bem organizada, e todos os comentários foram escritos no código.

O processo principal é o seguinte:

  • Obtenha informações da conta.
  • Obtenha os dados do Tick.
  • Calcular a propagação de oferta e demanda dos dados do Tick.
  • Calcular a diferença entre o saldo da conta e o valor de mercado do BTC.
  • Calcular as condições de compra e venda, preço da encomenda e quantidade da encomenda.
  • Faça uma encomenda e devolva a verdade.

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
            }
        }
    }
}

O módulo de retirada é mais simples.

  • Espera um segundo antes de cancelar a encomenda.
  • Continuamente obter a matriz de ordem não resolvida.
  • Se a matriz de ordens não liquidadas estiver vazia, o estado de retirada será devolvido imediatamente.
  • Se houver uma ordem não resolvida, toda a matriz é atravessada e a ordem é cancelada de acordo com o número da ordem.

VII. Código fonte completo da estratégia

// 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. Backtesting da estratégia

Em seguida, vamos testar esta simples estratégia de equilíbrio dinâmico para ver se funciona.

Ambiente de ensaio de retrocessoimg

Desempenho dos testes de retornoimg

Curva de ensaio de retrocessoimg

Durante o período de backtest, o BTC continuou a diminuir por até 8 meses, mesmo com um declínio máximo de mais de 70%, o que fez com que muitos investidores perdessem a confiança nos ativos blockchain.

Obter o código fonte da estratégia

O código fonte da estratégia foi publicado no site oficial da FMZ Quant:https://www.fmz.com/strategy/110545Não há necessidade de configurar, você pode backtesting online diretamente.

X. Resumo

A estratégia de equilíbrio dinâmico neste artigo tem apenas um parâmetro central (limite), que é um método de investimento muito simples. O que ele busca não é um retorno em excesso, mas um retorno constante. Ao contrário da estratégia de tendência, a estratégia de equilíbrio dinâmico é contra a tendência. Mas a estratégia de equilíbrio dinâmico é exatamente o oposto.

Na verdade, a estratégia de balanço dinâmico é um ofício que herda o conceito de preços imprevisíveis e capta flutuações de preços ao mesmo tempo. O núcleo da estratégia de balanço dinâmico é definir e ajustar a taxa de alocação de ativos, bem como o limiar de gatilho. Em vista do comprimento, um artigo não pode ser abrangente. Você deve saber que além das palavras, há um coração. A parte mais importante da estratégia de balanço dinâmico é a ideia de investimento. Você pode até substituir os ativos individuais de BTC neste artigo por uma cesta de carteiras de ativos blockchain.

Finalmente, vamos encerrar este artigo com as famosas palavras de Benjamin Graham no livro The Intelligent Investor: O mercado de ações não é uma máquina de pesagem que pode medir o valor com precisão, mas sim uma máquina de votação. As decisões tomadas por inúmeras pessoas são uma mistura de racionalidade e sensibilidade. Muitas vezes essas decisões estão longe de julgamentos de valor racionais. O segredo do investimento é investir quando o preço é muito menor do que o valor intrínseco, e acreditar que a tendência do mercado vai se recuperar. Benjamin Graham O Investidor Inteligente


Relacionados

Mais.