Analyse de la stratégie de LeeksReaper (2)

Auteur:Je ne sais pas., Créé: 2022-11-07 16:38:41, Mis à jour: 2023-09-15 21:07:34

img

Analyse de la stratégie de LeeksReaper (2)

Continuons d'expliquer le contenu du dernier chapitre (https://www.fmz.com/bbs-topic/9725).

La troisième fonction ajoutée:

    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log ( \"\" Start Balance \"\", self. P)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
            }
        } else if (self.p > 0.52) {
            Log ( \"\" Start Balance \"\", self. P)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

Lorsque le constructeurLeeksReaper ()construit un objet, lebalanceAccount ()La fonction ajoutée à l'objet met à jour les informations sur les actifs du compte stockées dans leself.account, c'est-à-dire leaccountcalculer la valeur du revenu et l'imprimer à temps. Ensuite, selon les dernières informations de l'actif du compte, calculer le ratio de solde de la monnaie des spots (solde de la position des spots), lors du déclenchement du seuil de décalage, fermer la position avec un petit ordre, de sorte que la monnaie (position) retour à l'état d'équilibre. Attendre un certain temps pour traiter, puis annuler tous les fabricants, le prochain tour d'exécution de la fonction, il vérifiera le solde et effectuera à nouveau le traitement correspondant.

Examinons le code de cette fonction phrase par phrase: Premièrement, la première phrasevar account = exchange.GetAccount ()déclare une variable localeaccountet appelle la fonction deexchange.GetAccountsur l'interface FMZ API. Obtenez les dernières données du compte courant et l'assigner à la variableaccountAlors jugez la variableaccount. Si la variable estnull(par exemple, temps d'arrêt, réseau, exception d'interface d'échange, etc.), il retournera (correspondant àif (!account) {...}) directement.

self.account = accountest d'attribuer la variable localeaccountà laaccountattribut de l'objet construit permettant d'enregistrer les dernières informations de compte dans l'objet construit.

Var now = new Date().getTime ()déclare une variable localenowet appelle legetTime()attribue une valeur à la variablenow.

if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)){...}détermine que si la différence entre l'horodatage actuel et l'horodatage enregistré la dernière fois dépasse le paramètreCalcNet Interval * 1000, cela signifie qu'il a été mis à jour depuis la dernière fois.CalcNetInterval * 1000en millisecondes (CalcNetIntervalLe prix d'achat d'une imprimante est utilisé pour calculer le revenu.self.orderBook.Bids.length > 0est également défini dans la condition (données de profondeur, il doit y avoir des informations de niveau valides dans la liste d'ordre).self.PreCalc = nowest exécuté pour mettre à jour la variable timestamp de la déclaration imprimée la plus récenteself.preCalcà l'horodatage actuelnowDans ce cas, la méthode de calcul de la valeur nette est utilisée dans les statistiques de rendement.var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), c'est-à-dire convertir la monnaie en argent (monnaie libellée) en fonction du prix d'achat actuel, puis l'ajouter au montant de l'argent sur le compte et l'assigner à la variable locale déclaréenet. Jugez si la valeur nette totale actuelle est compatible avec la valeur nette totale enregistrée la dernière fois:

            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }

Si ce n'est pas cohérent, c'est à dire,net! = self.preNetest vrai, mettre à jour l'attribut deself.preNetutilisé pour enregistrer la valeur nette avec la variablenet. Ensuite imprimer le total net denetles données à la courbe de rendement du robot de la plateforme de trading FMZ Quant (leLogProfitLa fonction peut être consultée dans le document de l'API FMZ).

Si l'impression régulière des gains n'est pas déclenchée, continuez le processus suivant pour enregistrer leaccount.Stocks(monnaie disponible sur le compte courant) et leaccount.Balance(monnaie disponible dans le compte courant) dans leself.BTCetself.CNY. Calculer l'échelle de décalage et enregistrer l'affectation dans leself.p.

self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)

L'algorithme est également très simple, qui consiste à calculer le pourcentage de la valeur courante de la monnaie à la valeur nette totale du compte.

