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

FMZ tutorial para iniciantes

Autora:Ervas daninhas, Criado: 2019-04-09 11:29:07, Atualizado: 2024-02-06 17:35:38

[TOC]

img

1.Começar com a plataforma FMZ

Esta é uma instrução básica para iniciantes, para uma versão completa da nossa documentação API, verifiqueFMZ APIHá muitas especificações óbvias que não estão cobertas neste tutorial deixado para você descobrir.

Depois de aprender todo o tutorial, você saberá como funciona o FMZ e poderá escrever algumas estratégias básicas.

1.1 Sobre a plataforma FMZ

O que é a plataforma FMZ?

A FMZ é uma plataforma de negociação automatizada para comerciantes de criptomoedas com suporte para muitos mercados de câmbio de bitcoin / et / altcoin.

O que é que a FMZ pode fazer por ti?

Você pode aprender a escrever seus bots ((estratégias) a partir de nossa estratégias quadrado que contém muitos código de código aberto, compartilhar o código de sua estratégias com os outros, pedir ajuda profissional a qualquer momento, executar sua estratégia em muitas trocas, controlar seu bot no site com computador ou celular, vender suas estratégias se quiser, comunicar com muitos outros amantes de auto-trading em nossogrupoEm uma palavra, FMZ é uma plataforma perfeita para aqueles que querem fazer negociação automatizada.

Quais trocas de Criptomoedas o FMZ suporta?

FMZ suporta quase todas as trocas que são populares, tais comoBinance, Bitfinex, Bitstamp, OKEX, Huobi, Poloniex, etc. também pode negociar futuros emOKEXeBitMEXVerifique a lista completa de apoio emAPIVocê só precisa escrever uma estratégia e executá-lo em todas as trocas sem quaisquer alterações.

Que linguagens de programação o FMZ suporta?

FMZ suporta JavaScript, Python, C ++ (JavaScript e Python são recomendados) para codificar suas estratégias.

A tua API KEY está segura?

De facto, as suas chaves de API são salvas depois de criptografadas.

  • Você precisa inserir a senha FMZ Ao adicionar a chave. O navegador da Web irá criptografar sua chave API e passar a chave criptografada para o servidor FMZ usandohttps.
  • Você precisa inserir a senha FMZ quando você executa o docker em seu servidor ou computador.
  • O FMZ enviará a chave criptografada para o seu docker usando https quando você iniciar um bot. O docker irá decifrar para obter a chave.
  • O FMZ não guarda a sua senha (apenas a senha Hash).
  • É melhor usar um segundo login de verificação FMZ.

Lista de funcionalidades atuais:

  • 1.Cross-platform, suporte para todas as principais bolsas de criptomoedas mais em breve
  • 2.Suporte para a troca simulada. https://wex.app/
  • 3.Tem um sistema eficaz de simulação de backtesting.
  • 4.Suporte para enviar e-mails, enviar mensagens para a sua conta de telegrama.
  • 5.Controlo baseado na web, acessível através do telemóvel.
  • 6.Apoia a programação Python\C++\JavaScript.
  • 7.O custo é extremamente baixo. 0,125 RMB por hora, cerca de 0,018 dólares.
  • 8.NoA FMZ funciona há mais de quatro anos sem problemas de segurança.

1.2 Um rápido início de utilização da plataforma FMZ

Para executar um bot, você precisa ter uma estratégia, adicionar uma troca, implantar um docker primeiro. o docker é o executor de sua estratégia executando em seu próprio computador ou servidor.

Uma rápida visão da página principal

img

  • 1.Página de controlo principal
  • 2.Gerenciar todos os seus bots (iniciar, parar, apagar, abrir, etc.)
  • 3.Gerenciar todas as suas estratégias código
  • 4.Implementar e gerir o seu docker
  • 5.Adicionar novas bolsas
  • 6.Negociação manual nas bolsas que adicionou
  • 7. Pague a conta
  • 8.Faça qualquer pergunta aqui
  • 9.Excâmbio simulado das FMZ
  • 10. Ferramenta de depuração onde você pode executar um bloco de código sem iniciar um bot.
  • 11.Todos os tipos de mensagens
  • 12.Quadrado de estratégia onde estão listadas as estratégias de código aberto e de cobrança
  • 13.Robôs ao vivo, onde estão listados todos os bots em funcionamento.
  • 14.Fóruns onde pode publicar uma mensagem para discutir qualquer questão relacionada.
  • 15.Pedir a alguém que escreva código para si ou que forneça este serviço a outros.
  • 16.Produtos destinados a bolsas e agências.
  • 17.Documentação API.
  • 18.Algumas ferramentas úteis, verifique por si próprio.
  • 19.As informações da sua conta.

Adicionar uma troca

Adicionar emhttps://www.fmz.com/m/add-platform, ou cliquePlatformetiqueta. A sua chave de acesso e chave secreta podem ser aplicadas na bolsa de criptomoedas. API-KEY é usado para negociar e obter as informações privadas da bolsa. Pode registar-se nas FMZTroca simuladae adicioná-lo para testes.

img

Implementar um docker

O FMZ não executa bots para você, você precisa implantar um docker por si mesmo como executor, o que é mais flexível e seguro, já que nosso serviço não participa da execução de seus bots.

Para as janelas, é bastante fácil, basta seguir as instruçõeshttps://www.fmz.com/m/add-node

img

Para o Linux, você pode alugar um VPS em nosso site, que irá implantar o docker automaticamente.

  • 1.Compre um servidor em nuvem (VPS) da Amazon ou do Google, a configuração mais baixa e mais barata é suficiente.
  • 2.Logue-se no seu servidor, siga as instruções do seu provedor de servidor ou pesquise no Google.
  • 3.Escolha o docker que corresponda à sua versão do sistema, na maioria das vezes, é 64 bits.
  • 4. Por centavos, corre.wget www.fmz.com/dist/robot_linux_amd64.tar.gzNão encontramos comando?yum install wget -y.
  • 5.Run tar -xzvf robot_linux_amd64.tar.gzpara desligar.
  • 6.Run ./robot -s node.fmz.com/xxxxx -p -p yourFMZpasswordDevias ver algo como:2018/07/05 05:04:10 Login OK, SID: 62086, PID: 7226, Name: host.localdomainO que significa que tudo está resolvido.node.fmz.com/xxxxxé único para cada utilizador, encontrar o seu própriohttps://www.fmz.com/m/add-node.
  • 7.Agora, o docker não é executado em segundo plano, se fechar o cliente SHH, o docker vai parar. Pressionectrl + Cpara parar o docker.
  • 8.Run nohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &para executar em segundo plano. este passo também pode ser feito porScreen command.
  • 9.Verificarhttps://www.fmz.com/m/nodes, se tudo estiver bem, você pode encontrar o docker implantado lá.

Escreva uma estratégia

Você deve escrever sua própria estratégia ou comprar do quadrado. Aqui vamos usar uma estratégia simples JavaScript como uma demonstração para mostrar como usar a página de edição.https://www.fmz.com/strategy/125482- Não. Este tutorial não vai cobrir como usar JavaScript como você pode encontrar muitos tutoriais on-line.

img

  • 1.Editar o seu código
  • 2.Backtesting, vamos cobrir esta parte num tutorial intermediário
  • 3.A linguagem de programação do seu código, JavaScript foi usado nesta demonstração
  • 4.O título, , divide o chinês e o inglês, o qual será mostrado é decidido pela língua do sítio da FMZ.
  • 5.O tipo da sua estratégia, o incumprimento é comum
  • 6.A categoria da sua estratégia: pode dividir as suas estratégias em diferentes categorias se tiver demasiadas
  • 7.Editar remotamente o seu código a partir do seu próprio IDE em vez do nosso website
  • 8.Um link para o documento API
  • 9.Notas da estratégia (apenas para ser visto por si).
  • 10.Descrições da estratégia: outras pessoas verão as descrições se partilhar ou vender a sua estratégia na Square.
  • 11.Manual da estratégia, só pode ser visto quando alguém comprou a sua estratégia.
  • 12.Salvar o seu código, ouCtrl+Sno modo de edição.
  • 13.Salvar a configuração de backtesting no código.
  • 14.Downloado ficheiro de estratégia
  • 15.Exportar e importar a estratégia mantendo todos os parâmetros
  • 16.Mudar o tamanho da fonte e editar o tema
  • 17.Formatar o código automaticamente
  • 18.Usar o modo VIM para editar.

Para enviar a mensagem para o seu telefone, você precisa vincular o telegrama à sua conta emhttps://www.fmz.com/m/account

/*
This strategy will send a message to your telegram when the price is higher or lower than
the set price.
All strategies must have a main function as the entrance.
*/
function main() {
     //change symbol,will cover the default symbol which was set when start a bot.Currency is a strategy arguments
    exchange.IO("currency", Currency)   
    var lastPushTime = 0    //the variable of last push timestamp.
    while(true){    //run a infinite loop, which is the basic structure
        //_C() function can retry the request automatically after failure. not necessary. var ticker = exchange.GetTicker() is ok.
        var ticker = _C(exchange.GetTicker) // for information about GetTicker, check on https://fmz-docs.readthedocs.io/en/latest/code_Instruction/Market%20API.html#getticker
        if(ticker.Last > UpPrice || ticker.Last < LowPrice){    //ticker.Last represents the last deal price
            if(Date.now() - lastPushTime > 300*1000){    //only push once in 5 mins, Date.now() return ms.
                lastPushTime = Date.now()    //update lastPushTime
                Log(Currency, 'Price is: ', ticker.Last, '@')    //Log the price on the bot's page and sent the message. '@' in the end means push message
            }
        }
        Log(Currency, 'Price is: ', ticker.Last) //just log the price
        Sleep(Interval*1000)    //check the last price again after Interval seconds
    }
}

Acerte o bot.

Finalmente, chegou a hora de executar um bot. NoRobotpágina, cliqueAdd robot, ou visitarhttps://www.fmz.com/m/add-robotdiretamente para adicionar um bot.img

  • 1.Nome do bot
  • 2. O docker para executar este bot
  • 3.A estratégia a executar
  • 4.Os parâmetros e o valor por defeito podem ser alterados.
  • 5. Período de Kline por defeito quando se utiliza a troca.GetRecords()
  • 6.Exchange
  • 7.Tradingsímbolo ou pares
  • 8.Se o símbolo de negociação de que necessita não estiver na lista, pode digitá-lo sozinho.
  • 9.Clickpara adicionar a troca
  • 10.A troca já adicionada.Múltiplas trocas podem ser adicionadas num bot, acesso porexchanges[0], exchanges[1]
  • 11.Clickpara gerir o robô!

Gerencie o bot

NoRobotPágina, pode ver que o bot está a funcionar.img

  • 1.Bot nome, clique aqui para bot página.
  • 2.Estratégia executada pelo bot, clique aqui para a página de estratégia.
  • 3.Estado do bot. Pode estar em execução, parado, erro.
  • 4.O lucro do bot, passado porLogProfit()Pode ser qualquer número que quiser.
  • 5.A data criada pode ser alterada para o último horário de comunicação.
  • 6.Monitorar o bot. FMZ enviará uma mensagem quando o bot foi parado acidentalmente
  • 7. Parem o robô.

Clique no nome do bot na página do bot para mais informações:img

2.A introdução da API mais utilizada

Esta parte irá introduzir algumas das API mais usadas, para uma versão completa da nossa documentação API, verifique noFMZ API- Não. É altamente recomendado para iniciantes executar o código de demonstração emPágina de depuração.

2.1 Registo

Utilizar: Log(msg) Parâmetros:cordas ou númerosDescrição:Regista uma mensagem na página de registro do robô.Retorno:NenhumDemo:

function main() {
    var msg = 'msg string'
    Log(msg)
    Log('hello', 'world', 123)
    Log("red color message", "#FF0000")
    Log("push this message to telegram!@") // won't push on debug page
}

2.2 GetTicker

Utilizar: exchange.GetTicker() Parâmetros:NenhumDescrição:Obtenha o tique do mercado atual.Retorno:

{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}

Demo:

function main() {
    var ticker = exchange.GetTicker()
    Log(ticker)
    Log('Last Price: ',ticker.Last, 'Bid Price: ', ticker.Buy)
}

2.3 Profundidade

Utilizar: exchange.GetDepth() Parâmetros:NenhumDescrição:Obtenha o livro de pedidos do mercado atual.Retorno:

{
    "Info":null,
    "Asks":[
        {"Price":5866.38,"Amount":0.068644},
        {"Price":5866.39,"Amount":0.263985},
        {"Price":5866.73,"Amount":0.05},
        {"Price":5866.77,"Amount":0.05},
        {"Price":5867.01,"Amount":0.15},
        {"Price":5875.89,"Amount":0.05},
        ......
        ]
    "Bids":[
        {"Price":5865.13,"Amount":0.001898},
        {"Price":5865,"Amount":0.085575},
        {"Price":5864.15,"Amount":0.013053},
        {"Price":5863.65,"Amount":0.016727},
        {"Price":5863.51,"Amount":0.128906},
        {"Price":5863.15,"Amount":0.2}
        ......
        ],
    "Time":1530241857399
}

Demo:

function main() {
    var depth = exchange.GetDepth()
    Log(depth)
    Log('Bid one: ', depth.Bids[0].Price, 'Ask one: ', depth.Asks[0].Price)
}

2.4 GetRecords

Utilizar: exchange.GetRecords(), exchange.GetRecords(Period) Parâmetros:

Nome Tipo Obrigatório Descrição
Período Varble global Não, não. O ciclo de Klines, Parâmetros opcionais, ciclo de linha K padrão é definido ao iniciar o robô.

Todos os parâmetros possíveis:PERIOD_M11 minuto,PERIOD_M5Cinco minutos.PERIOD_M1515 minutos.PERIOD_M3030 minutos.PERIOD_H11h,PERIOD_D11d.Descrição:Arranja barras Kline/candlestick para o mercado atual.Retorno:

[
    {"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
    {"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
    {"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
    ......
]

Demo:

//A useful JavaScript example using Records to get a close array:
function main(){
    var close = []
    var records = exchange.GetRecords(PERIOD_H1)
    Log('total bars: ', records.length)
    for(var i=0;i<records.length;i++){
        close.push(records[i].Close)
    }
    return close
}

2.5 GetAccount

Utilizar: exchange.GetAccount() Parâmetros:NenhumDescrição:Obter informações da contaRetorno:

{
    "Stocks":0.38594816,// free base asset
    "FrozenStocks":0,    //locked base asset
    "Balance":542.858308,//free quote asset
    "FrozenBalance":0     //locked quote asset
    "Info":{} //the raw data
}

Demo:

//A useful JavaScript example of Log your account value for a certain trading pair:
function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var account = exchange.GetAccount()
        var price = ticker.Buy
        var stocks = account.Stocks + account.FrozenStocks
        var balance = account.Balance + account.FrozenBalance
        var value = stocks*price + balance
        Log('Account value is: ', value)
        LogProfit(value)
        Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
        //when run in debug tool, add a break here
    }
}

2.6 Comprar

Utilizar: exchange.Buy(Price, Amount), exchange.Buy(Price, Amount, Msg) Parâmetros:

Nome Tipo Obrigatório Descrição
Preço Número - Sim, sim. Preço de compra da ordem limite
Montante Número - Sim, sim. Valor da ordem limite
Msg Corda Não, não. Adicionar uma mensagem extra na página de registro

Descrição:Envie uma ordem de compra e um registro de compra na página do botRetorno:devolver o OrderID se for bem sucedido,null- Se não.Demo:

//A useful JavaScript example of Buy for buy certain amount of bitcoin at a certain price:
function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var price = ticker.Sell
        if(price >= 7000){
            exchange.Buy(price+5, 1, 'BTC-USDT')
        }
        Sleep(3000)//Sleep 3000ms
    }
}

