В процессе загрузки ресурсов... загрузка...

Основное руководство по написанию стратегии с помощью платформы FMZ Quant Trading (обязательно читать)

Автор:FMZ~Lydia, Создано: 2023-07-12 15:09:33, Обновлено: 2024-02-05 20:05:43

[TOC]

img

Это руководство содержит базовые знания по написанию стратегии, включая введение API, backtest, диаграммы и многое другое. После изучения этого базового руководства пользователи смогут грамотно использовать базовый API и писать стабильную стратегию бота.Запустить FMZ Quant Platform.

Учебное пособие по старой версии:FMZ Quant (FMZ.COM) Руководство по написанию стратегии 2.0 (учебное пособие); в учебном пособии есть много индексов сообщений, которые рекомендуется читать.

Предварительные инструкции по написанию стратегии

Введение в API

Программная торговля - это использование программ для подключения к платформам через API для достижения автоматической покупки и продажи или других функций в соответствии с намерением дизайна.

В настоящее время существуют два основных протокола интерфейса для криптовалютных платформ: REST и Websocket. Каждый раз, когда протокол REST получает данные, к нему необходимо обращаться один раз. В качестве примера возьмем API моделированной платформы Wex.app. Откройте [ссылку] (https://api.wex.app/api/v1/public/ticker?market=BTC_USDT) непосредственно в браузере, и вы можете получить результат следующим образом:

{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}

Таким образом, вы можете увидеть, что торговля после последних рыночных котировок торговой пары BTC_USDT, будет меняться каждый раз, когда она обновляется; market=" сопровождается конкретными параметрами торговой пары, которые могут быть изменены для получения других данных торговой пары. Для публичных интерфейсов, таких как котировки рынка, их может получить каждый, поэтому проверка не требуется. Однако некоторые интерфейсы должны определить личность пользователя при размещении заказа или получении учетной записи. В этом случае для подписания необходим API-KEY. Websocket является режимом подписки. После отправки контента, который необходимо подписаться, платформа отправит обновленные данные в программу, и его не нужно пересматривать каждый раз, поэтому это более эффективно.

Торговая платформа FMZ Quant инкапсулирует интерфейс REST каждой платформы и использует единый способ вызова и единый формат данных, что делает написание стратегии проще и более общим.

Различные языки программирования

Большинство частей документа API платформы FMZ используют JavaScript в качестве примера, но из-за инкапсуляции между различными языками практически нет разницы, и вам нужно только обратить внимание на вопросы синтаксиса. C++" немного особенный, и будущие учебные пособия будут иметь специализированное введение. Поскольку Js относительно прост и не имеет проблем с совместимостью, его рекомендуется использовать новичкам. Платформа FMZ Quant поддерживает полный Python и может свободно устанавливать различные пакеты. Рекомендуется пользователям, которые имеют определенную основу программирования. Для пользователей, которые не хотят изучать языки программирования и просто хотят писать стратегии, платформа FMZ Quant также быстро поддерживает Mylanguage, который в основном совместим с веб-стратегиями, и рекомендуется для тех, у кого есть соответствующий опыт. Недостаток заключается в том, что Webstock не так мощный и гибкий, как языки програм

Поскольку Python имеет разные версии, он может быть указан в начале программы, например:#!Python2и#!Python3. Обратите внимание, что JavaScript недавно обновил свой синтаксис ES6, и те, кто заинтересован, могут узнать об этом. Коды Python и Javascript с одинаковыми функциями показаны ниже. Можно увидеть, что существуют только различия в синтаксисе, поэтому документ API дает только примеры Javascript, и это обучение также будет учитывать специальные случаи использования Python.

#python code
def main():
    while True:
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
#the corresponding Js code
function main(){
    while(true){
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
    }
}

Рекомендации по ресурсам

  • Это руководство не даст подробное введение на каждый интерфейс в FMZ платформы API документ, так что вы можете проверитьв этой статье для более подробной информации.
  • Если вы хотите получить сигнал tradingview и разместить заказ на FMZ, вы можете обратиться кв этой статье.
  • Для быстрого начала работы с Javascript и Python, написание простых стратегий не требует сложного синтаксиса, а только некоторых базовых понятий; вы можете изучить учебник, пока учитесь программировать (https://www.fmz.com/bbs-topic/9123, https://www.fmz.com/bbs-topic/9124).
  • Документ на моем языке; Mylanguage по-прежнему очень удобен для стратегий тренда.
  • Вот пример вызова C++. Те, кто интересуется C++, могут взглянуть.Примерне рекомендуется.
  • Курс количественной торговли криптовалютами NetEase Cloud Classroom, официально созданный FMZ, требует всего 20 юаней, с богатым подробным содержанием, от простого до глубокого, подходящего для начинающих!курсовая ссылка
  • Вот они.Некоторые методы обученияВы можете попробовать написать стратегии, пока изучаете основы.
  • Подробное объяснение исходного кода стратегии:связь.

Инструмент отладки

Платформа FMZ Quant предоставляетУстройство для отладкидля отладки интерфейсов API. Инструмент отладки поддерживает только JavaScript и может быть выполнен только в течение определенного периода времени; интерфейс платформы может быть отладён без создания бота; в результате будут возвращены возвращенные данные, и код инструмента отладки не будет сохранен.img

Рамочная программа стратегии

Стратегическая программа такая же, как и обычная программа, которая выполняется в кодовых командах. Особая часть заключается в том, что должна быть функция main. Поскольку стратегия должна работать непрерывно, обычно требуется петля плюс время сна. Поскольку частота доступа к API платформы ограничена, время сна должно быть соответствующим образом скорректировано. Эта структура является типичным исполнением с фиксированными интервалами, и вы также используете Websocket для написания стратегий, основанных на событиях. Например, немедленное исполнение, если глубина меняется, что будет представлено в расширенном учебном пособии.

Другие функции со специальными действиями показаны следующим образом:

  • onexit() является нормальной функцией на выходе; максимальное время выполнения составляет 5 минут; она может быть неуточнена; если время истекло, будет сообщена ошибка прерывания.
  • onerror() - это аномальная функция выхода; ее максимальное время выполнения составляет 5 минут; она может быть неопределенной.
  • init() является функцией инициализации; его стратегия будет вызвана автоматически при запуске; она может быть неспецифицированной.
function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
    while(true){
        onTick()
        Sleep(6000)
    }
}

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

function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
    try{
        while(true){
           onTick()
           Sleep(6000)
       }
    }catch(err){
        Log(err)
    }
}