Que dire de juger quand déclencher le solde monétaire (position)? Ici, je prends 50% plus ou moins 2 points de pourcentage comme tampon, et exécute le solde au-delà du tampon, c'est-à-dire si leself.p < 0.48, le solde monétaire est déclenché par déviation. Si l'argent est inférieur, le prix augmentera de 0,01 à chaque fois de la position d'achat à l'ouverture du marché, et trois petits ordres seront organisés.self.p > 0.52, si la devise est plus, vendre un et libérer de petites commandes. enfin, annuler toutes les commandes après avoir attenduSleep(BalanceTimeout)pendant un certain temps selon les paramètres.

        Var orders = exchange. Get Orders () # Get all current makers, with orders variable
        If (orders) { # If the variable orders used to obtain the current order data is not null
            for (var i = 0; i < orders.length; I + +) { # Loop through orders and cancel orders one by one
                if (orders[i].Id != self.tradeOrderId) {
                    Exchange. CancelOrder (orders [I]. Id) # Call exchange. CancelOrder to cancel orders based on orders [I]. Id
                }
            }
        }

La quatrième fonction ajoutée:

Dans la partie centrale de la stratégie, voici le jeu principal.self.poll = function(){...}La stratégie de l'UE pour l'emploi et la promotion de l'innovation est une stratégie qui a pour objectif de renforcer la compétitivité et la compétitivité des entreprises.main()fonction commence à exécuter et entre dans l'infiniwhileLa boucle, nous utilisonsvar reaper = LeeksReaper()pour construire l'objet leeksreaper, puis exécuter l'appel de boucle dereaper.poll()dans lemain() function.

Leself.pollLa fonction commence à s'exécuter, en effectuant des travaux préparatoires avant chaque boucle.self.numTick++Le nombre d'infections augmente.self.updateTrades()Il met à jour les récents enregistrements de négociation sur le marché et calcule les données d'utilisation pertinentes.self.updateOrderBook()Les données relatives aux commandes sont mises à jour et calculées.self.balanceAccount()vérifier le solde monétaire (position).

        Var burstPrice = self. Prices [self. Prices. Length-1] * BurstThresholdPct # Calculate Burst Price
        Var bull = false                   # Declare a bull-marked variable, initially false
        Var bear = false                  # Declare a bear marked variable, initially false
        Var tradeAmount = 0         # Declare the transaction amount variable, initially 0

L'étape suivante consiste à juger si le marché à court terme actuel est un taureau ou un ours.

        if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
            )) {
            bull = true
            tradeAmount = self.cny / self.bidPrice * 0.99
        } else if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
            )) {
            bear = true
            tradeAmount = self.btc
        }

Vous vous souvenez duself.updateOrderBook()fonction de l'article précédent où nous avons utilisé un algorithme de moyenne pondérée pour construire un ordre temporelpricesTrois nouvelles fonctions:_.min, _.max, etslicesont utilisés dans le code et sont faciles à comprendre.

· _. min: La fonction consiste à trouver la valeur minimale dans le tableau de paramètres.

· _.max: La fonction consiste à trouver la valeur maximale dans le tableau de paramètres.

· slice: La fonction est une fonction membre de l'ensemble des fonctionsJavaScriptIl est utilisé pour retourner une partie du tableau selon l'index. Par exemple:

function main() {
    // index     .. -8 -7 -6 -5 -4 -3 -2 -1
    var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    Log (arr. Slice (-5, -1))   // it will intercept the elements from 4 to 1 and return a new array: [4,3,2,1]
}

img

Les conditions pour juger un marché baissier ou haussier sont les suivantes:

· Leself.numTick > 2doit être vrai, c'est-à-dire que lorsqu'une nouvelle série de prix de détection éclate, elle doit être déclenchée après au moins trois séries de détection, afin d'éviter de déclencher au début. · la différence entre les dernières données de laself.pricesLes prix de l'ensemble des prix de l'ensemble des prix de l'ensemble des prix de l'ensemble des prix de l'ensemble des prix de l'ensemble des prix de l'ensemble des prix.self.pricesLe prix de l'ensemble devrait dépasser le prix de rupture deburstPrice.

Si toutes les conditions sont vraies, marquerbulloubearcomme vrai, et attribuer une valeur à la variabletradeAmountpour planifier la transaction avec Stud.

