Análise estratégica da máquina de colheita de laranja (2)

Autora:Sonhos pequenos, Criado: 2020-11-16 10:03:52, Atualizado: 2023-09-26 21:05:07

img

Análise estratégica da máquina de colheita de laranja (2)

E depoisConteúdo para cima e para trásAfinal, o que é isso?

A terceira função adicionada:

    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("开始平衡", 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("开始平衡", 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)
                }
            }
        }
    }

Construção de funçõesLeeksReaper()O que é adicionado ao objeto quando ele é construído?balanceAccount()A função é atualizar as informações de ativos da conta, armazenarself.accountO que é que é isso?accountPropriedade:. Calcular o valor do ganho em tempo real e imprimir. Em seguida, com base nas informações mais recentes sobre os ativos da conta, calcular a proporção do saldo da moeda corrente (equilíbrio da posição corrente), realizar um pequeno equilíbrio da moeda quando o desvio do limiar for desencadeado, para que a moeda (posições) volte ao equilíbrio. Esperar um certo tempo para negociar, depois cancelar todos os pendentes, executar a função no próximo round, novamente detectar o saldo e fazer o tratamento correspondente.

Vejamos o código para esta função, palavra por palavra: Primeiro, a primeira frase.var account = exchange.GetAccount()É uma variável local declarada.accountA partir daí, o usuário pode usar o aplicativo para criar um código de usuário.exchange.GetAccount()A função que obtém os dados mais recentes da conta atual e atribui valor aaccountVariações.accountA variável é igual anullO valor (por exemplo, falha de obtenção de problemas de tempo de espera, rede, interface de câmbio e outras anomalias) é devolvido diretamente (correspondente)if (!account){...}Aqui.

self.account = accountE isso é uma variação local.accountO valor atribuído aos objetos construídosaccountAs propriedades são usadas para registrar as informações mais recentes da conta em objetos construídos.

var now = new Date().getTime()Esta frase declara uma variável local.nowA partir de agora, o tempo de data é o tempo de data que você precisa para fazer uma chamada.getTime()A função retorna o tempo atual.nowVariações.

if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}Este código determina o diferencial entre o momento atual e o momento da última gravação se exceder o parâmetro.CalcNetInterval * 1000O que significa que desde a última atualização, já é mais do que isso.CalcNetInterval * 1000MilissegundosCalcNetIntervalSegundo), a função de imprimir ganhos em tempo real, já que o cálculo do ganho deve ser feito usando o preço de compra de um na lista, portanto, as condições também são limitadas.self.orderBook.Bids.length > 0Esta condição ((Depth Data, a lista de pagamentos deve ter informações de nível válidas) ‒ executa-se quando esta condição de if-statement é ativada.self.preCalc = nowAtualize a variável do cronômetro da última receita de impressãoself.preCalcO que é o tempo atualnowA estatística de ganhos aqui é baseada no cálculo do valor líquido, codificado como:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))O que significa que a moeda é convertida em dinheiro (a moeda de cálculo) de acordo com o preço de compra atual e somada à quantidade de dinheiro na conta com a variável local atribuída à declaração.net❖ Julgar se o total líquido atual e o total líquido registrado da última vez coincidem:

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

Se não estiverem de acordo,net != self.preNetÉ verdade.netAtribuições de atualização de variáveis para registrar o valor líquidoself.preNetE depois imprima isto.netOs dados de patrimônio líquido total para os inventores podem ser consultados na documentação da FMZ APILogProfitEsta função) ⋅

Se não tiver sido ativado o ganho de impressão de tempo, continue com o processo abaixo, e você terá um resultado positivo.account.StocksO número de moedas disponíveis na conta correnteaccount.Balance(quantidade de dinheiro disponível na conta corrente)self.btcself.cnyO cálculo da proporção de desvio e a atribuição são registrados noself.p

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

O algoritmo também é simples: calcula o valor atual da moeda como uma porcentagem do total da conta líquida.

A partir de agora, o que acontece com o balanço monetário? O autor aqui usa 50% para cima e 2 pontos percentuais para baixo como um amortecedor, excedendo o equilíbrio de execução da zona de amortecimento, ou seja,self.p < 0.48O desvio do equilíbrio monetário é desencadeado, pensando que há menos moeda, basta comprar uma posição no mercado e começar a aumentar o preço 0,01 a cada vez, colocando três folhetos.self.p > 0.52A partir daí, a empresa começou a vender uma folha de papel em uma loja de conveniência.Sleep(BalanceTimeout)O Facebook também divulgou uma mensagem sobre o assunto.

        var orders = exchange.GetOrders()                  # 获取当前所有挂单,存在orders变量
        if (orders) {                                      # 如果获取当前挂单数据的变量orders不为null
            for (var i = 0; i < orders.length; i++) {      # 循环遍历orders,逐个取消订单
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)     # 调用exchange.CancelOrder,根据orders[i].Id取消订单
                }
            }
        }