2.7 Vender

Utilizar: exchange.Sell(Price, Amount), exchange.Sell(Price, Amount, Msg) Parâmetros:

Nome Tipo Obrigatório Descrição
Preço Número - Sim, sim. Preço de venda da ordem limite
Montante Número - Sim, sim. valor da ordem limite
Msg Corda Não, não. Adicionar uma mensagem extra na página de registro

Descrição:Envie uma ordem de venda e um registro de venda na página do botRetorno:devolver o OrderID se for bem sucedido,null- Se não.Demo:

//A useful JavaScript example of Buy for buy certain amount of bitcoin at a certain price:
function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var price = ticker.Buy
        if(price >= 7000){
            var id = exchange.Sell(price-5, 1, 'BTC-USDT')
            Log('OrderId: ', id)
        }
        Sleep(3000)
    }
}

2.8 GetOrder

Utilizar: exchange.GetOrder(OrderId) Parâmetros:

Nome Tipo Obrigatório Descrição
Ordem Número - Sim, sim. Identificação do pedido

Descrição:Obtenha os detalhes da encomenda pela identificação da encomenda.Retorno:

{
    "Id":125723661,
    "Amount":0.01,
    "Price":7000,
    "DealAmount":0,
    "AvgPrice":0,
    "Status":0, // 0:Not filled, 1:Filled, 2:Canceled
    "Type":1,// 0:Buy, 1:Sell
    "ContractType":"",//just for futures contract orders
    "Info":{} //raw info from exchange
    }
}