Введение в API платформы

Установленная платформа и торговая пара

При вызове любого API, связанного с платформой, вам нужно указать платформу и торговую пару.exchangeНапример, чтоexchange.GetTicker()получит рыночный тикер этой биржевой торговой пары.

Платформа FMZ Quant поддерживает одновременное добавление нескольких объектов обменной пары. Например, вы можете одновременно управлять BTC и ETH одного аккаунта платформы, или вы можете одновременно управлять BTC одной биржи и ETH другой биржи. Обратите внимание, что одновременно можно добавлять различные аккаунты на одной платформе, и они различаются в соответствии с ярлыками, добавленными на веб-сайт FMZ.exchangesмассив, чтобы представить их, а именноexchanges[0]иexchanges[1]...и так далее, в соответствии с порядком сложения, когда бот создан.BTC_USDTBTC является валютой торговли, а USDT - валютой котировки.

img

Очевидно, если мы работаем с большим количеством торговых пар, этот метод будет очень неудобным.exchange.SetCurrency("BTC_USDT"); затем торговая пара, связанная сexchangeстановитсяBTC_USDT, который останется действительным до следующего вызова на смену торговой пары.Обратите внимание, что backtest поддерживает переключение торговых пар недавноНиже приведен конкретный пример:

var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
  for(var i=0;i<symbols.length;i++){
      exchange.SetCurrency(symbols[i])
      var ticker = exchange.GetTicker()
      var amount = _N(buyValue/ticker.Sell, 3)
      exchange.Buy(ticker.Sell, amount)
      Sleep(1000)
  }
}

Получить публичные интерфейсы

Как упоминалось в предыдущем примере, интерфейс рынка, как правило, является общедоступным интерфейсом, к которому может получить доступ каждый. Общие интерфейсы рынка: GetTicker, GetDepth, GetRecords и GetTrades. Котировка рынка является основой стратегии для принятия торговых решений. Позже я представлю их по одному. Лучше попробовать их в Debug Tool самостоятельно. Если вам нужно подробное объяснение, вы можете проверить это в документе API.

Каждый интерфейс обычно имеетInfoполе, которое представляет собой исходную строку данных, возвращенную платформой, и которое может быть использовано для дополнения дополнительной информации.JSON.parse(), в то время как Python использует библиотеку json.TimeПоле указывает временную отметку запроса, которая может быть использована для оценки задержки.

при использовании любого API в боте, доступ может потерпеть неудачу и вернутьсяnull, и Python возвращаетNone. В это время используемые данные сообщают об ошибке и заставляют бота остановиться, поэтому терпимость к ошибкам очень важна.

GetTicker

GetTicker, вероятно, является наиболее часто используемым интерфейсом. Вы можете найти последний раз исполненную цену, цену buy1 и цену sell1, а также последний объем торговли. Перед размещением ордера, исполненную цену можно определить в соответствии с информацией тикера. Пример бота возвращения:{"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) //return ticker in the debugging tool, and you can see the specific result
    Log('Last time executed price:',ticker.Last, 'Buy1 price:', ticker.Buy)
}

ПолучитьГлубину

GetDepth для получения глубокой информации о ожидаемых ордерах. Хотя GetTicker включает в себя цены buy 1 и sell1, если вы хотите запросить более глубокие ожидаемые ордера, вы можете использовать этот интерфейс, чтобы в целом проверить 200 ожидаемых ордеров. Шоковые цены можно рассчитать с помощью этого интерфейса. Ниже представлен реальный результат возврата. Среди них Asks представляет ожидающийся ордер продажи, а массив Sell1, Sell2... Так что цена также возрастает по очереди. Bids представляет ожидающийся ордер покупки, а массив buy1, buy2... Цена снижается по очереди.

{
    "Info":null,
    "Asks":[
        {"Price":5866.38,"Amount":0.068644},
        {"Price":5866.39,"Amount":0.263985},
        ......
        ]
    "Bids":[
        {"Price":5865.13,"Amount":0.001898},
        {"Price":5865,"Amount":0.085575},
        ......
        ],
    "Time":1530241857399
}

Пример использования GetDepth для запросов и предложений:

function main() {
    var depth = exchange.GetDepth()
    Log('Buy 1 price:', depth.Bids[0].Price, 'Sell 1 price:', depth.Asks[0].Price)
}

