[TOC] ¿Qué quieres decir?
Esto es una instrucción básica para principiantes, para una versión completa de nuestra documentación API, reviseAPI de la FMZHay muchas especificaciones obvias que no están cubiertas en este tutorial para que las descubras.
Después de aprender todo el tutorial, usted sabrá cómo funciona FMZ y ser capaz de escribir algunas estrategias básicas.
¿Qué es la plataforma FMZ?
FMZ es una plataforma de negociación automatizada para comerciantes de criptomonedas con soporte para muchos mercados de intercambio de bitcoin / et / altcoin.
¿Qué puede hacer FMZ por usted?
Puede aprender a escribir sus bots (estrategias) desde nuestra estrategias
¿Qué intercambios de Criptomonedas soporta FMZ?
FMZ admite casi todos los intercambios que son populares, tales comoBinance
, Bitfinex
, Bitstamp
, OKEX
, Huobi
, Poloniex
, etc. también puede negociar futuros enOKEX
yBitMEX
Consulte la lista completa de apoyo enAPISólo tienes que escribir una estrategia y ejecutarla en todos los intercambios sin ningún cambio.
¿Qué lenguajes de programación admite FMZ?
FMZ admite JavaScript, Python, C++ (JavaScript y Python se recomiendan) para codificar sus estrategias.
¿Está segura su API KEY?
De hecho, sus API-Key se guardan después de cifrado.
https
.Lista de características actuales:
Para ejecutar un bot, necesitas tener una estrategia, añadir un intercambio, desplegar un docker primero. el docker es el ejecutor de tu estrategia que se ejecuta en tu propia computadora o servidor.
Una vista rápida de la página principal
Añadir un intercambio
Añadir enhttps://www.fmz.com/m/add-platform, o haga clic enPlatform
etiqueta.
Su clave de acceso y clave secreta se pueden aplicar en el intercambio de criptomonedas. API-KEY se utiliza para comerciar y obtener la información privada del intercambio. No guardamos ninguna API-KEY o contraseñas en nuestro servidor.
Puede inscribirse en las ZFM
Despliegue un docker
FMZ no ejecuta bots para usted, usted necesita implementar un docker por sí mismo como el ejecutor, que es más flexible y seguro ya que nuestro servicio no participa en la ejecución de sus bots.
Para las ventanas, es bastante fácil, sólo sigue las instrucciones enhttps://www.fmz.com/m/add-node
Para Linux, puede alquilar un VPS en nuestro sitio web, que desplegará el docker automáticamente.
wget www.fmz.com/dist/robot_linux_amd64.tar.gz
¿No se encuentra el comando?yum install wget -y
.tar -xzvf robot_linux_amd64.tar.gz
para desabrochar../robot -s node.fmz.com/xxxxx -p -p yourFMZpassword
, deberías ver algo como2018/07/05 05:04:10 Login OK, SID: 62086, PID: 7226, Name: host.localdomain
, lo que significa que todo está trabajado.node.fmz.com/xxxxx
es único para cada usuario, encontrar el suyo enhttps://www.fmz.com/m/add-node.ctrl + C
para detener el muelle.nohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &
para ejecutarse en segundo plano. este paso también se puede hacer porScreen
command.Escribe una estrategia
Usted debe escribir su propia estrategia o comprar de la plaza. Aquí vamos a utilizar una estrategia simple JavaScript como una demostración para mostrar cómo usar la página de edición.https://www.fmz.com/strategy/125482¿ Qué pasa? Este tutorial no cubrirá cómo usar JavaScript ya que puedes encontrar muchos tutoriales en línea.
Ctrl+S
en modo de edición.Para enviar el mensaje a su teléfono, debe vincular el telegrama a su cuenta enhttps://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
}
}
Ejecuta el bot.
Finalmente, es hora de ejecutar un bot.
En elRobot
página, haga clicAdd robot
, o visitarhttps://www.fmz.com/m/add-robotdirectamente para añadir un bot.
exchanges[0]
, exchanges[1]
Administrar el bot
En elRobot
página, se puede ver que el bot está funcionando.
LogProfit()
, puede ser cualquier número que quieras.Haga clic en el nombre del bot en la página del bot para obtener más información:
Esta parte presentará algunas de las API más utilizadas, para una versión completa de nuestra documentación API, consulteAPI de la FMZ¿ Qué pasa? Se recomienda encarecidamente que los principiantes ejecuten el código demo enPágina de depuración.
2.1 Registro
Utilice: Log(msg)
Parámetros:cadenas o númerosDescripción:Registra un mensaje en la página de registro del robot.Regreso:No hay- ¿ Qué es eso?
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
Utilice: exchange.GetTicker()
Parámetros:No hayDescripción:Obtener el ticker del mercado actual.Regreso:
{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}
- ¿ Qué es eso?
function main() {
var ticker = exchange.GetTicker()
Log(ticker)
Log('Last Price: ',ticker.Last, 'Bid Price: ', ticker.Buy)
}
2.3 Profundidad
Utilice: exchange.GetDepth()
Parámetros:No hayDescripción:Obtenga el libro de pedidos del mercado actual.Regreso:
{
"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
}
- ¿ Qué es eso?
function main() {
var depth = exchange.GetDepth()
Log(depth)
Log('Bid one: ', depth.Bids[0].Price, 'Ask one: ', depth.Asks[0].Price)
}
2.4 Obtener registros
Utilice: exchange.GetRecords()
, exchange.GetRecords(Period)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Periodo de tiempo | el varble global | - No, no es así. | El ciclo de Kline |
Todos los parámetros posibles:PERIOD_M1
1 minuto,PERIOD_M5
Cinco minutos.PERIOD_M15
15 minutos,PERIOD_M30
:30 minutos,PERIOD_H1
1h,PERIOD_D1
- ¿Qué es eso?Descripción:Consigue barras Kline / candelabro para el mercado actual.Regreso:
[
{"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},
......
]
- ¿ Qué es eso?
//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 Obtener Cuenta
Utilice: exchange.GetAccount()
Parámetros:No hayDescripción:Obtener información de la cuentaRegreso:
{
"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
}
- ¿ Qué es eso?
//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
Utilice: exchange.Buy(Price, Amount)
, exchange.Buy(Price, Amount, Msg)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Precio | Número | - ¿ Qué? | Precio de compra de la orden límite |
Importe | Número | - ¿ Qué? | Cantidad de la orden límite de compra |
Msg | Cuadrícula | - No, no es así. | Añadir un mensaje adicional en la página de registro |
Descripción:Envía una orden de compra y un registro de compra a la página de los botsRegreso:devuelve el OrderID en caso de éxito,null
Si no es así.- ¿ Qué es eso?
//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
Utilice: exchange.Sell(Price, Amount)
, exchange.Sell(Price, Amount, Msg)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Precio | Número | - ¿ Qué? | Precio de venta de la orden límite |
Importe | Número | - ¿ Qué? | Vender el importe de la orden límite |
Msg | Cuadrícula | - No, no es así. | Añadir un mensaje adicional en la página de registro |
Descripción:Envía una orden de venta y un registro de venta a la página de los botsRegreso:devuelve el OrderID en caso de éxito,null
Si no es así.- ¿ Qué es eso?
//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 Obtener orden
Utilice: exchange.GetOrder(OrderId)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Ordenado | Número | - ¿ Qué? | Identificación del pedido |
Descripción:Obtenga los detalles de la orden por la ID de la orden.Regreso:
{
"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
}
}
- ¿ Qué es eso?
//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 Obtener órdenes
Utilice: exchange.GetOrders()
Parámetros:No hayDescripción:Obtenga todas las órdenes abiertas para sus símbolos comerciales.Regreso:Una lista de órdenes abiertas, el resultado tiene el mismo significado queGetOrder()
[
{
"Info":{},
"Id":16387538,
"Amount":1123,
"Price":0.00012826,
"DealAmount":0,
"AvgPrice":0,
"Status":0,
"Type":1,
"ContractType":""
}
]
- ¿ Qué es eso?
//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 el pedido
Utilice: exchange.CancelOrder(OrderId)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Ordenado | Número | - ¿ Qué? | Identificación del pedido |
Descripción:Cancelar un pedido por orden id.Regreso:el tipo de bool,true
significa que la cancelación de la solicitud de pedido fue exitosa.false
significa que la cancelación de la solicitud de pedido ha fracasado.
2.11 Tipo de contrato establecido
Utilice: exchange.SetContractType(ContractType)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Tipo de contrato | Cuadrícula | - ¿ Qué? | Tipo de contrato |
Descripción:Establecer el tipo de contrato para el comercio de futuros. debe establecerse primero antes de utilizar otras API privadas.Regreso:No hay- ¿ Qué es eso?
exchange.SetContractType("this_week") //OKEX future has “this_week”, “next_week”, “quarter” , "swap"
exchange.SetContractType("XBTUSD") //BitMEX future has "XBTUSD","XBTM19",etc
2.12 Posicionamiento
Utilice: exchange.GetPosition()
Parámetros:No hayDescripción:Obtener la información de posición actual, sólo para el comercio de futuros.Regreso:Una lista de posiciones, devolverá la lista vacía si la cuenta no tiene posición.- ¿ Qué es eso?
// 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 Establecer la dirección
Utilice: exchange.SetDirection(Direction)
Parámetros:
Nombre | Tipo de producto | Se trata de una obligación | Descripción |
---|---|---|---|
Dirección | Cuadrícula | - ¿ Qué? | puede serbuy , closebuy , sell , closesell . |
Descripción:Los tipos de órdenes de compra o venta establecidos sólo para el comercio de futuros.Regreso:No hay- ¿ Qué es eso?
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 Otras funciones de uso común:
Compruebe más detalles sobre esas funciones en FMZDocumentación de la API
Nombre | Descripción | Ejemplo |
---|---|---|
LogStatus |
Registra un mensaje o tablas en la barra de estado de los bots, se actualizará cada vez | LogStatus('msg') |
_C |
Función de nuevo intento | _C(exchange.GetRecords,PERIOD_H1) ,_C(exchange.GetTicker) |
_N |
Función de posición | _N(4001.512,2) ,_N(num,0) |
_G |
Diccionario global que se puede guardar después de reiniciar el robot. | _G('initValue', 1000);_G('initValue') |
_D |
Devuelve la marca de tiempo | _D() , _D(1478570053241) |
TA |
Biblioteca de indicadores TA-Lib. apoyoMACD , EMA , KDJ Y así sucesivamente. |
TA.MACD(records) |
Math |
Apoyo a la función matemática, verifique enhttps://mathjs.org/ | Math.min(1,2) , Math.sqrt(2) |
Hay muchas estrategias de enseñanza enhttps://www.fmz.com/square/s:tag:Study/1, que es simple y fácil para los principiantes.
Esta es una estrategia simple pero poderosa que solía ganar cientos de veces en los mercados spot reales de BTC. No puede ejecutarse en intercambios que tienen altas tarifas de comercio.
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)
}
}
Una estrategia de escape clásica, ¿de acuerdo?https://www.fmz.com/strategy/103247para las configuraciones. Puedes aprender a intercambiar características y dibujar gráficos del código fuente.
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);
}
}
Las hierbasSigue actualizando en este post, siéntete libre de hacer cualquier pregunta