Demo:

//A JavaScript example of using this API, which will buy until your account has 5 coins:
function main(){
    while(true){
        var amount = exchange.GetAccount().Stocks
        var ticker = exchange.GetTicker()
        var id = null
        if(5-amount>0.01){
            id = exchange.Buy(ticker.Sell, Math.min(10-amount,0.2))
        }else{
            Log('Job completed')
            return //return the main function, bot will stop
        }
        Sleep(3000) //Sleep 3000ms
        if(id){
            var status = exchange.GetOrder(id).Status
            if(Status == 0){
                exchange.CancelOrder(id)
            }
        }
    }
}

2.9 GetOrders

Utilizar: exchange.GetOrders() Parâmetros:NenhumDescrição:Obter todas as ordens abertas para os seus símbolos de negociação.Retorno:Uma lista de ordens abertas, o resultado tem o mesmo significado queGetOrder()

[
    {
        "Info":{},
        "Id":16387538,
        "Amount":1123,
        "Price":0.00012826,
        "DealAmount":0,
        "AvgPrice":0,
        "Status":0,
        "Type":1,
        "ContractType":""
    }
]

Demo:

//A JavaScript example of using this API, which will cancel all open orders for trading symbol:
fuction CancelAll(){
    var orders = exchange.GetOrders()
    for(var i=0;i<orders.length,i++){
        exchange.CancelOrder(orders[[i].Id) // cancel order by orderID
    }
}
function main(){
    CancelAll()
    while(true){
        //do something
        Sleep(10000)
    }
}

2.10 Cancelar encomenda

Utilizar: exchange.CancelOrder(OrderId) Parâmetros:

Nome Tipo Obrigatório Descrição
Ordem Número - Sim, sim. Identificação do pedido

Descrição:Cancelar uma encomenda por ID de encomenda.Retorno:tipo bool,truesignifica que o pedido de ordem foi cancelado com êxito.falsesignifica que o pedido de cancelamento da encomenda não foi efetuado.

2.11 SetContractType

Utilizar: exchange.SetContractType(ContractType) Parâmetros:

Nome Tipo Obrigatório Descrição
Tipo de contrato Corda - Sim, sim. Tipo de contrato

Descrição:Definir o tipo de contrato para negociação de futuros. deve ser definido primeiro antes de usar outra API privada.Retorno:NenhumDemo:

exchange.SetContractType("this_week") //OKEX future has “this_week”, “next_week”, “quarter” , "swap"
exchange.SetContractType("XBTUSD") //BitMEX future has "XBTUSD","XBTM19",etc

2.12 GetPosition

Utilizar: exchange.GetPosition() Parâmetros:NenhumDescrição:Obtenha as informações de posição atuais, apenas para negociação de futuros.Retorno:Uma lista de posições, retornará a lista vazia se a conta não tiver posição.Demo:

// Note: GetPosition function obtains all positions.
function main(){
    exchange.SetContractType("this_week") //for OKEX future
    var position = exchange.GetPosition()
    if(position.length>0){
        Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
            position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type, "ContractType:",                     position[0].ContractType)
    }
}

