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.account
O que é que é isso?account
Propriedade:. 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.account
A 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 aaccount
Variações.account
A variável é igual anull
O 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 = account
E isso é uma variação local.account
O valor atribuído aos objetos construídosaccount
As 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.now
A 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.now
Variaçõ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 * 1000
O que significa que desde a última atualização, já é mais do que isso.CalcNetInterval * 1000
MilissegundosCalcNetInterval
Segundo), 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 > 0
Esta 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 = now
Atualize a variável do cronômetro da última receita de impressãoself.preCalc
O que é o tempo atualnow
A 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.net
Atribuições de atualização de variáveis para registrar o valor líquidoself.preNet
E depois imprima isto.net
Os dados de patrimônio líquido total para os inventores podem ser consultados na documentação da FMZ APILogProfit
Esta 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.Stocks
O número de moedas disponíveis na conta correnteaccount.Balance
(quantidade de dinheiro disponível na conta corrente)self.btc
,self.cny
O 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.48
O 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.52
A 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 entrawhile
Antes 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.poll
A 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.prices
Arrays. Três novas funções são usadas neste código._.min
,_.max
,slice
A função é uma função que é muito bem compreendida.
_.min
A função : é o menor valor da matriz de parâmetros que se procura.
_.max
A função : é a busca do valor maior da matriz de parâmetros.
slice
A 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]
}
A condição para julgar um urso ou uma vaca é:
self.numTick > 2
Para 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.self.prices
O último dado, que é o mais recente, é o deself.prices
A diferença de preço máxima ou mínima de uma faixa anterior da matriz deve ser ultrapassada.burstPrice
O preço da explosão.Se todas as condições forem cumpridas, marquebull
Oubear
Paratrue
e dartradeAmount
A mudança de valor, o planejamento de negócios hip hop.
A partir de agora,self.updateTrades()
Atualização, cálculo de funçõesself.vol
Para os parâmetrosBurstThresholdVol
Decidir 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.askPrice
De 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 umwhile
A única condição para parar de saltar do ciclo é:tradeAmount >= MinStock
A 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.orderId
Se 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 pedidosorder
A atribuição inicial énull
O 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 = 0
O que é que isso significa?self.numTick
É igual a 0.
LeeksReaper()
A função de construção será executada no final.self
O 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.
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.
Inventor quantificado - sonho pequenoGrasshopper tem um artigo sobre a necessidade de um ambiente de mercado de alta frequência.
Inventor quantificado - sonho pequenoDesculpe, mas este artigo é principalmente para iniciantes em como executar o processo, e um monte de disparates é realmente incrível, você pode ignorá-lo.
Inventor quantificado - sonho pequenoÓptimo!
Inventor quantificado - sonho pequenoA primeira máquina de colheita de laranja tinha um módulo de equilíbrio que poderia ser removido.
Inventor quantificado - sonho pequenoNão é educado.
Inventor quantificado - sonho pequenoNão, não.
Inventor quantificado - sonho pequenoO 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.
Inventor quantificado - sonho pequenoO princípio deve ser mais ou menos o mesmo.