A quarta função adicionada:

A parte central da estratégia, a grande novidade, está chegando.self.poll = function() {...}A função é a principal lógica de toda a estratégia, e nós falamos sobre isso no artigo anterior,main()A função começa a executar e entrawhileAntes do ciclo da morte, nós usamosvar reaper = LeeksReaper()A partir daí, construímos um objeto para a colheita de amendoim, e o colocamos em uma máquina de colheita de amendoim.main()Chamadas circulares em funçõesreaper.poll()É a função a ser chamada.

self.pollA função começa a ser executada, fazendo algumas preparações antes de cada ciclo.self.numTick++O número de mortos aumentou.self.updateTrades()Atualize os registros de transações recentes no mercado e calcule os dados de uso.self.updateOrderBook()A partir de agora, o número de pedidos será atualizado e os dados serão calculados.self.balanceAccount()A partir de agora, o banco vai continuar a fazer o balanço da moeda.

        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct   # 计算爆发价格
        var bull = false             # 声明牛市标记的变量,初始为假
        var bear = false             # 声明熊市标记的变量,初始为假
        var tradeAmount = 0          # 声明交易数量变量,初始为0

O próximo passo é julgar se o mercado de curto prazo é um "bull" ou um "bear".

        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
        }

E lembre-se do artigo anterior.self.updateOrderBook()A função, em que nós construímos uma sequência de tempo em ordem, usando um algoritmo de média ponderada.pricesArrays. Três novas funções são usadas neste código._.min_.maxsliceA função é uma função que é muito bem compreendida.

  • _.minA função : é o menor valor da matriz de parâmetros que se procura.

  • _.maxA função : é a busca do valor maior da matriz de parâmetros.

  • sliceA função : é uma função membro de um objeto de um conjunto de arquivos JavaScript que retorna uma parte do conjunto de arquivos que foi selecionada de acordo com o índice, por exemplo:

    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))    // 会截取 4 ~ 1 这几个元素,返回一个新数组:[4,3,2,1]
    }
    

    img

A condição para julgar um urso ou uma vaca é:

  • self.numTick > 2Para se estabelecer, ou seja, quando um novo ciclo de preços de testes surge, é necessário passar por pelo menos três rodadas de testes antes de ser desencadeado, evitando o desencadeamento no início.
  • Sequência de preçosself.pricesO último dado, que é o mais recente, é o deself.pricesA diferença de preço máxima ou mínima de uma faixa anterior da matriz deve ser ultrapassada.burstPriceO preço da explosão.

Se todas as condições forem cumpridas, marquebullOubearParatruee dartradeAmountA mudança de valor, o planejamento de negócios hip hop.

A partir de agora,self.updateTrades()Atualização, cálculo de funçõesself.volPara os parâmetrosBurstThresholdVolDecidir se vai reduzir a intensidade das transações (reduzir a quantidade de transações planejadas).

        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol   // 缩减计划交易量,缩减为之前量的self.vol / BurstThresholdVol 倍
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8      // 缩减为计划的80%
        }
        
        if (self.numTick < 10) {    // 缩减为计划的80%
            tradeAmount *= 0.8
        }

A seguir, os sinais de negociação e o volume de negociação são avaliados:

        if ((!bull && !bear) || tradeAmount < MinStock) {   # 如果非牛市并且也非熊市,或者计划交易的量tradeAmount小于参数设置的最小交易量MinStock,poll函数直接返回,不做交易操作
            return
        }

Após o julgamento acima, executarvar tradePrice = bull ? self.bidPrice : self.askPriceDe acordo com o mercado de ursos ou de touros, o preço de negociação é definido e o preço de cobrança correspondente é atribuído.

Finalmente, entrou em umwhileA única condição para parar de saltar do ciclo é:tradeAmount >= MinStockA quantidade de transações planejadas é menor que a quantidade mínima de transações. No ciclo, execute a ordem seguinte, dependendo do estado atual do mercado de touros ou de ursos, e registre o ID único na variável.orderId◎ Depois de fazer o pedido de cada cicloSleep(200)Espere 200 milissegundos.orderIdSe for verdade (se a encomenda falhar e não retornar o ID da encomenda, a condição if não será acionada), se a condição for verdadeira.self.tradeOrderId