2.13 SetDireção

Utilizar: exchange.SetDirection(Direction) Parâmetros:

Nome Tipo Obrigatório Descrição
Direção Corda - Sim, sim. pode serbuy, closebuy, sell, closesell.

Descrição:Os tipos de ordens de compra ou venda definidos, apenas para negociação de futuros.Retorno:NenhumDemo:

function main(){
    exchange.SetContractType("this_week");
    exchange.SetMarginLevel(5) // Set the leverage to 5 times
    exchange.SetDirection("buy") // Set the order type to buy long
    exchange.Buy(5000, 2) //buy long at the price 1000, quantity of 2
    exchange.SetDirection("closebuy")
    exchange.Sell(4999, 2) //close long position
}

2.14 Outras funções comumente utilizadas:

Verifique mais detalhes sobre essas funções no FMZDocumentos da API

Nome Descrição Exemplo
LogStatus Registre uma mensagem ou uma tabela na barra de status dos bots, irá atualizar a cada vez LogStatus('msg')
_C Função de tentativa de novo _C(exchange.GetRecords,PERIOD_H1),_C(exchange.GetTicker)
_N Função de posição _N(4001.512,2),_N(num,0)
_G Um dicionário global que pode ser salvo depois de reiniciar o robô. _G('initValue', 1000);_G('initValue')
_D Retorna o carimbo de hora _D(), _D(1478570053241)
TA Biblioteca de indicadores TA-Lib. suporteMACD, EMA, KDJetc... TA.MACD(records)
Math Suporte matemático, verifique.https://mathjs.org/ Math.min(1,2), Math.sqrt(2)