GetRecords

GetRecords является одним из наиболее часто используемых интерфейсов, может возвращать информацию о ценах в течение длительного периода времени, что является основой для расчета различных индикаторов. Если период K-линии не указан, это означает использование периода по умолчанию при добавлении бота. Длина K-линии не может быть указана, и она будет продолжать увеличиваться с течением времени. Максимальное число составляет 2000, а в первом звонке число составляет около 200 (разные платформы возвращают разные номера). Последняя K-линия является последней K-линией, поэтому данные изменятся по мере изменения котировок на рынке; первая K-линия является самым старым данным.

exchange.SetMaxBarLen(Len)может устанавливать количество K-линий, приобретенных впервые (поддерживается некоторыми платформами), и устанавливать максимальное количество K-линий.Например:exchange.SetMaxBarLen(500).

GetRecords может указывать периоды, такие как PERIOD_M1: 1 минута, PERIOD_M5: 5 минут, PERIOD_M15: 15 минут, PERIOD_M30: 30 минут, PERIOD_H1: 1 час и PERIOD_D1: 1 день.exchange.GetRecords(PERIOD_M1). После обновления последнего докера он будет поддерживать настройку периодов, которые просто проходят второе число периода в качестве параметра. Настройка на уровне минуты будет синтезироваться в соответствии с 1-минутной K-линией, K-линия менее 1 минуты будет синтезироваться через GetTrades))) и товарные фьючерсы будут синтезироваться в соответствии с тиком.Обратите внимание, что есть также другие полные большие переменные, какPERIOD_M1Это глобальные переменные FMZ по умолчанию. Если вы заинтересованы, вы можете log их конкретные значения сами, и вы можете использовать их непосредственно в обычном.

Пример возвращения данных:

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

Пример итерации линии K:

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
}

GetTrades

GetTrades получает торговые данные в течение определенного промежутка времени (не ваши собственные торговые данные), что не поддерживается некоторыми платформами.

Получить учетную запись для торговли

Эти интерфейсы связаны с учетной записью, поэтому их нельзя получить напрямую. Чтобы получить их, вам нужно использовать API-KEY для подписания. После унифицированной автоматической обработки фоновой информации платформы FMZ вы можете использовать их напрямую.

Получить учетную запись

GetAccount для получения информации о счете. Как один из наиболее часто используемых интерфейсов, он должен быть вызван перед размещением заказа, чтобы избежать недостаточного баланса.{"Stocks":0.38594816,"FrozenStocks":0,"Balance":542.858308,"FrozenBalance":0,"Info":{}}где Stocks представляет собой доступный сальдо торговой валюты торговой пары, FrozenStocks представляет собой замороженный сальдо неисполненных ордеров, Balance представляет собой доступную сумму валюты котировки, а FrozenBalance представляет собой замороженный сальдо.BTC_USDT, Stocks относится к BTC, а Balance относится к USDT.

Обратите внимание, что результат возврата является результатом указанной торговой пары, а информация о других валютах на торговом счете находится в поле Info, поэтому вам не нужно вызывать его несколько раз, когда вы управляете несколькими торговыми парами.

Бот постоянно печатает общую стоимость текущей торговой пары:

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

Заказ на покупку

Способы вызова включаютexchange.Buy(Price, Amount)иexchange.Buy(Price, Amount, Msg), в котором Price указывает цену, Amount - сумму, Msg - дополнительную строку, которая может отображаться в журнале ботов, но не требуется. Эти методы являются ожидающимися заказами. Если заказ не может быть полностью выполнен немедленно, будет сгенерирован незавершенный заказ; ID заказа возвращается, если заказ успешно размещен, иnullбудет возвращена, если заказ не удастся, который используется для запроса статуса заказа.

Если вы хотите разместить ордер на покупку по рыночной цене, Цена равна -1, а Сумма - стоимость ордера.exchange.Buy(-1, 0.5); если торговая параETH_BTCНекоторые платформы не поддерживают рыночные заказы, а фьючерсы не проверяют обратную связь.

Некоторые платформы имеют требования к точности цены и суммы, которые могут контролироваться с помощью функции точности_N()Для торговли фьючерсами Buy и Sell имеют другие значения, которые будут специально представлены.

Пример покупки после достижения соответствующей цены:

function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var price = ticker.Sell
        if(price >= 7000){
            exchange.Buy(_N(price+5,2), 1, 'BTC-USDT')
            break
        }
        Sleep(3000)//Sleep 3000ms
    }
    Log('done')
}

Заказ на продажу

Порядок продажи. Параметры одинаковы с Buy. Параметры рыночного ордера имеют разные значения.exchange.Sell(-1, 0.2), означает продажу 0,2 ETH по рыночной цене.

Получить Ордер

GetOrder получает информацию о заказе на основе идентификатора заказа.exchange.GetOrder(OrderId), OrderId - это идентификатор заказа, который будет возвращен при размещении заказа.Typeи фактическую стоимость заказаStatusFMZ использует глобальные константы для представления этих значений.Statusзначение незавершенного заказа равняется 0, что эквивалентноORDER_STATE_PENDING. Все эти глобальные константы можно просматривать в документе... Результат возврата:

{
    "Id":125723661, //Order id
    "Amount":0.01, //Order ammount 
    "Price":7000, //Order price 
    "DealAmount":0, //Executed amount 
    "AvgPrice":0, //executed average price
    "Status":0, //0: not completely executed; 1: executed; 2: canceled 
    "Type":1,//Order type; 0: buy order; 1: sell order 
    "ContractType":"",//contract type, used in futures trading
    "Info":{} //the platform returns the raw information
    }
}

Стратегия покупки определенного количества валюты:

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(5-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){ //Here you can aslo use "status == ORDER_STATE_PENDING" to judge 
                exchange.CancelOrder(id)
            }
        }
    }
}

GetOrders

GetOrder получает список всех незавершенных заказов текущей торговой пары. Если нет незавершенного заказа, возвращается пустой массив. Конкретный результат списка заказов, например GetOrder.

Пример отмены всех ордеров текущей торговой пары:

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

Отменить заказ

Согласно номеру заказа, отменить заказ.exchange.CancelOrder(OrderId). Если отмена удалась, возвращается true; если нет, возвращается false.

Фьючерсы и вечный контракт

Для криптовалюты фьючерсная торговля отличается от спотовой торговли. Вышеперечисленные функции спотовой торговли также применимы к торговле фьючерсами, а одиночная фьючерсная торговля имеет свои функции. Перед проведением программной торговли криптовалютными фьючерсами вы должны быть знакомы с ручными операциями на веб-сайте и понимать основные концепции, такие как открытое, закрытое, перекрестное, изолированное, рычаг, близкая прибыль и убыток, плавающий доход, маржа и другие концепции, а также соответствующие формулы расчета. Соответствующие учебники можно найти на различных фьючерсных платформах, и вам нужно научиться им самостоятельно.

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

Если платформа поддерживает как фьючерсы, так и спотовые, такие как фьючерсы OKEX и Huobi, вам необходимо выбрать OKEX Futures и Huobi Futures отдельно на интерфейсе платформы для добавления, поскольку эти фьючерсные платформы рассматриваются как разные платформы от спотовых на FMZ.

SetContractType

Первый шаг в торговле фьючерсами заключается в установке контракта, который будет торговаться. В качестве примера возьмем фьючерсы OKEX, выберите торговую пару BTC при создании бота или бэкстестинга, а также необходимо установить еженедельный, следующую неделю или квартальный контракт в коде. Если он не установлен, он попроситinvalid contract type. В отличие от спотовых торговых пар, фьючерсные контракты часто используют торговую валюту, такую как BTC, в качестве маржи. Добавление BTC к торговой паре обычно представляет собой торговую пару BTC_USD, которая использует BTC в качестве маржи. Если есть фьючерсный контракт с USDT в качестве маржи, необходимо создать бот для добавления торговой пары BTC_USDT. Например, вечные контракты, такие как Binance OKEX Futures, с контрактами с крипто-маржировкой и контрактами с маржировкой USDT.После установки торговой пары, вы также должны установить конкретный тип контракта, например, вечный, еженедельный, следующей недели и т. Д. После установки контракта, вы можете выполнять операции, такие как получение рыночных котировок, покупка и продажа.

Binance, OKEX, HuobiDM и т. Д. Имеют контракты с крипто-маржировкой и контракты с маржировкой USDT, которые необходимо различать при добавлении бота и настройке контракта.

//OKEX Futures
exchange.SetContractType("swap")        // set to perpetual contract
exchange.SetContractType("this_week")   // set to weekly contract 
exchange.SetContractType("next_week")   // set to next week contract 
exchange.SetContractType("quarter")     // set to quarterly contract

//HuobiDM
exchange.SetContractType("this_week")   // set to weekly contract 
exchange.SetContractType("next_week")   // set to next week contract
exchange.SetContractType("quarter")     // set to quarterly contract 
exchange.SetContractType("swap")        // set to perpetual contract

//Binance Futures
exchange.SetContractType("swap")   // set to perpetual contract, and notice that crypto-margined and USDT-margined contracts are all in the perpetual contract
exchange.SetContractType("quarter")   // set to quarterly contract
exchange.SetContractType("next_quarter")  // set to next quarter contract

//BitMEX
exchange.SetContractType("XBTUSD")    // set to perpetual contract
exchange.SetContractType("XBTM19")  // the contract settled at a specific time; for more details, please log in BitMEX to check each contract code

//GateIO
exchange.SetContractType("swap")      // set to perpetual contract, and do not set the default as swap perpetual contract 
//Deribit
exchange.SetContractType("BTC-27APR18")  // the contract settled at a specific time; for more details, please log in Deribit to check out 

ПолучитьПозицию

Для получения списка информации о текущей позиции фьючерсы OKEX (OKCOIN) могут передаваться в параметр для указания типа контракта, который будет получен.[], если нет позиции. Информация о позиции возвращается следующим образом. Существует много конкретной информации, которую необходимо проанализировать в сочетании с торговой парой.