Dans ce cas, selon leself.volLes résultats de l'enquête ont été mis à jour et calculés au cours de l'année précédente.self.updateTrades()fonction, leBurstThresholdVolLe paramètre détermine si l'intensité de la transaction doit être réduite (réduire le volume de transaction prévu).

        if (self.vol < BurstThresholdVol) {
            TradeAmount * = self. Vol/BurstThresholdVol      //Reduce the planned volume by self. Vol/BurstThresholdVol times of the previous volume
        }
        
        if (self.numTick < 5) {
            TradeAmount * = 0.8      // reduced to 80% of the plan
        }
        
        If (self. NumTick < 10) {       // reduce to 80% of the plan
            tradeAmount *= 0.8
        }

Ensuite, jugez si le signal de négociation et le volume répondent aux exigences:

        If ( (!Bull && !Bear) | | tradeAmount &lt; MinStock) {     # If it is not a bull market and not a bear market, or the amount tradeAmount planned to trade is less than the minimum trading volume MinStock set by the parameter, the poll function returns without trading operations directly
            return
        }

Après le jugement susmentionné, exécutervar tradePrice = bull ? self.bidPrice: self.askPricefixe le prix de la transaction selon qu'il s'agit d'un marché baissier ou d'un marché haussier, et attribue la valeur avec le prix du connaissement correspondant.

Enfin, unewhileLa seule condition d'arrêt de la boucle est que le volume de négociation prévu detradeAmount > = MinStockest inférieure au volume de négociation minimum. Dans la boucle, l'ordre est exécuté en fonction de l'état actuel du marché.orderId. Sleep(200)Il attend 200 millisecondes après avoir placé une commande dans chaque boucle.orderIdest vrai (si l'ordre échoue, l'identifiant d'ordre ne sera pas retourné, et la condition if ne sera pas déclenchée).self.tradeOrderId.

Déclarer une variableorderutilisé pour stocker les données de commande, avec une valeur initiale denull. Ensuite, les données d'ordre de l'ID sont obtenues dans une boucle, et juger si l'ordre est l'état de fabricant, si oui, l'ordre de l'ID est annulé, et si non, la boucle de détection est terminée.

                Var order = null         // Declare a variable to hold the order data
                While (true) {             // a while loop
                    Order = exchange. GetOrder (orderId)          // Call GetOrder to query the order data whose order ID is orderId
                    If (order) {                                                   // If the order data is queried and the query fails and the order is null, the current if condition will not be triggered
                        If (order. Status = = ORDER _ STATE _ PENDING) {              // Judge whether the order status is maker
                            Exchange. CancelOrder (orderId)                                    // If the order is maker, cancel the order
                            Sleep(200)
                        } else {                                                                               // otherwise execute break to end the current while loop
                            break
                        }
                    }
                }

Le procédé suivant est ensuite effectué:

                Self. TradeOrderId = 0                         // Reset self. TradeOrderId.
                TradeAmount-= order. DealAmount    // Update tradeAmount, subtract the quantity of the order on the bill of lading that has been completed
                TradeAmount * = 0.9                          //Decrease the order amount
                If (order. Status = = ORDER _ STATE _ CANCELED) {                   // if the order is already cancelled
                    Self. UpdateOrderBook ()                                                      // Update data such as order book
                    While (bull & & self. BidPrice-tradePrice &gt; 0.1) {               // In a bull market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    While (bear & & self. AskPrice-tradePrice &lt; -0.1) {             // In a bear market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
                        tradeAmount *= 0.99
                        tradePrice -= 0.1
                    }
                }

Lorsque le processus de programme se termine de la boucle dewhile (tradeAmount > = MinStock){...}, il indique que l'exécution de ce processus de transaction d'éclatement des prix est terminée. Exécuter leself.numTick = 0, c'est-à-dire réinitialiserself.numTickà 0.

LeLeeksReaper()Le constructeur renvoie leselfobjet à la fin de l'exécution, c'est-à-dire lorsquevar reaper = LeeksReaper(), il est renvoyé àreaper.

Jusqu'à présent, nous avons analysé comment leLeeksReaper()constructeur construit l'objet LeeksReaper, chaque méthode de l'objet LeeksReaper, et le processus d'exécution des principales fonctions logiques. Je crois que vous aurez une compréhension claire de ce processus d'algorithme de stratégie à haute fréquence après avoir lu cet article.


Relationnée

Plus de