[TOC]
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.
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
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 emOKEX
eBitMEX
Verifique 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.
https
.Lista de funcionalidades atuais:
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
Adicionar uma troca
Adicionar emhttps://www.fmz.com/m/add-platform, ou cliquePlatform
etiqueta.
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 FMZ
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
Para o Linux, você pode alugar um VPS em nosso site, que irá implantar o docker automaticamente.
wget www.fmz.com/dist/robot_linux_amd64.tar.gz
Não encontramos comando?yum install wget -y
.tar -xzvf robot_linux_amd64.tar.gz
para desligar../robot -s node.fmz.com/xxxxx -p -p yourFMZpassword
Devias ver algo como:2018/07/05 05:04:10 Login OK, SID: 62086, PID: 7226, Name: host.localdomain
O 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.ctrl + C
para parar o docker.nohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &
para executar em segundo plano. este passo também pode ser feito porScreen
command.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.
Ctrl+S
no modo de edição.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.
NoRobot
página, cliqueAdd robot
, ou visitarhttps://www.fmz.com/m/add-robotdiretamente para adicionar um bot.
exchanges[0]
, exchanges[1]
Gerencie o bot
NoRobot
Página, pode ver que o bot está a funcionar.
LogProfit()
Pode ser qualquer número que quiser.Clique no nome do bot na página do bot para mais informações:
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 Kline |
Todos os parâmetros possíveis:PERIOD_M1
1 minuto,PERIOD_M5
Cinco minutos.PERIOD_M15
15 minutos.PERIOD_M30
30 minutos.PERIOD_H1
1h,PERIOD_D1
1d.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,true
significa que o pedido de ordem foi cancelado com êxito.false
significa 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 , KDJ etc... |
TA.MACD(records) |
Math |
Suporte matemático, verifique.https://mathjs.org/ | Math.min(1,2) , Math.sqrt(2) |
Há muitas estratégias de ensinohttps://www.fmz.com/square/s:tag:Study/1, que é simples e fácil para iniciantes.
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)
}
}
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);
}
}
Ervas daninhasContinue atualizando este post, sinta-se à vontade para fazer qualquer pergunta