Учебное пособие для начинающих FMZ

Автор:Трава, Создано: 2019-04-09 11:29:07, Обновлено: 2024-02-06 17:35:38

[TOC]

img

1.Начать с платформы FMZ

Это основная инструкция для новичков, для полной версии нашей документации API, проверьтеFMZ APIЕсть много очевидных характеристик, которые не охвачены в этом руководстве, оставленные для вас, чтобы вы обнаружили.

После изучения всего учебника вы будете знать, как работает FMZ и сможете написать некоторые базовые стратегии.

1.1 О платформе FMZ

Что такое платформа FMZ?

FMZ - это автоматизированная торговая платформа для трейдеров криптовалют с поддержкой многих биржевых рынков биткоина / эфира / альткоина.

Что FMZ может сделать для вас?

Вы можете узнать, как написать свои боты ((стратегии) из нашей стратегии площади, которая содержит много открытого исходного кода, поделиться вашим кодом стратегии с другими, попросить профессиональную помощь в любое время, запустить свою стратегию на многих биржах, управлять своим ботом на сайте с компьютера или сотового телефона, продавать свои стратегии, если вы хотите, общаться со многими другими любителями автоторговли в нашемгруппаКороче говоря, FMZ - это идеальная платформа для тех, кто хочет заниматься автоматической торговлей.

Какие криптовалютные биржи поддерживает FMZ?

FMZ поддерживает почти все популярные биржи, такие какBinance, Bitfinex, Bitstamp, OKEX, Huobi, Poloniex, и т. д. Вы также можете торговать фьючерсами наOKEXиBitMEXПроверьте полный список поддержкиAPIВам нужно только написать одну стратегию и запустить ее на всех биржах без каких-либо изменений.

Какие языки программирования поддерживает FMZ?

FMZ поддерживает JavaScript, Python, C++ (JavaScript и Python рекомендуются) для кодирования ваших стратегий.

Твой API-ключ в безопасности?

Действительно, ваши API-ключи сохраняются после шифрования.

  • Вам нужно ввести пароль FMZ При добавлении ключа. Веб-браузер будет шифровать ваш ключ API и передать шифрованный ключ на сервер FMZ с помощьюhttps.
  • Вам нужно ввести пароль FMZ, когда вы запускаете докер на вашем сервере или компьютере.
  • FMZ отправит зашифрованный ключ на ваш докер с помощью https, когда вы запустите бота. Докер расшифрует ключ.
  • FMZ не сохраняет ваш пароль (только пароль Hash). Так что даже мы не знаем ваш API ключ.
  • Вам нужно защитить свой пароль и докер-сервер. Лучше всего использовать второй логин проверки FMZ.

Список текущих функций:

  • 1.Межплатформенная поддержка всех основных криптовалютных бирж в ближайшее время появится больше
  • 2.Поддержка моделируемого обмена. https://wex.app/
  • 3.Имеет эффективную систему симуляции обратного тестирования.
  • 4.Поддержка отправки электронной почты, пересылки сообщений на ваш аккаунт Telegram.
  • 5.Веб-контроль, к которому можно получить доступ через телефон.
  • Поддержка программирования Python\C++\JavaScript.
  • 7.Стоимость чрезвычайно низкая. 0,125 юаней в час, около 0,018 долларов.
  • 8.NoФМЗ работает уже более четырех лет без каких-либо проблем с безопасностью.

1.2 Быстрое начало использования платформы FMZ

Чтобы запустить бота, вам нужно иметь стратегию, добавить обмен, сначала развернуть докер. Докер - это исполнитель вашей стратегии, работающий на вашем собственном компьютере или сервере.

Быстрый взгляд на главную страницу

img

  • 1.Ваша главная страница управления
  • 2.Управляйте всеми ботами (запуск, остановка, удаление, открытие и т.д.)
  • 3.Управляйте всеми своими стратегиями кодом
  • 4.Разверните и управляйте докером
  • 5.Добавить новые биржи
  • Ручная торговля на добавленных вами биржах
  • 7.Оплатите свой счет
  • 8.Задайте любой вопрос здесь
  • 9.Симулируемый обмен FMZ
  • Инструмент для отладки, с помощью которого можно запустить блок кода без запуска бота.
  • 11.Всевозможные сообщения
  • 12.Квадрат стратегии, в котором перечислены стратегии открытого исходного кода и стратегии зарядки
  • 13.Живые роботы, где перечислены все живые роботы.
  • 14.Форумы, на которых можно разместить сообщение для обсуждения любого вопроса.
  • 15.Попросите кого-нибудь написать код для вас или предоставить эту услугу другим.
  • 16.Продукты для бирж и агентств.
  • 17.Документация API.
  • 18.Некоторые полезные инструменты, проверьте сами.
  • 19.Информация о вашем счете.

Добавить обмен

Добавить вhttps://www.fmz.com/m/add-platform, или нажмитеPlatformна этикетке. Ваш ключ доступа и секретный ключ могут быть применены на криптовалютной бирже. API-KEY используется для торговли и получения частной информации с биржи. Мы не сохраняем API-KEY или пароли на нашем сервере. Вы можете зарегистрироваться на FMZсимулируемый обмени добавить его для тестирования.

img

развернуть докер

FMZ не запускает ботов за вас, вам нужно развернуть докер самостоятельно в качестве исполнителя, что более гибко и безопасно, поскольку наш сервис не участвует в запуске ваших ботов.

Для окон это довольно просто, просто следуйте инструкции наhttps://www.fmz.com/m/add-node

img

Для Linux вы можете арендовать VPS на нашем сайте, который автоматически развернет докер.

  • 1.Покупайте облачный сервер (VPS) у Amazon или Google, достаточно самой низкой и самой дешевой конфигурации.
  • 2.Входите на сервер, следуйте инструкциям поставщика сервера или поищите в Google.
  • 3.Выберите докер, который соответствует вашей версии системы, в большинстве случаев это 64-битный.
  • 4. За центо, беги.wget www.fmz.com/dist/robot_linux_amd64.tar.gz, команда не найдена? сначала установитьyum install wget -y.
  • 5.Run tar -xzvf robot_linux_amd64.tar.gzчтобы разблокировать.
  • 6.Run ./robot -s node.fmz.com/xxxxx -p -p yourFMZpasswordВы должны увидеть что-то вроде2018/07/05 05:04:10 Login OK, SID: 62086, PID: 7226, Name: host.localdomain, что означает, что все сделано.node.fmz.com/xxxxxявляется уникальным для каждого пользователя, найдите свой собственный наhttps://www.fmz.com/m/add-node.
  • Теперь докер не работает в фоновом режиме, если вы закрываете клиент SHH, докер остановится. Нажмитеctrl + Cчтобы остановить докер.
  • 8.Run nohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &чтобы запустить в фоновом режиме. этот шаг также может быть выполненScreen command.
  • 9.Проверьтеhttps://www.fmz.com/m/nodes, если все в порядке, вы можете найти докер развернут там.

Напишите стратегию

Здесь мы будем использовать простую стратегию JavaScript в качестве демонстрации, чтобы показать, как использовать страницу редактирования.https://www.fmz.com/strategy/125482- Да. В этом учебном пособии не будет рассказано о том, как использовать JavaScript, так как вы можете найти множество учебных пособий в Интернете.

img

  • 1. Измените свой код
  • 2.В качестве обратного тестирования мы рассмотрим эту часть в промежуточном учебном пособии
  • 3.Язык программиста вашего кода, JavaScript был использован в этой демонстрации
  • 4.Заголовок разделен на китайский и английский язык.
  • 5.Тип вашей стратегии, дефолт часто встречается
  • 6.Категория вашей стратегии. Если у вас слишком много стратегий, вы можете разделить их на разные категории.
  • 7.Удаленное редактирование вашего кода с вашего собственного IDE вместо нашего веб-сайта
  • 8.Ссылка на документ API
  • 9.Примечания к стратегии (показываются только вам).
  • 10.Описание стратегии. Другие люди увидят описания, если вы поделитесь или продадите свою стратегию на Square.
  • 11.Руководство по стратегии, можно увидеть только тогда, когда кто-то купил вашу стратегию.
  • 12.Сохранить код, илиCtrl+Sв режиме редактирования.
  • 13.Сохранить конфигурацию обратного тестирования в коде.
  • 14.Downloadфайл стратегии
  • 15.Экспорт и импорт стратегии при сохранении всех параметров
  • 16.Изменить размер шрифта и редактировать тему
  • 17.Оформление кода автоматически
  • 18.Используйте режим VIM для редактирования.

Чтобы отправить сообщение на свой телефон, вам нужно связать телеграмму с вашим аккаунтом по адресуhttps://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
    }
}