3.Duas estratégias reais completas

Há muitas estratégias de ensinohttps://www.fmz.com/square/s:tag:Study/1, que é simples e fácil para iniciantes.

3.1 Estratégia spot de market maker de alta frequência

Esta é uma estratégia simples, mas poderosa, que costumava ganhar centenas de vezes em mercados spot reais de BTC.

var floatAmountBuy = 20
var floatAmountSell = 20
var diffPrice = 3
var Interval = 3000

function CancelPendingOrders() {
    var orders = _C(exchange.GetOrders);
    for (var j = 0; j < orders.length; j++) {
        exchange.CancelOrder(orders[j].Id, orders[j])
    }
}

function GetPrice(depth) {
    var price = {buy:0, sell:0}
    var askAmount = 0
    var bidAmount = 0
    for(var i=0; i<depth.Bids.length; i++){
        askAmount += depth.Asks[i].Amount
        bidAmount += depth.Bids[i].Amount
        if(askAmount >= floatAmountBuy && !price.buy){
            price.buy = depth.Asks[i].Price
        }
        if(bidAmount >= floatAmountSell && !price.sell){
            price.sell = depth.Bids[i].Price
        }
    }
    if(!price.buy || !price.sell){
        price = {buy:depth.Asks[depth.Asks.length-1].Price, sell:depth.Bids[depth.Bids.length-1].Price}
    }
    return price
}