Declare uma variável para armazenar dados de pedidosorderA atribuição inicial énullO ciclo então obtém dados de pedidos desse ID e decide se o pedido está pendente, se está pendente, cancele o pedido desse ID e salte do ciclo de detecção se não estiver pendente.

                var order = null           // 声明一个变量用于保存订单数据
                while (true) {             // 一个while循环
                    order = exchange.GetOrder(orderId)    // 调用GetOrder查询订单ID为 orderId的订单数据
                    if (order) {                          // 如果查询到订单数据,查询失败order为null,不会触发当前if条件
                        if (order.Status == ORDER_STATE_PENDING) {   // 判断订单状态是不是正在挂单中
                            exchange.CancelOrder(orderId)            // 如果当前正在挂单,取消该订单
                            Sleep(200)
                        } else {                                     // 否则执行break跳出当前while循环
                            break
                        }
                    }
                }

A seguir, execute o seguinte processo:

                self.tradeOrderId = 0              // 重置self.tradeOrderId
                tradeAmount -= order.DealAmount    // 更新tradeAmount,减去提单的订单已经成交的数量
                tradeAmount *= 0.9                 // 减小下单力度
                if (order.Status == ORDER_STATE_CANCELED) {     // 如果订单已经是取消了
                    self.updateOrderBook()                      // 更新订单薄等数据
                    while (bull && self.bidPrice - tradePrice > 0.1) {   // 牛市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {  // 熊市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格
                        tradeAmount *= 0.99
                        tradePrice -= 0.1
                    }
                }

Quando o processo de programação saiwhile (tradeAmount >= MinStock) {...}Quando este ciclo é completado, o processo de negociação do estouro do preço é concluído. Execuçãoself.numTick = 0O que é que isso significa?self.numTickÉ igual a 0.

LeeksReaper()A função de construção será executada no final.selfO objeto volta, ou seja,var reaper = LeeksReaper()A partir de então, a empresa começou a vender o produto.reaper

Até aqui.LeeksReaper()Como as funções de construção são construídas para este objeto da colher de sopa e os diferentes métodos de execução dos objetos da colher de sopa, as principais funções lógicas, analisamos novamente, e acredito que você deve ter uma compreensão mais clara deste processo de algoritmo de estratégia de alta frequência depois de ler este artigo.


Mais.

XukittyA ideia de combinar a máquina de colheita de louro com o robô de alta frequência do deus da erva não deu certo?

Mattzhang1988Ele disse um monte de disparates.

CyndiYY1024Há um pouco de incompreensão, por que é necessário manter o equilíbrio da moeda e do dinheiro, se o equilíbrio não for atingido, você terá que comprar e vender. Depois de passar pelo BalanceTimeout, cancele a ordem novamente, deixe o equilíbrio e entre para o próximo ciclo de explosão.

A força de DamascoOnde está o comando abaixo?

Eddie, não.No vídeo anterior, no nevoeiro de nuvens, uma FMZ foi usada para rever o vídeo. Monitorar os fluxos de preços no mercado, detectar explosões de preços, seguir a direção da tendência, calcular a porcentagem de hip-hop com base no tamanho do volume de negociação como referência, e realizar transações de hip-hop. Após a transação de hip-hop, não se mantém o estoque, mantendo um estado de equilíbrio monetário no longo prazo. Eu disse, certo, Dream General?

XukittyPor favor, ensine-me, o programa está sempre no equilíbrio de moeda e dinheiro, o que é essa função?

XukittyObrigado Dreamz, a FMZ é um verdadeiro tesouro.

ImprimirOu não entendi.

O que foi?O que é este parâmetro BurstThresholdVol?

Evan1987O vídeo é repleto de detalhes, e depois de uma hora de visualização, eu mal entendo os detalhes.

RootmeO meu sonho é 666, e depois de investigar, descobri que posso escrever uma máquina de colheita de couve que seja a mesma que a do dinheiro impresso.

Sonhos pequenosGrasshopper tem um artigo sobre a necessidade de um ambiente de mercado de alta frequência.

Sonhos pequenosDesculpe, mas este artigo é principalmente para iniciantes em como executar o processo, e um monte de disparates é realmente incrível, você pode ignorá-lo.

Sonhos pequenosÓptimo!

Sonhos pequenosA primeira máquina de colheita de laranja tinha um módulo de equilíbrio que poderia ser removido.

Sonhos pequenosNão é educado.

Sonhos pequenosNão, não.

Sonhos pequenosO número de explosões, que é um parâmetro de política, é artificialmente definido, e se você olhar em detalhes para a política ou o artigo, você saberá o que essa variável controla.

Sonhos pequenosO princípio deve ser mais ou menos o mesmo.