O recurso está a ser carregado... Carregamento...

Discussão sobre Design de Estratégia de Alta Frequência Magicamente Modificado Recolhedor de Lucro

Autora:Ninabadass, Criado: 2022-04-25 11:49:11, Atualizado: 2022-04-25 12:04:06

Discussão sobre Design de Estratégia de Alta Frequência Magicamente Modificado Recolhedor de Lucro

Nos artigos anteriores, analisamos as ideias e implementação de código da versão spot original da estratégia de colheita de lucro de alta frequência.

Análise dos produtores de lucro (1) Análise dos produtores de lucros (2)

Muitos usuários no círculo de criptomoedas quantitativas estão muito preocupados com a estratégia desenvolvida por um mestre chamadoimprimir dinheiroA estratégia deimprimir dinheiroA partir da observação e análise de muitos seguidores, pode-se ver que a estratégia de alta frequência é semelhante ao princípio da colheita de lucro (o mestre Xiaocao também disse que o princípio da estratégia de alta frequência é semelhante ao da colheita de lucro). Mas deve haver alguma sutileza que permita que uma estratégia tenha uma taxa de ganho estável e uma proporção de lucro/perda adequada.

Portanto, eu estava tão animado que eu não podia deixar de querer modificar magicamente a estratégia, mesmo o resultado e efeito da estratégia magicamente modificada não era nada diante das estratégias desenvolvidas pelos mestres.

Magicamente modificado Recolhimento de Lucro

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

Ideia de modificação

A estratégia é planejada para negociar no mercado de contratos Binance USDT, que suporta posições unidirecionais. Portanto, a estratégia é modificada e projetada de acordo com as características das posições unidirecionais (posições unidirecionais são mais convenientes para modificação de estratégia), e você só precisa considerar a compra e venda, não precisa pensar em fechar posições.

A estratégia mantém basicamente o critério original de ruptura da tendência de preços a curto prazo e a faixa de ruptura de preços a curto prazo é controlada pelo parâmetroburstThresholdPct. De acordo com o critério para determinar se o preço a curto prazo ébulloubear.

A estratégia remove alguns módulos do original, como o módulo de balanço. Uma modificação bastante grande é mudar a colocação de ordens para ordens pendentes na carteira de pedidos e aguardando execução. Espera-se que abra posições a um custo relativamente baixo no mercado caótico com um jogo longo e curto acirrado, siga a tendência de curto prazo e feche posições quando a tendência de curto prazo se inverter e, em seguida, continue a executar ordens pendentes e posições abertas de forma inversa.

A estratégia remove outro código inútil, por isso é muito curta e simples. Embora a estratégia seja uma estratégia não lucrativa, mesmo com perdas, é um modelo muito fácil e útil para um FMZer aprender estratégias de alta frequência, observar as ações de estratégias de alta frequência, observar as regras microscópicas do mercado, etc. A negociação programada e quantitativa precisa ser baseada em muita prática, experiência e teorias.

Corra no Bot

img

Pode-se observar que é mais difícil abrir e fechar posições quando a situação do mercado não é ativa.

Optimização da Estratégia

No momento, não foi encontrada uma boa direcção de otimização. Os alunos, que estão interessados, podem falar ativamente e discutir juntos.

Endereço estratégico:https://www.fmz.com/strategy/260806

A estratégia é apenas para estudo; quando o mercado está plano, executá-lo no bot pode causar perdas.


Mais.