Stratégie de balance dynamique basée sur la monnaie numérique

Auteur:Je ne sais pas., Créé: 2022-12-01 16:17:29, Mis à jour: 2023-09-20 09:43:30

img

I. Résumé

Benjamin Graham, le mentor de Warren Buffett, a mentionné un mode de négociation dynamique des actions et des obligations dans le livre L'investisseur intelligent.

img

Le mode de négociation est très simple: - investir 50% des fonds dans des fonds d'actions et les 50% restants dans des fonds d'obligations. - en fonction de l'intervalle fixe ou des variations du marché, procéder à un rééquilibrage des actifs pour ramener la proportion des actifs boursiers et des actifs obligataires à l'original de 1:1. C'est la logique de toute la stratégie, y compris quand acheter et vendre et combien acheter et vendre.

II. Principe de l'équilibre dynamique

Dans cette méthode, la volatilité des fonds obligataires est en fait très faible, bien inférieure à la volatilité des stocks, de sorte que les obligations sont utilisées ici comme "ancres de référence", c'est-à-dire pour mesurer si les stocks ont augmenté trop ou trop peu par les obligations. Si le prix des actions augmente, la valeur marchande des actions sera supérieure à la valeur marchande des obligations. Lorsque le ratio de valeur marchande des deux dépasse le seuil fixé, la position totale sera réajustée, les actions seront vendues et les obligations achetées, de sorte que le ratio de valeur marchande des actions et des obligations reviendra à l'original de 1:1. Au contraire, si le prix des actions diminue, la valeur marchande de l'action sera inférieure à la valeur marchande des obligations. Lorsque le ratio de valeur marchande des deux dépasse le seuil fixé, la position totale sera réajustée, les actions seront achetées et les obligations seront vendues, de sorte que le ratio de valeur marchande des actions et des obligations reviendra à l'original de 1:1. De cette façon, nous pouvons profiter des fruits de la croissance des actions et réduire la volatilité des actifs en équilibrant dynamiquement la proportion entre les actions et les obligations.

III. La logique de la stratégie

Stratégie de balance dynamique dans l'actif blockchain BTC

La logique de la stratégie

  • Selon la valeur actuelle des BTC, le solde du compte réserve un liquidité de ¥5000 et 0,1 BTC, c'est-à-dire que le ratio initial de l'argent liquide par rapport à la valeur marchande des BTC est de 1:1.
  • Si le prix du BTC augmente à ¥6000, c'est-à-dire que la valeur marchande du BTC est supérieure au solde du compte et que la différence entre eux dépasse le seuil fixé, alors vendez (6000-5000)/6000/2 pièces. Cela signifie que le BTC s'est apprécié et que nous pouvons échanger l'argent.
  • Si le prix de BTC diminue à ¥4000, c'est-à-dire que la valeur marchande de BTC est inférieure au solde du compte et que la différence entre eux dépasse le seuil fixé, alors achetez (5000-4000)/4000/2 pièces. Cela signifie que le BTC s'est déprécié et que nous pouvons racheter BTC.

De cette façon, peu importe si BTC s'apprécie ou s'amortit, nous gardons toujours le solde du compte et la valeur marchande de BTC dynamiquement égaux.

IV. Cadre stratégique

Alors, comment l'implémenter dans le code? Nous prenons la plateforme de trading FMZ Quant comme exemple, jetons un coup d'œil au cadre stratégique d'abord:

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

L'ensemble du cadre de stratégie est très simple en fait, y compris une fonction principale, une fonction de commande onTick, une fonction CancelPendingOrders et les paramètres nécessaires.

V. Module de placement de commandes

// 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 logique de négociation des ordres est bien organisée, et tous les commentaires ont été écrits dans le code.

Le processus principal est le suivant:

  • Obtenez des informations sur le compte.
  • Prends les données de Tick.
  • Calculer l'écart entre les offres et les demandes des données Tick.
  • Calculer la différence entre le solde du compte et la valeur marchande des BTC.
  • Calculer les conditions d'achat et de vente, le prix de commande et la quantité de commande.
  • Faites une commande et retournez vraie.

VI. Module de retrait

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

Le module de retrait est plus simple: les étapes sont les suivantes:

  • Attends une seconde avant d'annuler la commande.
  • Obtenir continuellement le tableau d'ordre non réglé. Si une exception est renvoyée, continuer à obtenir.
  • Si le tableau des ordres non réglés est vide, l'état de retrait est renvoyé immédiatement.
  • S'il y a un ordre non réglé, l'ensemble du tableau est traversé et l'ordre est annulé selon le numéro d'ordre.

VII. Code source complet de la stratégie

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

Paramètres extérieurs

img

VIII. Retrospective de la stratégie

Ensuite, testons cette stratégie d'équilibrage dynamique simple pour voir si elle fonctionne.

Environnement de contre-testimg

Performance des tests de retourimg

courbe de rétro-testimg

Au cours de la période de backtest, le BTC a continué à baisser jusqu'à 8 mois, même avec une baisse maximale de plus de 70%, ce qui a fait perdre confiance à de nombreux investisseurs dans les actifs blockchain. Le rendement cumulé de cette stratégie est jusqu'à 160%, et le ratio de risque de rendement annualisé dépasse 5.

Obtenez le code source de la stratégie

Le code source de la stratégie a été publié sur le site officiel de FMZ Quant:https://www.fmz.com/strategy/110545Il n'y a pas besoin de configurer, vous pouvez backtesting en ligne directement.

X. Résumé

La stratégie d'équilibre dynamique dans cet article n'a qu'un seul paramètre de base ( seuil), qui est une méthode d'investissement très simple. Ce qu'elle poursuit n'est pas un rendement excédentaire, mais un rendement régulier. Contrairement à la stratégie de tendance, la stratégie d'équilibre dynamique est contre la tendance. Mais la stratégie d'équilibre dynamique est tout le contraire. Lorsque le marché est populaire, réduire la position, tandis que lorsque le marché est impopulaire, élargir la position, ce qui est similaire à la régulation macroéconomique.

En fait, la stratégie de balance dynamique est un métier qui hérite du concept de prix imprévisibles et capture en même temps les fluctuations de prix. Le noyau de la stratégie de balance dynamique est de définir et d'ajuster le ratio d'allocation des actifs, ainsi que le seuil de déclenchement. Compte tenu de la longueur, un article ne peut pas être complet. Vous devez savoir qu'au-delà des mots, il y a un cœur. La partie la plus importante de la stratégie de balance dynamique est l'idée d'investissement. Vous pouvez même remplacer les actifs BTC individuels dans cet article par un panier de portefeuilles d'actifs blockchain.

Enfin, terminons cet article avec les célèbres mots de Benjamin Graham dans le livre The Intelligent Investor: Le marché boursier n'est pas une machine à peser qui peut mesurer la valeur avec précision, mais plutôt une machine à voter. Les décisions prises par d'innombrables personnes sont un mélange de rationalité et de sensibilité. Benjamin Graham L'investisseur le plus intelligent


Relationnée

Plus de