Тип данных Имя переменной Описание
объект Информация необработанная структура, которую возвращает платформа
Номер Уровень маржи размер рычага; OKCoin составляет 10 или 20, а перекрестная позиция OK фьючерсов возвращает 10 (фиксированный), для сырого API не поддерживает
Номер Сумма сумма позиции; OKCoin указывает количество контракта (целое число больше 1)
Номер Замороженная сумма сумма замороженной позиции
Номер Цена средняя цена позиции
Номер Маржинальная сумма замороженный марж
Номер Прибыль товарные фьючерсы: прибыль и убыток позиции на рынке; криптовалюта: криптовалютная единица: BTC/LTC, традиционная фьючерсная единица: RMB (примечание:в случае перекрестной позиции фьючерсов OKCoin, это относится к реализованной прибыли и убытку, а не к прибыли и убытку позиции. При изолированной позиции это относится к прибыли и убытку позиции.)
конст Тип PD_LONG - длинная позиция (CTP использует closebuy_today для закрытия позиции ); PD_SHORT - короткая позиция (CTP использует closesell_today для закрытия позиции); в фьючерсах CTP PD_LONG_YD указывает на длинную позицию вчера (которая использует closebuy для закрытия позиции); PD_SHORT_YD - короткая позиция вчера (которая использует closesell для закрытия позиции)
строка Тип контракта Фьючерсы на сырьевые товары - это коды контрактов, а акции - код платформы_код акций; переданный тип специфических параметров SetContractType
function main(){
    exchange.SetContractType("this_week");
    var position = exchange.GetPosition();
    if(position.length>0){ //especially pay attention to judging the length of position before call, or an error will occur
        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)
    }
}

Фьючерсы открытые и закрытые позиции

Во-первых, вам нужно установить размер рычага; метод вызова:exchange.SetMarginLevel(10), где 10 означает 10-кратный уровень кредитного плеча, а конкретный размер поддерживаемого кредитного плеча можно проверить на соответствующих платформах,Обратите внимание, что рычаг должен быть установлен на платформе, и код должен соответствовать настройкам, установленным на платформе, в противном случае произойдет ошибка.Вы также можете оставить его не настроенным и использовать рычаг подзагрузки. Затем установите направление торговли; метод вызова:exchange.SetDirection(Direction), что соответствует открытым и закрытым позициям.В отличие от фьючерсов, если вечный контракт не содержит концепции длинного и короткого одновременно, то есть не допускается одна позиция.buyиsellЕсли он поддерживает двусторонние позиции, вы должны установитьclosebuy, closesell.Конкретные отношения:

Операция Параметры направления Функция установления порядка
Открытая длинная позиция Обмен.Установка направления ((купить) Обмен.Купить ((()
Закрыть длинную позицию Обмен.Установка направления ((closebuy) Обмен.Продажа.
Открытая короткая позиция Обмен.Установка направления ((продажа) Обмен.Продажа.
Закрыть короткую позицию Обмен.Установка направления ((закрытие продажи) Обмен.Купить ((()

Наконец, есть конкретный код для открытых и закрытых позиций. Количество размещенных заказов варьируется от платформы к платформе. Например, фьючерсы Huobi основаны на количестве контракта, и один контракт составляет 100 долларов США.

function main(){
    exchange.SetContractType("this_week")    // for example, set OKEX futures to weekly contract 
    price = exchange.GetTicker().Last
    exchange.SetMarginLevel(10) // set to 10 times of leverage  
    exchange.SetDirection("buy") // set the order type as buy long 
    exchange.Buy(price+10, 20) // set contract quantity as 20 orders
    pos = exchange.GetPosition()
    Log(pos)
    Log(exchange.GetOrders()) // check out if there is any unfinished order 
    exchange.SetDirection("closebuy"); // if it is a perpetual contract, directly set exchange.SetDirection("sell")
    exchange.Sell(price-10, 20)
}

Приведите конкретный пример стратегии полного закрытия позиций:

function main(){
    while(true){
        var pos = exchange.GetPosition()
        var ticker = exchange.GetTicekr()
        if(!ticker){
            Log('not able to obtain ticker')
            return
        }
        if(!pos || pos.length == 0 ){
            Log('no position')
            return
        }
        for(var i=0;i<pos.length;i++){
            if(pos[i].Type == PD_LONG){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closebuy')
                exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
            }
            if(pos[i].Type == PD_SHORT){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closesell')
                exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
            }
        }
        var orders = exchange.Getorders()
        Sleep(500)
        for(var j=0;j<orders.length;j++){
            if(orders[i].Status == ORDER_STATE_PENDING){
                exchange.CancelOrder(orders[i].Id)
            }
        }
    }
}

Торговля криптовалютными инструментами

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

Использованиеexchange.IO("trade_margin") для перехода на режим учетной записи с рычагом использования; размещение ордера и получение активов счета будут иметь доступ к интерфейсу платформы с рычагом использования. Использованиеexchange.IO("trade_normal") для перехода на обычный режим счета.

Поддерживаемые платформы:

  • OKEX V3: Торговые пары режима счета с использованием рычага отличаются от обычных, а некоторые торговые пары могут не существовать.
  • Huobi: торговые пары в режиме учетного счета с использованием рычага отличаются от обычных, и некоторые торговые пары могут не существовать.
  • ZB: активы могут быть переведены только в QC. В секторе торговли с использованием кредитного плеча активы между различными торговыми парами независимы, то есть количество монет QC в торговой паре ETH_QC не видно в BTC_QC.
  • FCoin
  • Binance

Торговля товарными фьючерсами

Торговля товарными фьючерсами и торговля криптовалютными фьючерсами совершенно отличаются друг от друга. Во-первых, время торговли товарными фьючерсами очень короткое, но криптовалюта торгуется в течение 24 часов; протокол товарных фьючерсов не является широко используемым REST API; частота торговли и объем ожидаемых заказов товарных фьючерсов ограничены, но криптовалютные фьючерсы очень свободны и так далее. Поэтому при торговле товарными фьючерсами есть много пунктов, нуждающихся в особом внимании, и его рекомендуют тем, кто имеет богатый опыт в ручных операциях.https://www.fmz.com/bbs-topic/325Для добавления товарных фьючерсных компаний:https://www.fmz.com/bbs-topic/371

Фьючерсы на сырьевые товары внедрили прозрачный надзор в июне 2019 года; для отдельной программы отдельным пользователям необходимо открыть счет для подачи заявки на код авторизации для фьючерсных брокеров (специфический шаблон информации о заявке может быть отправлен в группу WeChat или QQ group), что обычно занимает 4-5 дней; процедуры довольно сложные. Как программный провайдер торговли, платформа FMZ подала заявку на коды авторизации программного обеспечения от различных поставщиков фьючерсных услуг. Пользователи могут использовать их непосредственно без подачи заявки. При добавлении фьючерсного брокера, поищите see through, чтобы увидеть список, на который подала заявку FMZ. Конкретная справочная запись:https://www.fmz.com/bbs-topic/3860. Если ваш фьючерсный брокер больше не в списке, вы можете подать заявку только самостоятельно или открыть новый счет поддерживаемого брокера, что обычно занимает 2 дня. FMZ имеет углубленные отношения сотрудничества с некоторыми поставщиками услуг; например, Guotai Junan Hongyuan Futures приобрела институциональную версию платформы FMZ, которую могут использовать ее пользователи, и пользователи автоматически становятся VIP при открытии счета, а плата за обслуживание минимизируется. Справка об открытии счета:https://www.fmz.com/bbs-topic/506.

Благодаря преимуществам структуры платформы FMZ Quant, пользователи также могут добавлять несколько учетных записей фьючерсных брокеров и реализовывать некоторые функции, которые другие программные программы торговли товарными фьючерсами не могут выполнить, такие как синтез высокочастотного тика; вы можете обратиться к:https://www.fmz.com/bbs-topic/1184

Рамочная стратегия

Прежде всего, поскольку это не 24-часовая торговля и требует операции входа, необходимо судить о статусе ссылки перед торговлей.exchange.IO("status")этоtrue, что указывает на успешное подключение к платформе. Если API вызвано, когда вход не удается, not login не будет запрошен. Вы можете добавить Sleep (2000) после запуска стратегии, давая ему определенное время для входа. Вы также можете попробовать повторно подписаться_C(exchange.SetContractType,"MA888"), что обеспечит успешный вход.

Коды покупки и торговли товарными фьючерсами аналогичны кодам покупки и торговли криптовалютными фьючерсами. Здесь мы представим различия и моменты, на которые необходимо обратить внимание.

function main(){
    _C(exchange.SetContractType,"MA888") //If you do not log in successfully, you cannot subscribe to the contract, so better to try again
    while(true){
        if(exchange.IO("status")){
            var ticker = exchange.GetTicker()
            Log("MA888 ticker:", ticker)
            LogStatus(_D(), "Already connected with CTP !")//_D obtain event
        } else {
            LogStatus(_D(), "Not connected with CTP !")
            Sleep(1000)
        }
    }
}

Рекомендуется использовать для торговли библиотеку товарных фьючерсов (которая будет описана позже), код будет очень простым на данный момент, и нет необходимости иметь дело с утомительными деталями.https://www.fmz.com/strategy/57029

function main() {
    // Use the CTA strategy framework of commodity futures library 
    $.CTA(Symbols, function(st) {
        var r = st.records
        var mp = st.position.amount
        var symbol = st.symbol
        /*
        "r" represents K-line, "mp" indicates the position amount of the current variety; positive number means long position, negative number means short position, and 0 means no position; "symbol" is the variety name
        if the return value is n: 
            n = 0 : full close positions (no matter now they are long or short)
            n > 0 : if right now long positions are held, add n long positions; if now they are short positions, close n short posiitons; if n is over the position amount right now, reverse to open long positions 
            n < 0 : if right now short positions are held, add n short positions; if now they are long positions, close n long posiitons; if -n is over the position amount right now, reverse to open short positions 
        */
        if (r.length < SlowPeriod) {
            return
        }
        var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod));
        if (mp <= 0 && cross > ConfirmPeriod) {
            Log(symbol, "Golden Cross Period", cross, "the moment position", mp);
            return Lots * (mp < 0 ? 2 : 1)
        } else if (mp >= 0 && cross < -ConfirmPeriod) {
            Log(symbol, "Death Cross Period", cross, "the moment position", mp);
            return -Lots * (mp > 0 ? 2 : 1)
        }
    });
}

Способы получения данных о СТП

Фьючерсы на сырьевые товары используют протокол CTP, и все котировки на рынке и исполнение ордеров будут уведомлены только после изменений, в то время как запросы об ордерах, счетах и позициях являются активными запросами.GetTicker, GetDepthиGetRecords, все должны иметь кэшированные данные, чтобы получить последние данные. Если нет данных, он будет ждать, пока есть данные, поэтому не нужно, чтобы стратегия использовала Sleep. Когда есть изменения котировок рынка, тикер, глубина и записи будут обновляться. В это время вызов любого из этих интерфейсов будет возвращен немедленно, и состояние вызванного интерфейса будет настроено на режим wait for update. В следующий раз, когда тот же интерфейс будет вызван, он будет ждать, пока не будут возвращены новые данные. Некоторые непопулярные контракты или ценовой лимит вызовут отсутствие торговли в течение длительного времени, что означает, что стратегия застряла в течение длительного времени, также нормально.

Если вы хотите получить данные каждый раз, когда вы получаете рыночные котировки, даже если это старые данные, вы можете переключиться на режим немедленного обновления рыночных котировокexchange.IO("mode", 0). В это время стратегия не может быть написана как управляемая событиями, и необходимо добавить событие SLeep, чтобы избежать быстрой бесконечной петли.exchange.IO("mode", 1)чтобы вернуться в режим кэша по умолчанию.

При работе с одним контрактом используйте режим по умолчанию. Однако, если существует несколько контрактов, возможно, что один из контрактов не обновляет котировки рынка, в результате чего блокируется интерфейс для получения котировок рынка, и обновления котировок других контрактов также не могут быть получены. Для решения этой проблемы можно использовать режим немедленного обновления, но неудобно писать высокочастотные стратегии.exchange.IO("wait")Если добавлено несколько обменных объектов, что редко встречается в товарных фьючерсах, вы можете использоватьexchange.IO("wait_any"), а возвращенный Index укажет возвращенный индекс платформы.

Продвижение изменений на рынке:{Event:"tick", Index: platform index (in the order of the platforms added in the bot), Nano: event of nanosecond-level time, Symbol: contract name}Заказы:{Event:"order", Index:Exchange index, Nano:Event of nanosecond-level time, Order:Order information (same as GetOrder)}

К этому времени структура стратегии может быть написана так:

function on_tick(symbol){
    Log("symbol update")
    exchange.SetContractType(symbol)
    Log(exchange.GetTicker())
}

function on_order(order){
    Log("order update", order)
}

function main(){
    while(true){
        if(exchange.IO("status")){ //Judge the link status 
            exchange.IO("mode", 0)
            _C(exchange.SetContractType, "MA888")//Subscribe to MA; only the subscription request for the first time is ture, and the later ones are program switches, which do not consume time
            _C(exchange.SetContractType, "rb888")//Subscribe to rb
            while(true){
                var e = exchange.IO("wait")
                if(e){
                    if(e.event == "tick"){
                        on_tick(e.Symbol)
                    }else if(e.event == "order"){
                        on_order(e.Order)
                    }
                }
           }
        }else{
            Sleep(10*1000)
        }
    }
}

Различия между товарными фьючерсами и криптовалютами

Также обратите внимание на разницу между товарными фьючерсами и криптовалютными платформами. Например, GetDepth на самом деле имеет только один уровень глубины (5 уровней глубины дороги), а GetTrades не может получить историю торговли (все имитируются на основе изменений позиции, и нет реального торгового рекорда). Фьючерсы на товары имеют механизм ценового лимита. Когда лимит выше, цена ордера на продажу на глубину является предельной ценой, а объем ордера равен 0. Когда лимит ниже, цена ордера на покупку является предельной ценой, а объем ордера равен 0. Кроме того, частота интерфейса запроса товарных фьючерсов, таких как получение счетов, ордеров и позиций, строго ограничена, обычно каждые 2 секунды. Фьючерсы на товары также имеют ограничения на количество размещенных и отмененных ордеров.

Контракты набора

exchange.IO("инструменты"): возвращает список всех контрактов на платформе {наименование контракта: подробности} в виде словаря и поддерживает только ботов.exchange.IO("продукты"): он возвращает список всех элементов на платформе {наименование контракта: подробности} в виде словаря и поддерживает только ботов.exchange.IO("подписанный"): он возвращает подписанные рыночные котировки на платформе в виде словаря и поддерживает только ботов.

ВContractTypeТрадиционные фьючерсы CTP относятся к идентификатору контракта, который чувствителен к буквам и буквам.exchange.SetContractType("au1506"). После успешного настройки контракта он вернет подробную информацию о контракте, такую как минимальная сумма покупки, плата за обслуживание, время доставки и т. Д. При подписке на несколько контрактов только в первый раз запрос на подписку фактически отправляется, а затем торговая пара просто переключается на уровне кода, что не занимает времени. Основным непрерывным контрактом является код 888, такой как MA888, контракт непрерывной ставки - 000, такой как MA000; 888 и 000 являются виртуальными контрактными сделками, которые поддерживают только бэкстест, а реальные боты поддерживают только рыночные котировки.Тем не менее, Mylanguage может управлять основным контрактом, и программа автоматически меняет позиции, то есть закрывает не основные позиции и открывает новые позиции на основных позициях.

Неудачный вход не может установить контракты, но вернется немедленно, поэтому вы можете попробовать снова, чтобы узнать, что вход CTP завершен.

Открытая позиция и закрытая позиция

Руководство SetDirectionможет получить четыре параметра:buy, closebuy, sell, closesellФьючерсы на товары имеют большеclosebuy_todayиclosesell_today, указывающий на закрытие текущих позиций;closebuy/ closesellДля традиционных фьючерсов CTP вы можете установить второй параметр как 1 или 2 или 3, что относится к спекуляции, арбитражу и хеджированию соответственно. Если не установить, то по умолчанию это спекуляция.Конкретные операции, такие как покупка и продажа, получение позиций, получение заказов, отмена заказов и получение счетов, такие же, как торговля фьючерсами криптовалют, поэтому обратитесь к предыдущему разделу.

Операция Параметры направления Функция установления порядка
Открытая длинная позиция Обмен.Установка направления ((купить) Обмен.Купить ((()
Закрыть длинную позицию Обмен.Установка направления ((closebuy) Обмен.Продажа.
Открытая короткая позиция Обмен.Установка направления ((продажа) Обмен.Продажа.
Закрыть короткую позицию Обмен.Установка направления ((закрытие продажи) Обмен.Купить ((()

Следующий пример - это конкретная функция закрытия позиции. Обратите внимание, что этот пример слишком прост. Вы также должны рассмотреть, находится ли он в течение торгового времени, как перепробовать ожидаемый ордер, если он не полностью заполнен, какой максимальный объем ордера, является ли частота слишком высокой, и является ли это скользящей ценой или рыночной ценой и так далее.это библиотечный пакет предлагаемых платформ для открытия и закрытия позиций в реальных ботах:https://www.fmz.com/strategy/12961В разделе "Библиотека" есть специальное введение, и также рекомендуется изучить исходные коды библиотеки.

function Cover(contractType, amount, slide) {
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType != contractType) {
            continue;
        }
        var depth = _C(e.GetDepth);
        if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
            exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
            exchange.Sell(depth.Bids[0]-slide, amount, contractType, positions[i].Type == PD_LONG ? "Close today" : "Close yesterday", 'Bid', depth.Bids[0]);
        } else {
            exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
            exchange.Buy(depth.Asks[0]+slide, amount, contractType, positions[i].Type == PD_SHORT ? "Close today" : "Close yesterday", 'Ask', depth.Asks[0]);
        }
    }
}

Фьючерсы на сырьевые товары поддерживают типы пользовательских ордеров (поддержка ботов, но не для бэкстеста), которые определяются суффиксом, приложенным к _, например:

exchange.SetDirection("buy_ioc");
exchange.SetDirection("sell_gtd-20170111")

Специфические суффиксы:

  • ioc немедленно завершить, или отменить THOST_FTDC_TC_IOC
  • gfs действительны в узле THOST_FTDC_TC_GFS
  • gfd действителен в день THOST_FTDC_TC_GFD
  • gtd действует до указанной даты THOST_FTDC_TC_GTD
  • gtc действует до отмены THOST_FTDC_TC_GTC
  • gfa действителен при аукционных торгах THOST_FTDC_TC_GFA

Интерфейс Esunny

По умолчанию интерфейсы, открываемые в товарных фьючерсных брокерах, являются всеми интерфейсами CTP. При необходимости их можно заменить интерфейсами Esunny. Благодаря инкапсуляции FMZ метод вызова одинаков. Разница заключается в том, что учетные записи, заказы и позиции все находятся в пуш-режиме, поэтому докер будет поддерживать эти данные локально и немедленно вернется, когда будет вызван соответствующий интерфейс, не делая запроса.

Протокол Esunny Типы пользовательских заказов:

  • gfd действителен в день TAPI_ORDER_TIMEINFORCE_GFD
  • gtc действителен до отмены TAPI_ORDER_TIMEINFORCE_GTC
  • gtd действителен до указанной даты TAPI_ORDER_TIMEINFORCE_GTD
  • fak Частично выполнено, отменить остальное TAPI_ORDER_TIMEINFORCE_FAK
  • ioc выполнять немедленно, или отменить TAPI_ORDER_TIMEINFORCE_FAK
  • fok не выполнен полностью, отменить все TAPI_ORDER_TIMEINFORCE_FOK

Часто используемые глобальные функции

Регистрация - Регистрация & WeChat Push

При регистрации записи журнала на интерфейсе бота и добавлении символа @ после строки сообщение будет входить в очередь push, и оно будет отправлено непосредственно после привязки к WeChat или Telegram, напримерLog('Push to WeChat@').

Цвет лога также может быть настроен, например:Log('this is a log in red font #ff0000'). #ff0000является шестой знаком цвета RGB, что указывает на то, что все файлы журнала хранятся в базе данных SqLit бота в каталоге, в котором расположен докер, который можно загрузить и открыть с помощью программного обеспечения для базы данных, или можно использовать для копирования резервного копирования и восстановления (наименование базы данных и идентификатор бота одинаковы).

LogProfit - Прибыль от печати

Он записывает прибыль и рисует кривую прибыли на интерфейсе бота, который может быть сохранен после перезагрузки бота.LogProfit(1000). Обратите внимание, что параметрLogProfitЭто не обязательно прибыль, и это может быть любое число и нужно заполнить самостоятельно.

LogStatus - отображение состояния (включая таблицы)

Если статус бота, так как журнал будет сохранен первым и обновляется постоянно, требует информации только для отображения не для сохранения, вы можете использоватьLogStatusПараметрыLogStatusявляются строками, которые также могут быть использованы для представления информации таблицы.

Пример конкретной таблицы отображения реальной позиции бота:

var table = {type: 'table', title: 'position information', cols: ['Column1', 'Column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}; 
LogStatus('`' + JSON.stringify(table) + '`'); // After serialization, JSON will be added the character "'" on both sides, which is regarded as a comlpex messag format (now supporting tables)
LogStatus('The first line information\n`' + JSON.stringify(table) + '`\nthe third line information'); // the table information can be displayed in multiple lines
LogStatus('`' + JSON.stringify([table, table]) + '`'); // Multiple tables are supported to be displayed at the same time, which will be displayed in one group by TAB  
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n

Больше