function onTick() {
    var price = GetPrice(_C(exchange.GetDepth))
    var buyPrice = price.buy + 0.01
    var sellPrice = price.sell - 0.01
    if ((sellPrice - buyPrice) <= diffPrice){
        buyPrice -= 10
        sellPrice += 10
    }
    CancelPendingOrders()
    var account = _C(exchange.GetAccount)
    var amountBuy = _N((account.Balance / buyPrice-0.01), 2)
    var amountSell = _N((account.Stocks), 2)
    if (amountSell > 0.02) {
        exchange.Sell(sellPrice, amountSell)
    }
    if (amountBuy > 0.02) {
        exchange.Buy(buyPrice, amountBuy)
    }
}

function main() {
    while (true) {
        onTick()
        Sleep(Interval)
    }
}

3.2 Característica OKEX de duplo impulso

Uma estratégia de fuga clássica.https://www.fmz.com/strategy/103247para configurações. Você pode aprender como trocar características e desenhar gráficos a partir do código fonte.

var ChartCfg = {
    __isStock: true,
    title: {
        text: 'Dual Thrust Up-Down Track'
    },
    yAxis: {
        plotLines: [{value: 0,
            color: 'red',
            width: 2,
            label: {
                text: 'Up Track',
                align: 'center'}
                },
            {value: 0,
            color: 'green',
            width: 2,
            label: {
                text: 'Down Track',
                align: 'center'},
            }
        ]
    },
    series: [{type: 'candlestick',
        name: 'current cycle',
        id: 'primary',
        data: []
        },
        {type: 'flags',
        onSeries: 'primary',
        data: [],
        }
    ]
};

var STATE_IDLE = 0;
var STATE_LONG = 1;
var STATE_SHORT = 2;
var State = STATE_IDLE;

var LastBarTime = 0;
var UpTrack = 0;
var BottomTrack = 0;
var chart = null;
var InitAccount = null;
var LastAccount = null;
var Counter = {
    w: 0,
    l: 0
};

function GetPosition(posType) {
    var positions = exchange.GetPosition();
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].Type === posType) {
            return [positions[i].Price, positions[i].Amount];
        }
    }
    return [0, 0];
}

function CancelPendingOrders() {
    while (true) {
        var orders = exchange.GetOrders();
        for (var i = 0; i < orders.length; i++) {
            exchange.CancelOrder(orders[i].Id);
            Sleep(Interval);
        }
        if (orders.length === 0) {
            break;
        }
    }
}