Запустите бота

Наконец, пришло время запустить бота. НаRobotстраница, кликнутьAdd robot, или посетитьhttps://www.fmz.com/m/add-robotпрямо для добавления бота.img

  • 1.Имя бота
  • 2. Докер, чтобы запустить этот бот
  • 3.Стратегия выполнения
  • 4.Параметры, значение по умолчанию могут быть изменены.
  • 5.Предусмотренный период Клайна при использовании обмена.GetRecords()
  • 6.Exchange
  • 7.Tradingсимвол или пары
  • 8.Если необходимый вам торговый символ не указан в списке, вы можете просто ввести его самостоятельно.
  • 9.Clickдобавить обмен
  • 10.Борс уже добавлен.На одном боте можно добавить несколько бирж, доступ к нимexchanges[0], exchanges[1]
  • 11.Clickчтобы управлять ботом!

Управление ботом

НаRobotНа странице, вы можете видеть, что бот работает.img

  • 1.Имя бота, нажмите здесь, чтобы перейти на страницу бота.
  • 2.Стратегия, которую запускает бот, нажмите здесь на страницу стратегии.
  • Статус бота. может работать, остановиться, ошибка.
  • 4.Прибыль бота, прошедшаяLogProfit(), может быть любое число, которое вы хотите.
  • 5.Дата создания, может быть изменена на время последнего сообщения.
  • Проследуйте бота. FMZ отправит вам сообщение, когда бот был случайно остановлен
  • 7. Остановите робота.

