
В предыдущей статье мы говорили о скриптах программной торговли. По сути, торговая стратегия — это торговая скриптовая программа. В статье в основном говорится о необходимости аппаратного носителя для торговой скриптовой программы (где программа работает), на каком языке программирования можно написать эту торговую скриптовую программу (листинг использование платформы количественной торговли Inventor Существует три языка программирования. Конечно, вы можете использовать любой язык программирования для реализации стратегий программной торговли). В этой статье мы продолжим обсуждение количественного анализа криптовалютного круга и разберемся в знаниях количественного анализа криптовалютного круга.
Типы торговых стратегий Новички, которые только знакомятся с программной торговлей и количественной торговлей, могут быть сбиты с толку различными терминами, такими как трендовые стратегии, арбитражные стратегии, высокочастотные стратегии, сеточные стратегии и т. д. Фактически, общие типы стратегий программной торговли и количественной торговли можно просто описывается следующим образом: Несколько направлений.
Вышеизложенное разделено с точки зрения торговых стратегий. С точки зрения разработки стратегии на платформе количественной торговли Inventor стратегии также можно разделить на:
Стратегия одного продукта Другими словами, эта стратегия работает только с одним продуктом, например, с торговлей BTC или ETH.
Стратегия мультипродукта Проще говоря, это означает эксплуатацию нескольких видов продукции в соответствии с стратегической логикой.
Стратегия с несколькими счетами Проще говоря, это настройка нескольких объектов обмена на реальном диске (концепция обмена была введена в предыдущей статье, а объект обмена с настроенным API KEY представляет собой учетную запись обмена). Например, некоторые стратегии копирования сделок предполагают наличие нескольких счетов, следующих за операцией (это может быть одна и та же биржа или разные биржи). Короче говоря, несколько объектов биржи (счетов) управляются на одном реальном счете.
Множественные логические стратегии Например, на реальном рынке стратегия MACD, стратегия скользящей средней, стратегия сетки и т. д. разрабатываются одновременно (конечно, они работают на разных биржевых объектах. Если вы работаете на одном и том же биржевом объекте, вам нужно посмотреть, (конкретные стратегии имеют логические конфликты)
API-интерфейс обмена Как запрограммированные торговые скрипты управляют биржевыми счетами? Ответ — через API-интерфейс, открытый биржей. Итак, какие типы интерфейсов открыты для обмена? В предыдущей статье мы говорили о разделе «Обмен», в котором говорилось, что обмены обычно имеют интерфейсы REST и Websocket. Здесь мы добавляем некоторые концепции с уровня стратегической программы. Интерфейсы обмена делятся на два типа: проверенные и непроверенные, в зависимости от того, проверены они или нет (как REST, так и Websocket).
Интерфейсы, не требующие аутентификации
Обычно называемый «публичным интерфейсом», этот тип интерфейса не требует проверки.API KEY(Если вы забыли, что такое API KEY, вы можете обратиться к предыдущей статье). Этот тип интерфейса, как правило, представляет собой рыночный интерфейс, такой как запрос глубокой рыночной информации, запрос данных K-line, запрос ставок финансирования, запрос информации, связанной с транзакционными продуктами, запрос временных меток сервера обмена и т. д.
Проще говоря, интерфейс, который не имеет никакого отношения к вашей учетной записи, можно приблизительно определить как публичный интерфейс (проверка не требуется).
На платформе количественной торговли Inventor при вызове непроверенной функции API (инкапсулирующей непроверенный интерфейс биржи, публичный интерфейс) даже если API KEY настроен неправильно, данные, возвращаемые интерфейсом, могут быть получены в обычном режиме. (Потому что это не проверено)
Интерфейсы, которые необходимо проверить Проще говоря, это интерфейс, который необходимо проверить (проверить API KEY). Такой тип интерфейса называется приватным интерфейсом. Этот тип интерфейса обычно связан с некоторыми операциями или информацией по вашему счету, такими как запрос активов счета, запрос позиций счета, запрос отложенных ордеров, запрос переводов, перевод монет, настройка кредитного плеча, настройка режимов позиций и т. д. Эти операции должны быть проверены. На платформе количественной торговли Inventor при вызове функции API, требующей проверки (интерфейс, который инкапсулированный обмен должен проверить, закрытый интерфейс), если API KEY настроен неправильно, при вызове интерфейса будет выдано сообщение об ошибке и Будет возвращено нулевое значение.
Так как же эти интерфейсы используются на платформе количественной торговли Inventor?
Количественная торговая платформа Inventor инкапсулирует поведение биржи и определяет последовательные интерфейсы (такие как интерфейс K-line, интерфейс глубокого рынка, интерфейс запроса текущих активов, интерфейс заказа, интерфейс снятия заказа и т. д.). Эти интерфейсы называются API-функциями Информацию о количественной торговой платформе Inventor можно получить, запросив документацию API (https://www.fmz.com/api).
Так как же использовать некоторые интерфейсы обмена с непоследовательным поведением и определениями на платформе количественной торговли Inventor?
К таким интерфейсам обмена относятся: передача активов, условное поручение, размещение пакетного заказа, отмена пакетного заказа, изменение заказа и т. д. Некоторые биржи имеют эти интерфейсы, а другие нет. Их функции и детали использования могут сильно различаться. Поэтому эти интерфейсы доступны на платформе количественной торговли Inventor.exchange.IOЭта функция используется для доступа (подробности см. в документе API количественной торговой платформы Inventor: https://www.fmz.com/api#exchange.io…). На Strategy Square количественной торговой платформы Inventor также есть несколько практических примеров стратегий ввода-вывода.
Все ли функции API в документации API платформы количественной торговли Inventor генерируют сетевые запросы?
Давайте сначала предположим, что API-интерфейс биржи имеет ограничение частоты доступа (например, 5 раз в секунду). Доступ не может быть слишком частым, иначе он сообщит об ошибке http 429 и откажет в доступе (большинство бирж сообщают об ошибке 429). ). Такое же ограничение применяется и к вызову интерфейса пакетного обмена на платформе количественной торговли Inventor. Для функций API на платформе количественной торговли Inventor, которые не генерируют сетевые запросы, такого ограничения нет. Не все функции API количественной торговой платформы Inventor будут генерировать сетевые запросы. Некоторые функции API Inventor изменяют только некоторые локальные настройки, такие как установка текущей торговой пары, установка кода контракта, функция расчета индикатора, получение имени объекта обмена, и т. д. В принципе, вы можете судить о том, происходит ли сетевой запрос, исходя из цели функции. Пока это получение данных обмена, работа с учетными записями обмена и т. д., сетевой запрос будет сгенерирован. Эти интерфейсы должны обращать внимание на частота звонков.
Давайте поговорим о некоторых распространенных проблемах и опыте использования функций API на платформе количественной торговли Inventor.

При написании стратегий нам необходимо оценивать и проверять данные, возвращаемые интерфейсом. Например, эта строка кода используется для получения рыночной информации на платформе количественной торговли Inventor (то же самое верно при написании программы для прямого доступа к бирже интерфейс):var ticker = exchange.GetTicker()Если нам нужно это использоватьtickerПеременная (см. структуру, возвращаемую функцией GetTicker)Last(последние цены) данные, нам нужно использоватьvar newPrice = ticker.LastПолучите данные следующим образом (что такое newPrice? new: latest, Price: price, да! Соедините их вместе!) В это время, еслиGetTicker()Это нормально, если функция возвращает нормальные данные, но если запрос истекает по времени, происходят сетевые ошибки, обменник отключает сетевой кабель, кабель перерезается, непослушный ребенок дергает выключатель питания и т. д., это приведет кGetTicker()Функция возвращаетnull. в это времяtickerЗначение равноnullЯ посещу его снова.LastПроизойдет исключение программы, которое приведет к остановке программы политики.
Похоже, что сбой вызова интерфейса (вызов GetTicker завершился неудачей и вернул null) не является прямой причиной остановки реальной торговли стратегии (прямая причина — доступ кnullПеременные свойства), сбой вызова интерфейса и ошибка не приведут к остановке реальной торговли (выделено мной).
Так что же мы можем сделать, чтобы избежать ненормальной приостановки реальной торговли?
Ответ заключается в том, чтобы выполнить обработку отказоустойчивости данных, возвращаемых интерфейсом. Очень просто определить, являются ли возвращаемые данныеnull(JavaScript используется в качестве примера, другие языки в принципе такие же)
Напишите небольшой фрагмент кода для пояснения (это всего лишь объяснение, оно не будет работать, если вы запустите его напрямую!)
var ticker = exchange.GetTicker()
if (ticker) {
var newPrice = ticker.Last
Log("打印最新价格:", newPrice)
} else {
// 数据为null,不做操作就不会出问题
}
Не толькоGetTickerИнтерфейс должен быть отказоустойчивым. Все интерфейсы с сетевыми запросами должны быть отказоустойчивыми для возвращаемых значений (если вы используете возвращаемое значение функции)
Есть много способов терпеть недостатки, вы можете использовать_C()Функция (см. документацию FMZ API), напишите собственную отказоустойчивую функцию и разработайте собственный отказоустойчивый механизм и логику.
о_C()При использовании функций многие новые студенты, скорее всего, будут использовать их неправильно._C()Параметры функции — это ссылки на функции, а не вызовы функций. Проще говоря:
_C(funcName, param1, param2), вызов правильный, funcName не имеет скобок, param1 и param2 — параметры, которые необходимо передать функции funcName.
_C(funcName(param1, param2)), ошибка вызова, обычно новички, которые невнимательно читают документацию FMZ API, пишут это так.
LTC_USDT function main() {
exchange.IO("simulate", true) // 切换为OKEX交易所的模拟盘
exchange.Buy(-1, 1) // 价格是-1,表示下的订单为市价单,数量为1表示下单量是1USDT
}
Поскольку на биржах обычно установлены ограничения по сумме ордера, ордера, размер которых меньше лимита, не будут отправлены (например, для успешной отправки ордера на спотовой бирже Binance требуется, чтобы сумма ордера превышала 5 USDT). Таким образом, размещение такого заказа приведет к ошибке:
错误 Buy(-1, 1): map[code:1 data:[map[clOrdId: ordId: sCode:51020 sMsg:Order amount should be greater than the min available amount. tag:]] msg:]

Так как функция порядка имеет толькоBuy,Sell. Однако фьючерсы (конечно, нет проблем со спотом, спот имеет только покупку и продажу) имеют направления, такие как открытие длинной позиции, закрытие длинной позиции, открытие короткой позиции и закрытие короткой позиции. Очевидно, что покупка/продажа не может представлять операции в стольких направлениях . В это время необходимо ввести настройку направления торговли фьючерсами. Эта функцияexchange.SetDirection()。
На ФМЗ
exchange.SetDirection("buy")(сначала задайте направление) иexchange.BuyПри совместном использовании это означает, что размещенный ордер представляет собой ордер на открытие длинной позиции.
И так далее:
exchange.SetDirection("sell")иexchange.SellПри совместном использовании это означает, что размещенный ордер представляет собой ордер на открытие короткой позиции.
exchange.SetDirection("closebuy")иexchange.SellПри совместном использовании это означает, что размещенный ордер представляет собой ордер на закрытие длинной позиции.
exchange.SetDirection("closesell")иexchange.BuyПри совместном использовании это означает, что размещенный приказ представляет собой приказ на закрытие короткой позиции.
Обычно новичкиexchange.SetDirection("sell")иexchange.BuyИспользуется в сочетании с другими или в других неправильных комбинациях. Затем он сообщил об ошибке (тестирование на исторических данных может и не сообщить об ошибке, но это, очевидно, логическая ошибка, и люди с обсессивно-компульсивным расстройством не могут ее терпеть…).
Еще одна распространенная ошибка новичков
function main() {
exchange.SetContractType("quarter") // 设置当前合约为季度合约
exchange.SetDirection("sell")
var id = exchange.Sell(-1, 1)
Log("看我市价单下单了,成交了,就有持仓了", exchange.GetPosition())
exchange.SetDirection("closebuy") // closebuy 和Sell 搭配使用,嗯没错~
exchange.Sell(-1, 1)
}

Увидев это, вы можете спросить: «Почему у меня есть позиция и я использую closebuy и sell вместе, но он выдает ошибку, и я не могу закрыть позицию?» Я бы ответил: «Я закрыл не в том направлении! Я закрыл длинную позицию».
Другая возможная ситуация для вышеуказанной ошибки: направление закрытия установлено правильно, функция ордера используется правильно, и позиция удерживается в этом направлении, но эта ошибка все равно выдается.
Причина в том, что ваша программа могла разместить несколько ордеров, но первоначальный ордер не был выполнен, а закрывающий ордер висел на рынке в ожидании выполнения. В это время программа продолжает закрывать позицию, и она выдаст сообщение ошибка превышения позиции закрытия.
print。
JavaScriptconsole.log。
Голангfmt.Println()。
С++coutДавайте поговорим об информации, отображаемой на платформе FMZ. На платформе количественной торговли Inventor есть два основных места, где отображается информация.
- Строка состояния
После запуска реального диска страница реального диска выглядит так, как показано на рисунке.

Часть отображения — это информация строки состояния. Строка состояния в основном используется для отображения некоторых изменяющихся в реальном времени данных (потому что изменения в реальном времени должны наблюдаться в реальном времени, и их нельзя каждый раз печатать в виде журналов, поэтому этот вид данных можно отобразить в строке состояния. Если каждый из них распечатать, то журнал будет содержать много повторяющихся и бессмысленных данных, что повлияет на запрос).
Отображение использования данных в строке состояния`LogStatus`Подробную информацию о функции см. в документации API FMZ.
- Столбец журнала
Также на реальной странице рынка, как показано на рисунке:

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

2. Журнал заказов, используемый в стратегии FMZ`exchange.Sell`/`exchange.Buy`Он будет автоматически записан в журнал вывода.

3. Журнал отмены заказов, используемый в стратегии FMZ`exchange.CancelOrder`, журнал отмены заказов будет автоматически выведен в журнал.

4. Журнал ошибок. При работе стратегии FMZ, если в интерфейсе сетевого запроса возникает ошибка вызова или выдается исключение (например, оператор типа throw), в журнал автоматически выводится журнал ошибок.

Функции API FMZ, которые могут генерировать выходные данные журнала, такие как Log(…), exchange.Buy(Price, Amount), exchange.CancelOrder(Id) и т. д., могут сопровождаться некоторыми дополнительными выходными параметрами после обязательных параметров, например: exchange.CancelOrder(orders[j].Id, orders[j]) Это отменяет заказы[j] При размещении данного заказа будет выведена информация о заказе.
function main() {
Log("数据1", "数据2", "数据3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...")
exchange.CancelOrder(id, "附带数据1", data2, "...")
LogProfit(100, "附带数据1", data2, "...")
}
JavaScriptЯзыковая стратегия будет отображаться при печати рассчитанных данных индикатора.null。На Strategy Square есть обучающий пример: https://www.fmz.com/strategy/125770 Протестировав этот пример стратегии, вы можете увидеть график, сгенерированный системой бэктестинга и 10-периодной скользящей средней:

Стратегия пользовательского рисования, нарисованная линия К и график скользящей средней:

В: Что делать, если мне нужна 10-часовая скользящая средняя? Ответ: Данные K-line могут использовать данные K-line за часовой период.
Проще говоря, K-line, которую мы видим, представляет собой массив после его оцифровки (если вы не понимаете концепцию массива, вы можете поискать на Baidu), в котором каждый элемент представляет собой столбец K-line, который организован по порядку. Первый элемент — самый дальний от текущего времени, а последний элемент массива — самый близкий к текущему времени. Обычно последний столбец данных K-line — это столбец текущего периода, который изменяется в реальном времени и не завершен (вы можете наблюдать за изменениями, войдя на страницу биржи и наблюдая за ее K-line). Рассчитанные показатели также соответствуют один к одному столбцам линии К. В приведенном выше примере вы можете видеть, что одно значение индикатора соответствует одному столбцу линии К. Обратите внимание, что последний столбец K-line изменяется в реальном времени, и рассчитанные показатели также будут меняться вместе с изменениями в столбце K-line.
На платформе количественной торговли Inventor вы можете использовать библиотеку TA (библиотека, реализованная платформой FMZ, интегрированная в кастодиан и может использоваться напрямую на разных языках) или библиотеку talib (talib — это хорошо зарекомендовавшая себя библиотека индикаторов, интегрирован с JS и C++, а Python нужно писать самостоятельно) Установить). Например, в приведенном выше примере скользящая средняя рассчитывается: Использование библиотеки TA:
function main() {
var records = exchange.GetRecords()
var ma = TA.MA(records, 10)
Log(ma) // 打印均线
}
Использование библиотеки талиба:
function main() {
var records = exchange.GetRecords()
var ma = talib.MA(records, 10)
Log(ma) // 打印均线
}
Рассчитанные данные индикатора ma представляют собой массив, каждый элемент которого соответствует массиву K-строк (записей), то естьma[ma.length -1]соответствоватьrecords[records.length - 1], и так далее.
То же самое относится и к другим сложным индикаторам, и вам необходимо обратить внимание на такие индикаторы, как MACD.
var macd = TA.MACD(records) // 这样只传入K线数据,不传入指标参数,指标参数采用的就是默认值,其它指标函数也是同理
В настоящее время переменная macd представляет собой двумерный массив (если вы не понимаете концепцию, вы можете поискать на Baidu). Проще говоря, двумерный массив — это массив, и каждый его элемент также является массивом . Вопрос: Почему данные индикатора MACD представляют собой двумерный массив? Ответ: Поскольку индикатор MACD состоит из двух линий (линии DIF и линии DEA) и набора баров объема (бар объема MACD, по сути, эти данные бара объема также можно рассматривать как линию). Таким образом, переменную macd можно разделить на:
var dif = macd[0]
var dea = macd[1]
var macdColumn = macd[2]
Также есть готовый пример обучения здесь, если вам интересно, изучите его: https://www.fmz.com/strategy/151972
