Discussion sur la conception de la stratégie de haute fréquence Magically Modified Profit Harvester

Auteur:Je suis désolée., Créé à: 2022-04-25 11:49:11, mis à jour à: 2022-04-25 12:04:06

Discussion sur la conception de la stratégie de haute fréquence Magically Modified Profit Harvester

Dans les articles précédents, nous avons analysé les idées et la mise en œuvre du code de la version spontanée originale de la stratégie de récolte de profit à haute fréquence.

Analyse des bénéfices réalisés par le moissonneur (1) Analyse des bénéfices réalisés par le moissonneur (2)

Beaucoup d'utilisateurs dans le cercle de crypto-monnaie quantitative sont très préoccupés par la stratégie développée par un maître appeléimprimer de l'argentLa stratégie deimprimer de l'argentLa stratégie à haute fréquence est similaire au principe de la moissonneuse de bénéfices (le maître Xiaocao a également dit que le principe de la stratégie à haute fréquence est similaire à celui de la moissonneuse de bénéfices).

Par conséquent, j'étais tellement excité que je ne pouvais m'empêcher de vouloir modifier magiquement la stratégie, même le résultat et l'effet de la stratégie magiquement modifiée n'étaient rien face aux stratégies développées par les maîtres. Mais c'est aussi une pratique d'apprentissage pour la stratégie à haute fréquence. Les FMZ intéressés peuvent discuter et en apprendre ensemble.

Une moissonneuse de profit magiquement modifiée.

var TickInterval = 100

function LeeksReaper() {
    var self = {}
    self.numTick = 0
    self.lastTradeId = 0
    self.vol = 0
    self.askPrice = 0
    self.bidPrice = 0
    self.orderBook = {
        Asks: [],
        Bids: []
    }
    self.prices = []
    self.tradeOrderId = 0
    self.account = null
    self.buyPrice = 0
    self.sellPrice = 0
    self.state = 0
    self.depth = null

    self.updateTrades = function() {
        var trades = _C(exchange.GetTrades)
        if (self.prices.length == 0) {
            while (trades.length == 0) {
                trades = trades.concat(_C(exchange.GetTrades))
            }
            for (var i = 0; i < 15; i++) {
                self.prices[i] = trades[trades.length - 1].Price
            }
        }
        self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {
            // Huobi not support trade.Id
            if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
                self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
                mem += trade.Amount
            }
            return mem
        }, 0)

    }
    self.updateOrderBook = function() {
        var orderBook = _C(exchange.GetDepth)
        self.depth = orderBook
        self.buyPrice = orderBook.Bids[pendingLevel].Price
        self.sellPrice = orderBook.Asks[pendingLevel].Price
        self.orderBook = orderBook
        if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
            return
        }
        self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
        self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
        self.prices.shift()
        self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.15 +
            (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
            (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.1 +
            (orderBook.Bids[3].Price + orderBook.Asks[3].Price) * 0.075 +
            (orderBook.Bids[4].Price + orderBook.Asks[4].Price) * 0.05 +
            (orderBook.Bids[5].Price + orderBook.Asks[5].Price) * 0.025))
    }

    self.updateAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        LogProfit(parseFloat(account.Info.totalWalletBalance), account)
    }

    self.CancelAll = function() {
        while (1) {
            var orders = _C(exchange.GetOrders)
            if (orders.length == 0) {
                break
            }
            for (var i = 0; i < orders.length; i++) {
                exchange.CancelOrder(orders[i].Id)
            }
            Sleep(100)
        }
    }

    self.poll = function() {
        self.numTick++
        self.updateTrades()
        self.updateOrderBook()
        var pos = _C(exchange.GetPosition)

        var burstPrice = self.prices[self.prices.length - 1] * burstThresholdPct
        var bull = false
        var bear = false
        LogStatus(_D(), "\n", 'Tick:', self.numTick, 'self.vol:', self.vol, ', lastPrice:', self.prices[self.prices.length - 1], ', burstPrice: ', burstPrice)

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

        if (pos.length != 0) {
            if (pos[0].Type == PD_LONG) {
                self.state = 1
            } else {
                self.state = 2
            }
        } else {
            self.state = 0
        }


        if ((!bull && !bear)) {
            return
        }

        if (bull) {
            var price = (self.state == 0 || self.state == 1) ? self.buyPrice : self.depth.Bids[coverPendingLevel].Price
            var amount = (self.state == 0 || self.state == 1) ? pendingAmount : pos[0].Amount
            exchange.SetDirection("buy")
            exchange.Buy(price, amount)
        } else if (bear) {
            var price = (self.state == 0 || self.state == 2) ? self.sellPrice : self.depth.Asks[coverPendingLevel].Price
            var amount = (self.state == 0 || self.state == 2) ? pendingAmount : pos[0].Amount
            exchange.SetDirection("sell")
            exchange.Sell(price, amount)                    
        }
        self.numTick = 0
        Sleep(TickInterval)
        self.CancelAll()
        self.updateAccount()
    }

    while (!self.account) {
        self.updateAccount()
        Sleep(500)
    }
    Log("self.account:", self.account)

    return self
}

function main() {
    LogProfitReset()
    exchange.SetPrecision(pricePrecision, amountPrecision)
    exchange.SetContractType("swap")
    var reaper = LeeksReaper()  
    while (true) {
        reaper.poll()
        Sleep(100)
    }
}

img

Idée de modification

La stratégie est prévue pour le commerce sur le marché des contrats Binance USDT, qui prend en charge les positions unidirectionnelles. Par conséquent, la stratégie est modifiée et conçue en fonction des caractéristiques des positions unidirectionnelles (les positions unidirectionnelles sont plus pratiques pour la modification de la stratégie), et vous n'avez qu'à envisager d'acheter et de vendre, pas besoin de penser à la fermeture des positions. Cette façon de penser est également plus proche de la version au comptant de la moissonneuse de bénéfices.

La stratégie maintient essentiellement le critère de rupture de tendance des prix à court terme d'origine et la fourchette de rupture des prix à court terme est contrôlée par le paramètreburstThresholdPct. Selon le critère de détermination du prix à court termebulloubear.

La stratégie supprime certains modules de l'original, tels que le module de solde. Une modification assez importante consiste à changer la mise en place des ordres à des ordres en attente dans le carnet de commandes et en attente d'exécution. Il est prévu qu'il ouvre des positions à un coût relativement faible sur un marché chaotique avec un jeu long-short féroce, suit la tendance à court terme et ferme des positions lorsque la tendance à court terme s'inverse, puis continue à inverser les ordres en attente et les positions ouvertes.

Bien que la stratégie soit une stratégie peu rentable, même avec des pertes, c'est un modèle très facile et utile pour un FMZer d'apprendre des stratégies à haute fréquence, d'observer les actions des stratégies à haute fréquence, d'observer les règles microscopiques du marché, etc. Le trading programmé et quantitatif doit être basé sur beaucoup de pratique, d'expérience et de théories.

Courez dans le bot

img

On constate qu'il est plus difficile d'ouvrir et de fermer des positions lorsque la situation du marché n'est pas active.

Optimisation de la stratégie

À l'heure actuelle, aucune bonne orientation d'optimisation n'a été trouvée. Les élèves intéressés peuvent s'exprimer et en discuter ensemble.

Adresse stratégique:https://www.fmz.com/strategy/260806

La stratégie est seulement pour l'étude; quand le marché est plat, l'exécuter dans le bot pourrait faire des pertes.


Plus de