function Trade(currentState, nextState) {
    var pfn = nextState === STATE_LONG ? exchange.Buy : exchange.Sell;
    if (currentState !== STATE_IDLE) {
        exchange.SetDirection(currentState === STATE_LONG ? "closebuy" : "closesell");
        while (true) {
            var amount = GetPosition(currentState === STATE_LONG ? PD_LONG : PD_SHORT)[1];
            if (amount === 0) {
                break;
            }
            // pfn(amount);
            pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount);
            Sleep(Interval);
            CancelPendingOrders();
        }
        var account = exchange.GetAccount();

        if (account.Stocks > LastAccount.Stocks) {
            Counter.w++;
        } else {
            Counter.l++;
        }

        LogProfit(_N(account.Stocks - InitAccount.Stocks), "Profit rate:", _N((account.Stocks - InitAccount.Stocks) * 100 / InitAccount.Stocks) + '%');
        LastAccount = account;
    }
    exchange.SetDirection(nextState === STATE_LONG ? "buy" : "sell");
    while (true) {
        var pos = GetPosition(nextState === STATE_LONG ? PD_LONG : PD_SHORT);
        if (pos[1] >= AmountOP) {
            Log("Average Price", pos[0], "amount:", pos[1]);
            break;
        }
        // pfn(AmountOP-pos[1]);
        pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]);
        Sleep(Interval);
        CancelPendingOrders();
    }
}

function onTick(exchange) {
    var records = exchange.GetRecords();
    if (!records || records.length <= NPeriod) {
        return;
    }
    var Bar = records[records.length - 1];
    if (LastBarTime !== Bar.Time) {
        var HH = TA.Highest(records, NPeriod, 'High');
        var HC = TA.Highest(records, NPeriod, 'Close');
        var LL = TA.Lowest(records, NPeriod, 'Low');
        var LC = TA.Lowest(records, NPeriod, 'Close');

        var Range = Math.max(HH - LC, HC - LL);

        UpTrack = _N(Bar.Open + (Ks * Range));
        DownTrack = _N(Bar.Open - (Kx * Range));
        if (LastBarTime > 0) {
            var PreBar = records[records.length - 2];
            chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1);
        } else {
            for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) {
                var b = records[records.length - i];
                chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]);
            }
        }
        chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]);
        ChartCfg.yAxis.plotLines[0].value = UpTrack;
        ChartCfg.yAxis.plotLines[1].value = DownTrack;
        ChartCfg.subtitle = {
            text: 'Up Track: ' + UpTrack + '  Down Track: ' + DownTrack
        };
        chart.update(ChartCfg);
        chart.reset(PeriodShow);

        LastBarTime = Bar.Time;
    } else {
        chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1);
    }

    LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date());
    var msg;
    if (State === STATE_IDLE || State === STATE_SHORT) {
        if (Bar.Close >= UpTrack) {
            msg  = 'Long Price: ' + Bar.Close + ' Up Track:' + UpTrack;
            Log(msg);
            Trade(State, STATE_LONG);
            State = STATE_LONG;
            chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: 'Long', text: msg});
        }
    }

    if (State === STATE_IDLE || State === STATE_LONG) {
        if (Bar.Close <= DownTrack) {
            msg = 'Short Price: ' + Bar.Close + ' Down Track:' + DownTrack;
            Log(msg);
            Trade(State, STATE_SHORT);
            chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: 'Short', text: msg});
            State = STATE_SHORT;
        }
    }
}

function onexit() {
    var pos = exchange.GetPosition();
    if (pos.length > 0) {
        Log("Warning, has positions when exiting", pos);
    }
}

function main() {
    if (exchange.GetName() !== 'Futures_OKCoin') {
        throw "Only support OKEX features";
    }
    exchange.SetRate(1);
    exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]);
    exchange.SetMarginLevel([10, 20][MarginLevelIdx]);

    if (exchange.GetPosition().length > 0) {
        throw "Can't have Positions when start.";}

    CancelPendingOrders();

    InitAccount = LastAccount = exchange.GetAccount();
    LoopInterval = Math.min(1, LoopInterval);
    Log('Exchange Name:', exchange.GetName(), InitAccount);
    LogStatus("Ready...");

    LogProfitReset();
    chart = Chart(ChartCfg);
    chart.reset();

    LoopInterval = Math.max(LoopInterval, 1);
    while (true) {
        onTick(exchange);
        Sleep(LoopInterval * 1000);
    }
}


Mais.

Ervas daninhasContinue atualizando este post, sinta-se à vontade para fazer qualquer pergunta