Нажмите на имя бота на странице бота для получения дополнительной информации:img

2.Самое распространенное введение API

Эта часть представит некоторые наиболее часто используемые API, для полной версии нашей API документации, проверьте наFMZ API- Да. Для новичков рекомендуется запустить демо-кодСтраница отладки.

2.1 Журнал

Использование: Log(msg) Параметры:строки или цифрыОписание:Запишите сообщение на страницу журнала роботов.Возвращение:Никаких.Демонстрация:

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

Использование: exchange.GetTicker() Параметры:Никаких.Описание:Посмотрите на текущий рынок.Возвращение:

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

Демонстрация:

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

2.3 Получитьглубину

Использование: exchange.GetDepth() Параметры:Никаких.Описание:Получите текущую книгу заказов на рынке.Возвращение:

{
    "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
}

Демонстрация:

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

2.4 GetRecords

Использование: exchange.GetRecords(), exchange.GetRecords(Period) Параметры:

Имя Тип Обязательно Описание
Период глобальный варбл Нет, нет. Цикл Klines, Факультативные параметры, по умолчанию цикл линии K устанавливается при запуске робота.

Все возможные параметры:PERIOD_M11 минута.PERIOD_M55 минут.PERIOD_M1515 минут.PERIOD_M3030 минут,PERIOD_H11 час,PERIOD_D11d.Описание:Попробуй купить "Клейн" и "Свечильник" на текущий рынок.Возвращение:

[
    {"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},
    ......
]

Демонстрация:

//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

Использование: exchange.GetAccount() Параметры:Никаких.Описание:Получить информацию о счетеВозвращение:

{
    "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
}

Демонстрация:

//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 Покупать

Использование: exchange.Buy(Price, Amount), exchange.Buy(Price, Amount, Msg) Параметры:

Имя Тип Обязательно Описание
Цена Число Да, да. Цена покупки предельного ордера
Сумма Число Да, да. Сумма лимитного ордера покупки
Msg Строка Нет, нет. Добавить дополнительное сообщение на странице журнала

Описание:Отправить ордер на покупку и журнал покупки на странице ботовВозвращение:вернуть OrderID, если удалось,nullЕсли нет.Демонстрация:

//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 Продать

Использование: exchange.Sell(Price, Amount), exchange.Sell(Price, Amount, Msg) Параметры:

Имя Тип Обязательно Описание
Цена Число Да, да. Цена продажи предельного ордера
Сумма Число Да, да. продать сумму лимитного ордера
Msg Строка Нет, нет. Добавить дополнительное сообщение на странице журнала

Описание:Отправить ордер на продажу и журнал продажи на страницу ботовВозвращение:вернуть OrderID, если удалось,nullЕсли нет.Демонстрация:

//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

Использование: exchange.GetOrder(OrderId) Параметры:

Имя Тип Обязательно Описание
Приказ Число Да, да. Идентификатор заказа

Описание:Получите детали заказа по идентификатору заказа.Возвращение:

{
    "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
    }
}

Демонстрация:

//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

Использование: exchange.GetOrders() Параметры:Никаких.Описание:Получите все открытые ордера на ваши торговые символы.Возвращение:Список открытых заказов, результат имеет такое же значение, какGetOrder()

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

Демонстрация:

//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 Отменить заказ

Использование: exchange.CancelOrder(OrderId) Параметры:

Имя Тип Обязательно Описание
Приказ Число Да, да. Идентификатор заказа

Описание:Отменить заказ по номеру заказа.Возвращение:тип bool,trueозначает, что аннулирование запроса на заказ было успешно.falseозначает, что аннулирование запроса не удалось.

2.11 SetContractType

Использование: exchange.SetContractType(ContractType) Параметры:

Имя Тип Обязательно Описание
Тип контракта Строка Да, да. Тип контракта

Описание:Установка типа контракта для торговли фьючерсами. должна быть установлена сначала, прежде чем использовать другой частный API.Возвращение:Никаких.Демонстрация:

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

2.12 Положение

Использование: exchange.GetPosition() Параметры:Никаких.Описание:Получите информацию о текущей позиции, только для торговли фьючерсами.Возвращение:Список позиций, вернет пустой список, если у счета нет позиции.Демонстрация:

// 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 Установка направления

Использование: exchange.SetDirection(Direction) Параметры:

Имя Тип Обязательно Описание
Направление Строка Да, да. может бытьbuy, closebuy, sell, closesell.

Описание:Установка типов ордеров на покупку или продажу, только для торговли фьючерсами.Возвращение:Никаких.Демонстрация:

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 Другие часто используемые функции:

Узнайте больше о функциях на FMZAPI-документы

Имя Описание Пример
LogStatus Зарегистрируйте сообщение или таблицы на строке состояния ботов, будет обновляться каждый раз LogStatus('msg')
_C Функция повторного попытки _C(exchange.GetRecords,PERIOD_H1),_C(exchange.GetTicker)
_N Функция положения _N(4001.512,2),_N(num,0)
_G Глобальный словарь, который можно сохранить после перезагрузки робота. _G('initValue', 1000);_G('initValue')
_D Возвращает временную отметку _D(), _D(1478570053241)
TA Библиотека показателей TA-Lib. поддержкаMACD, EMA, KDJИ так далее... TA.MACD(records)
Math Поддержите математическую функцию, проверьте.https://mathjs.org/ Math.min(1,2), Math.sqrt(2)

3.Две полные реальные стратегии

Есть много стратегий обучения вhttps://www.fmz.com/square/s:tag:Study/1, что просто и легко для начинающих.

3.1 Спотная стратегия высокочастотного маркетмейкера

Это простая, но мощная стратегия, которая раньше зарабатывала сотни раз на реальных спотовых рынках 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 Функция OKEX с двойной тягой

Классическая стратегия побега.https://www.fmz.com/strategy/103247для конфигурации. Вы можете научиться обмениваться функциями и рисовать графики из исходного кода.

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);
    }
}


Больше

Травапродолжайте обновлять этот пост, не стесняйтесь задавать вопросы