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

Инструкции по API FMZ

Автор:Нуль, Создано: 2020-04-20 10:19:00, Обновлено: 2023-04-12 14:44:56

в последних 10 журналов и очистить остальные Логрезест ((10)
}


```Python
def main():
    LogReset(10)
void main() {
    LogReset(10);
}

Логавакуум ((()

LogVacuum(), после вызоваLogReset()Функция очистки журнала, восстанавливает пространство для хранения, занятоеSQLiteФункция не возвращает значения. Причина в том, чтоSQLiteне восстанавливает занимаемое пространство при удалении данных, поэтому вам нужно выполнитьVACUUMПри вызове этой функции операция перемещения файла будет происходить с большой задержкой. Рекомендуется вызвать ее в соответствующий временной интервал.

API рыночных котировок

Основные функции рыночного интерфейса:

Имя функции Описание
GetTicker Получить данные о цитатах
GetRecords Получить данные K-линии
ПолучитьГлубину Получить данные книги заказов (данные о глубине заказов)
GetTrades Получите последние торговые записи на рынке

Следующие функции можно вызвать черезexchangeилиexchanges[0]объекты; например: функции, такие какexchange.GetTicker();илиexchanges[0].GetTicker();, возвращает рыночные котировки текущих торговых пар и контрактов по установке.

Важные советы для вызова функций API с доступом к сети:При вызове любой функции API, которая получает доступ к интерфейсу платформы (например,exchange.GetTicker(), exchange.Buy(Price, Amount), exchange.CancelOrder(Id), и т. д.), неудача доступа, вероятно, вызвана различными причинами. Поэтому мы должны сделать отказоустойчивую обработку для вызова этих функций.exchange.GetTicker()Функция для получения рыночных данных может, из-за проблем с сервером платформы и проблем с сетевой передачей и т.д., привести к тому, что значение возвратаexchange.GetTicker()функция -null. Затем, возвращение значениеexchange.GetTicker()должна быть обработана с помощью отказоустойчивой обработки.

Данные, возвращенныеexchange.GetTicker()функция в следующем коде присваиваетсяtickerпеременный, и мы должны иметь дело с допустимостью ошибок, прежде чем использоватьticker variable.

function main() {
    var ticker = exchange.GetTicker()
    if(!ticker){
        // Recall once, or use other processing logic
        ticker = exchange.GetTicker()
    }
}
def main():
    ticker = exchange.GetTicker()
    if not ticker:
        ticker = exchange.GetTicker()
void main() {
    auto ticker = exchange.GetTicker();
    if(!ticker.Valid) {
        ticker = exchange.GetTicker();
        Log("Test");
    }
}

Кроме того, для проверки эффективности стратегии по отказоустойчивости FMZ специально добавил уникальныйРежим отказоустойчивостиСистема backtest может случайным образом возвращать некоторые API-звонки, которые будут происходить при доступе к сети в соответствии с установленными параметрами, и возвращать значения возврата некоторых неудачных звонков. Вы можете быстро проверить надежность программы в боте. Переключитесь на страницу системы backtest на странице редактирования стратегии, нажмитеперевернутый треугольниквыпадающий элемент управления с правой стороны кнопки "Начать обратное тестирование", и кнопка "Возвратное тестирование допустимости неисправностей" появится.

Обмен.GetTicker ((()

exchange.GetTicker()получает текущие рыночные котировки текущих торговых пар и контрактов, причем прибыль:Tickerструктуры. В системе обратного тестированияTickerДанные, возвращенныеexchange.GetTicker()функция, гдеHighиLowявляются моделируемыми значениями, взятыми из текущего времени продажа 1 и покупка 1 в боте.Tick interface.

function main(){
    var ticker = exchange.GetTicker()
    /*
        The platform interface may not be accessible due to network problems (even if the device's docker program can open the platform website, the API may not be accessible)
        At this time, ticker is null, when accessing ticker. When it is "High", it will cause an error; so when testing, ensure that you can access the platform interface
    */
    Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume)
}
def main():
    ticker = exchange.GetTicker()
    Log("High:", ticker["High"], "Low:", ticker["Low"], "Sell:", ticker["Sell"], "Buy:", ticker["Buy"], "Last:", ticker["Last"], "Volume:", ticker["Volume"])
void main() {
    auto ticker = exchange.GetTicker();
    Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume);
}

В реальном боте (не backtest),Infoатрибут в возвращаемом значенииexchange.GetTicker()функция хранит исходные данные, возвращенные при вызове интерфейса.

Обмен.ПолучитьГлубину()

exchange.GetDepth()получает данные книги ордеров на обмен текущих торговых пар и контрактов.Depth structure.

Depthструктура содержит два массива структур, а именно:Asks[]иBids[], AsksиBidsсодержат следующие структурные переменные:

Тип данных Имя переменной Описание
Номер Цена цены
Номер Сумма сумма

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

function main(){
    var depth = exchange.GetDepth()
    /*
       The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
       At this time, depth is null. When accessing depth.Asks[1].Price, it will cause an error; so when testing, ensure that you can access the platform interface
    */
    var price = depth.Asks[1].Price
    Log("Sell 2 price is:", price)
}
def main():
    depth = exchange.GetDepth()
    price = depth["Asks"][1]["Price"]
    Log("Sell 2 price is:", price)
void main() {
    auto depth = exchange.GetDepth();
    auto price = depth.Asks[1].Price;
    Log("Sell 2 price is:", price);
}

Обмен.GetTrades ((()

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

// In the simulated backtest, the data is empty; to have a trading history, there must be a real bot running
function main(){
    var trades = exchange.GetTrades()
    /*
        The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
        At this time, "trades" is null. When accessing trades[0].Id, it will cause an error; so when testing, ensure that you can access the platform interface
    */
    Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type)
}
def main():
    trades = exchange.GetTrades()
    Log("id:", trades[0]["Id"], "time:", trades[0]["Time"], "Price:", trades[0]["Price"], "Amount:", trades[0]["Amount"], "type:", trades[0]["Type"])
void main() {
    auto trades = exchange.GetTrades();
    Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type);
}

Обмен.GetRecords ((()

exchange.GetRecords(Period)возвращает K-линейные данные. K-линейный период указывается при создании бота; если вы указываете параметры, когдаexchange.GetRecords()Если функция вызвана, полученные данные будут K-линейными данными, соответствующими параметру периода. Если нет указанного параметра, K-линейные данные возвращаются в соответствии с K-линейным периодом, установленным на параметрах бота, или K-линейным периодом, установленным на странице backtest.

ПараметрPeriod:

  • ПЕРИОД_М1: относится к 1 минуте
  • ПЕРИОД_М5: относится к 5 минутам
  • ПЕРИОД_М15: относится к 15 минутам
  • ПЕРИОД_М30: относится к 30 минутам
  • ПЕРИОД_H1: относится к 1 часу
  • ПЕРИОД_Д1: относится к 1 дню Значение параметраPeriodможет проходить только стандартные периоды, определенные выше, но также может проходить числа, в единице секунды.

Возвратное значениеexchange.GetRecords(Period)Функция: Возвратное значение представляет собой массивRecordВ случае, если вы хотите, чтобы использовать эти структуры, возвращенные K-линейные данные будут накапливаться с течением времени, верхний предел накопленных K-линейных баров влияет наexchange.SetMaxBarLenПо умолчанию верхний предел составляет 5000 K-линейных баров, когда он не установлен. Когда данные K-Line достигают предела накопления K-Line, они обновляются путем добавления K-Line-линии и удаления ранней K-Line-линии (например, очереди в / из).

Количество K-линейных балок, полученных приGetRecordsФункция изначально вызвана.

  • Первые 1000 K-линейных строк в момент начала периода обратного тестирования заранее принимаются в системе обратного тестирования в качестве начальных данных K-линии.
  • Конкретное количество K-линейных баров, которые должны быть приобретены во время реального бота, основано на максимальном количестве данных, которые могут быть приобретены K-линейным интерфейсом биржи.

Дляexchange.GetRecords(Period)Функция, бот и обратный тесткриптовалютаоба поддерживают пользовательские периоды, и параметрPeriodэто количество секунд. Например:

function main() {
    // Print K-line data with a K-line period of 120 seconds (2 minutes)
    Log(exchange.GetRecords(60 * 2))         
    // Print K-line data with a K-line period of 5 minutes
    Log(exchange.GetRecords(PERIOD_M5))      
}
def main():
    Log(exchange.GetRecords(60 * 2))
    Log(exchange.GetRecords(PERIOD_M5))
void main() {
    Log(exchange.GetRecords(60 * 2)[0]);
    Log(exchange.GetRecords(PERIOD_M5)[0]);
}

НастройкаPeriodпараметр 5 - запрос данных K-линии с периодом 5 секунд. ЕслиPeriodпараметр не равномерно делится на 60 (то есть представленный период - это период недоступных минут), нижний слой системы использует соответствующий интерфейсGetTradesполучать данные о торговых записях и синтезировать необходимые данные K-линии. ЕслиPeriodпараметр равномерно делится на 60, затем требуемые K-линейные данные синтезируются с использованием минимум 1-минутных K-линейных данных (используя более длительный период для синтеза требуемых K-линейных данных, если это возможно).

function main(){
    var records = exchange.GetRecords(PERIOD_H1)
    /*
        The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
        At this time, "records" is null. When accessing records[0].Time, it will cause an error; so when testing, ensure that you can access the platform interface
    */
    Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High)
    Log("The second k-line data is, Time:", records[1].Time ,"Close:", records[1].Close)
    Log("Current K-line (latest)", records[records.length-1], "Current K-line (latest)", records[records.length-2])
}
def main():
    records = exchange.GetRecords(PERIOD_H1)
    Log("The first k-line data is, Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"])
    Log("The second k-line data is, Time:", records[1]["Time"], "Close:", records[1]["Close"])
    Log("Current K-line (latest)", records[-1], "Current K-line (latest)", records[-2])
void main() {
    auto records = exchange.GetRecords(PERIOD_H1);
    Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High);
    Log("The second k-line data is, Time:", records[1].Time, "Close:", records[1].Close);
    Log("Current K-line (latest)", records[records.size() - 1], "Current K-line (latest)", records[records.size() - 2]);
}

exchange.GetRecords()Функция имеет два условия для получения данных K-линии:

  • В этом случае полученные данные являются данными, непосредственно возвращенными обменником.

  • Программа FMZ докер получает последние торговые записи биржи каждый раз, когда программа стратегии звонитexchange.GetRecords(), то есть, он называетexchange.GetTrades()Функция получения данных и синтеза данных K-линии.

На уровне симуляции необходимо установитьбазовый период K-линии(когда система обратного тестирования моделирует уровень обратного тестирования, соответствующие данные K-линии используются для генерации данных о тиках в соответствии с наборомбазовый период K-линии); следует отметить, что период K-линейных данных, полученных в стратегии, не может быть меньшебазовый период линии KПотому что в обратном тесте на уровне моделирования данные K-линии каждого периода синтезируются данными K-линии, соответствующими базовым периодам K-линии в системе обратного теста.

Внутри.cppязык, если вам нужно построить свои собственные данные K-линии, есть следующие примеры кода:

#include <sstream>
void main() { 
    Records r;
    r.Valid = true;
    for (auto i = 0; i < 10; i++) {
        Record ele;
        ele.Time = i * 100000;
        ele.High = i * 10000;
        ele.Low = i * 1000;
        ele.Close = i * 100;
        ele.Open = i * 10;
        ele.Volume = i * 1;
        r.push_back(ele);
    }
    // Output display: Records[10]
    Log(r);                      
    auto ma = TA.MA(r,10);       
    // Output display: [nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
    Log(ma);                     
}

Обмен.GetPeriod ((()

Вexchange.GetPeriod()Функция возвращает период K-линии, установленный на странице веб-сайта платформы FMZ при запуске стратегий вобратная проверкаибот. Возвращаемое значение - цельное число в единице секунды. Возвращаемое значение: числовой тип.

function main() {
    // For example, in the backtest and bot, set the K-line period on the website page of FMZ platform to 1 hour
    var period = exchange.GetPeriod()
    Log("K-line period:", period / (60 * 60), "hour")
}
def main():
    period = exchange.GetPeriod()
    Log("K-line period:", period / (60 * 60), "hour")
void main() {
    auto period = exchange.GetPeriod();
    Log("K-line period:", period / (60 * 60.0), "hour");
}

Обмен.SetMaxBarLen(Len)

Вexchange.SetMaxBarLen(Len)функция влияет на два аспекта во время выполнения стратегии криптовалюты:

  • Влияние на количество K-линейных строк (BAR), полученных впервые.
  • Влияние на верхнюю границу K-линейных строк (BAR).
function main() {
    exchange.SetMaxBarLen(50)
    var records = exchange.GetRecords()
    Log(records.length, records)
}
def main():
    exchange.SetMaxBarLen(50)
    r = exchange.GetRecords()
    Log(len(r), r)
void main() {
    exchange.SetMaxBarLen(50);
    auto r = exchange.GetRecords();
    Log(r.size(), r[0]);
}

Обмен.GetRawJSON ((()

exchange.GetRawJSON()возвращает сырой контент (строки), возвращенные последнимОтдыхзапрос, который можно использовать для анализа данных самостоятельно. Возвратное значение: тип строки, действителен только в среде торговли криптовалютой. Backtest не поддерживает функцию. Стратегии вcppЯзык не поддерживает эту функцию.

function main(){
    exchange.GetAccount(); 
    var obj = JSON.parse(exchange.GetRawJSON());
    Log(obj);
}
import json
def main():
    exchange.GetAccount()
    obj = json.loads(exchange.GetRawJSON())
    Log(obj)
void main() {
    auto obj = exchange.GetAccount();
    // C++ doe not support "GetRawJSON" function
    Log(obj);
}

Обмен.GetRate ((()

exchange.GetRate()возвращает обменные курсы валюты, используемой в данный момент на бирже, и валюты ценообразования, отображаемой в данный момент, а возвращаемое значение 1 указывает на то, что конвертация валютного курса отключена.

Примечание:

  • Еслиexchange.SetRate()не был вызван для установления обменного курса, значение обменного курса возвращаетсяexchange.GetRate()является 1 по умолчанию, то есть конверсия валютного курса, показанная в данный момент, не была обменена.
  • Еслиexchange.SetRate()используется для установления стоимости обменного курса, например:exchange.SetRate(7), тогда вся информация о ценах текущего обменного объекта, представляющего собой валюту, действующую на торговой платформе, такая как котировки, глубина, цены на заказы и т. д., будет умножена на ранее установленный курс 7 для конвертации.
  • Еслиexchangeсоответствует обмену с USD в качестве валюты ценообразования, после вызоваexchange.SetRate(7), все цены бота будут преобразованы в цены, близкие к CNY, умножением на 7.exchange.GetRate()Это 7.

Обмен.GetUSDCNY()

exchange.GetUSDCNY()возвращает последний обменный курс доллара США (источник данных предоставленyahooВозвращаемое значение: числовой тип.

exchange.SetData ((Ключ, Значение)

Вexchange.SetData(Key, Value)Функция используется для установки данных, загруженных в момент запуска стратегии, которые могут быть любыми экономическими показателями, отраслевыми данными, соответствующим индексом и т. Д. Она может быть использована для количественной оценки всей количественной информации для торговых стратегий и также поддерживает использование в системе бэкстеста.

Способ вызоваexchange.SetData(Key, Value)Функция:

  • Запишите данные прямо в стратегию Формат данных требуется какdataпеременная в следующем примере.

    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    function main() {
        var data = [
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
        exchange.SetData("test", data)
        while(true) {
            Log(exchange.GetData("test"))
            Sleep(1000)
        }
    }
    
    '''backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    '''  
    
    def main():
        data = [
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
        exchange.SetData("test", data)
        while True:
            Log(exchange.GetData("test"))
            Sleep(1000)
    
    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */  
    
    void main() {
        json data = R"([
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ])"_json;
        
        exchange.SetData("test", data);
        while(true) {
            Log(exchange.GetData("test"));
            Sleep(1000);
        }
    }
    

    При выполнении вышеуказанного кода испытания соответствующие данные будут получены в соответствующее время, как показано на рисунке:

    img

    Как мы можем видеть, соответствующее время временной отметки1579622400000это2020-01-22 00: 00: 00; когда программа стратегии запускается после этого времени, до следующего временного знака данных1579708800000, то есть до времени2020-01-23 00: 00: 00- Позвони.exchange.GetData(Source)Все, что мы получаем, это содержание[1579622400000, 123]По мере того как программа продолжает работать и время меняется, получайте данные по частям.

  • Запрос данных через внешние ссылки

    Запрошенный формат данных

    {
        "schema":["time","data"],
        "data":[
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
    }
    

    Где?schemaявляется форматом данных каждой записи в основном теле загруженных данных, формат фиксируется как["time", "data"], что соответствуетdataАтрибут формата данных один за другим.dataатрибут сохраняет основное тело данных, и каждый кусок данных состоит из меток времени на уровне миллисекунд и содержимого данных (содержимое данных может быть любыми закодированными данными JSON).

    Программа обслуживания для тестирования написана вGoязык:

    package main
    import (
        "fmt"
        "net/http"
        "encoding/json"
    )  
    
    func Handle (w http.ResponseWriter, r *http.Request) {
        defer func() {
            fmt.Println("req:", *r)
            ret := map[string]interface{}{
                "schema": []string{"time","data"},
                "data": []interface{}{
                    []interface{}{1579536000000, "abc"},
                    []interface{}{1579622400000, 123},
                    []interface{}{1579708800000, map[string]interface{}{"price":123}},
                    []interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}},
                },
            }
            b, _ := json.Marshal(ret)
            w.Write(b)
        }()
    }  
    
    func main () {
        fmt.Println("listen http://localhost:9090")
        http.HandleFunc("/data", Handle)
        http.ListenAndServe(":9090", nil)
    }
    

    После получения запроса программа отвечает на данные:

    {
        "schema":["time","data"],
        "data":[
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
    }
    

    Код стратегии испытания:

    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    function main() {
        while(true) {
            Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
            Sleep(1000)
        }
    }
    
    '''backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    '''  
    
    def main():
        while True:
            Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
            Sleep(1000)
    
    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */  
    
    void main() {
        while(true) {
            Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
            Sleep(1000);
        }
    }
    

exchange.GetData ((Источник)

Вexchange.GetData(Source)Функция используется для загрузки данныхexchange.SetData(Key, Value)Данные получаются одновременно во время обратного теста, а данные кэшируются в течение одной минуты во время фактической торговли.

  • Получение метода вызова данных, записанных непосредственно

    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    function main() {
        exchange.SetData("test", [[1579536000000, _D(1579536000000)], [1579622400000, _D(1579622400000)], [1579708800000, _D(1579708800000)]])
        while(true) {
            Log(exchange.GetData("test"))
            Sleep(1000 * 60 * 60 * 24)
        }
    }
    
    '''backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    '''  
    def main():
        exchange.SetData("test", [[1579536000000, _D(1579536000000/1000)], [1579622400000, _D(1579622400000/1000)], [1579708800000, _D(1579708800000/1000)]])
        while True:
            Log(exchange.GetData("test"))
            Sleep(1000 * 60 * 60 * 24)
    
    /*backtest
    start: 2020-01-21 00:00:00
    end: 2020-02-12 00:00:00
    period: 1d
    basePeriod: 1d
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */    
    void main() {
        json arr = R"([[1579536000000, ""], [1579622400000, ""], [1579708800000, ""]])"_json;
        arr[0][1] = _D(1579536000000);
        arr[1][1] = _D(1579622400000);
        arr[2][1] = _D(1579708800000);
        exchange.SetData("test", arr);
        while(true) {
            Log(exchange.GetData("test"));
            Sleep(1000 * 60 * 60 * 24);
        }
    }
    
  • Способ вызова данных из внешних ссылок

    function main() {
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
        Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
    }
    
    def main():
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
        Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
    
    void main() {
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
        Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"));
    }
    
  • Использовать фундаментальные данные платформы центра обработки данных Используйтеexchange.GetData(Source)Функция для полученияОсновные данные.

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

API торговли

Следующие функции можно вызвать черезexchangeилиexchanges[0]Например:exchange.Sell(100, 1);указывает, что следующий ордер - это ордер на продажу с ценой 100 и количеством 1 на бирже.

Обмен.Покупка ((Цена, Сумма)

exchange.Buy(Price, Amount)используется для размещения ордера на покупку и возвращения идентификатора ордера. Значение параметра:Priceэто цена заказа в виде номера, иAmountвозвращаемое значение: тип строки или цифровой тип (конкретный тип зависит от типа возвращения каждой биржевой платформы).

Номер возвращенного заказа может быть использован для запроса информации о заказе и отмены заказов.

function main() {
    var id = exchange.Buy(100, 1);
    Log("id:", id);
}
def main():
    id = exchange.Buy(100, 1)
    Log("id:", id)
void main() {
    auto id = exchange.Buy(100, 1);
    Log("id:", id);
}
  • Фьючерсные заказы

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

    // The following is the wrong call
    function main() {
        exchange.SetContractType("quarter")
      
        // Set short direction
        exchange.SetDirection("sell")     
        // Place a buy order, and you will get an error, so you can only sell short
        var id = exchange.Buy(50, 1)      
    
        // Set short direction
        exchange.SetDirection("buy")      
        // Place a sell order, and you will get an error, so you can only buy long
        var id2 = exchange.Sell(60, 1)    
      
        // Set close long position direction
        exchange.SetDirection("closebuy")    
        // Place a buy order, and you will get an error, so you can only sell short
        var id3 = exchange.Buy(-1, 1)        
      
        // Set close short position direction
        exchange.SetDirection("closesell")   
        // Place a sell order, and you will get an error, so you can only buy long
        var id4 = exchange.Sell(-1, 1)       
    }
    
    # The following is the wrong call
    def main():
        exchange.SetContractType("quarter")
        exchange.SetDirection("sell")
        id = exchange.Buy(50, 1)
        exchange.SetDirection("buy")
        id2 = exchange.Sell(60, 1)
        exchange.SetDirection("closebuy")
        id3 = exchange.Buy(-1, 1)
        exchange.SetDirection("closesell")
        id4 = exchange.Sell(-1, 1)
    
    // The following is the wrong call
    void main() {
        exchange.SetContractType("quarter");
        exchange.SetDirection("sell");
        auto id = exchange.Buy(50, 1);
        exchange.SetDirection("buy");
        auto id2 = exchange.Sell(60, 1);
        exchange.SetDirection("closebuy");
        auto id3 = exchange.Buy(-1, 1);
        exchange.SetDirection("closesell");
        auto id4 = exchange.Sell(-1, 1);
    }
    

    Сообщения об ошибке:

    direction is sell, invalid order type Buy
    direction is buy, invalid order type Sell
    direction is closebuy, invalid order type Buy
    direction is closesell, invalid order type Sell
    
  • Рыночный порядок

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

    // For example, trading pairs: ETH_BTC, bought in by market order
    function main() {
        // Buy a market order, and buy ETH coins equal to 0.1 BTC (quote currency) 
        exchange.Buy(-1, 0.1)    
    }
    
    def main():
        exchange.Buy(-1, 0.1)
    
    void main() {
        exchange.Buy(-1, 0.1);
    }
    

обмен.продажа ((Цена, сумма)

exchange.Sell(Price, Amount)размещает ордер на продажу и возвращает идентификатор ордера. Значение параметра:Priceэто цена заказа, числовой тип.Amountявляется суммой заказа, числовым типом. Возвратное значение: тип строки или числовой тип (конкретный тип зависит от типа возврата каждой биржи).

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

function main(){
    var id = exchange.Sell(100, 1)
    Log("id:", id)
}
def main():
    id = exchange.Sell(100, 1)
    Log("id:", id)
void main() {
    auto id = exchange.Sell(100, 1);
    Log("id:", id);
}
  • Фьючерсные заказы

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

  • Рыночные заказы

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

    // For example, trading pairs: ETH_BTC, sold out by market order 
    function main() {
        // Note: Sell by a market order, and sell 0.2 ETH coins 
        exchange.Sell(-1, 0.2)   
    }
    
    def main():
        exchange.Sell(-1, 0.2)
    
    void main() {
        exchange.Sell(-1, 0.2);
    }
    

Обмен.Отмена Заказа ((Id)

exchange.CancelOrder(orderId), целью этой функции является отмена заказа с ID. Значение параметра:Idявляется номером заказа, в виде строки или числового типа (конкретный тип зависит от типа возврата при размещении заказа на каждой платформе); значение возврата: тип bool.

возвращается результат операции;trueозначает, что запрос на отмену заказа был отправлен успешно;falseозначает, что запрос на отмену заказа не отправляется (значение возврата указывает только на то, успешно ли отправляется запрос или нет, поэтому лучше позвонитьexchange.GetOrders()чтобы проверить, отменяет ли платформа заказ).

function main(){
    var id = exchange.Sell(99999, 1)
    exchange.CancelOrder(id)
}
def main():
    id = exchange.Sell(99999, 1)
    exchange.CancelOrder(id)
void main() {
    auto id = exchange.Sell(99999, 1);
    exchange.CancelOrder(id);
}

Функция API FMZ, которая может генерировать функции вывода журнала, такие какLog(...), exchange.Buy(Price, Amount)иexchange.CancelOrder(Id). Вы можете следовать необходимым параметрам с некоторыми дополнительными параметрами вывода, такие какexchange.CancelOrder(orders[j].Id, orders[j])Таким образом, он отменяетorders[j]заказ, который сопровождается выводом этой информации заказа, а именноOrderСтруктураorders[j].

function main() {
    Log("data1", "data2", "data3", "...")
    var data2 = 200
    var id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
    exchange.CancelOrder(id, "Incidental data1", data2, "...")
    LogProfit(100, "Incidental data1", data2, "...")
}
def main():
    Log("data1", "data2", "data3", "...")
    data2 = 200
    id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
    exchange.CancelOrder(id, "Incidental data1", data2, "...")
    LogProfit(100, "Incidental data1", data2, "...")
void main() {
    Log("data1", "data2", "data3", "...");
    int data2 = 200;
    auto id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...");
    exchange.CancelOrder(id, "Incidental data1", data2, "...");
    LogProfit(100, "Incidental data1", data2, "...");
}

Обмен.GetOrder ((Id)

exchange.GetOrder(orderId)получает подробности заказа в соответствии с номером заказа.Idявляется порядковым номером, который необходимо получить, иIdявляется строкой или числовым типом (конкретный тип зависит от типа возврата каждой биржи).Orderструктуры. (Не поддерживается некоторыми биржами)

  • Orderструктура
  • AvgPriceуказывает среднюю реализованную цену (некоторые биржи не поддерживают это поле; установите его на 0, если они не поддерживают).
function main(){
    var id = exchange.Sell(1000, 1)
    // The parameter id is the order number, you need to fill in the number of the order you want to query
    var order = exchange.GetOrder(id)      
    Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
        order.DealAmount, "Status:", order.Status, "Type:", order.Type)
}
def main():
    id = exchange.Sell(1000, 1)
    order = exchange.GetOrder(id)
    Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:", 
        order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
void main() {
    auto id = exchange.Sell(1000, 1);
    auto order = exchange.GetOrder(id);
    Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", 
        order.DealAmount, "Status:", order.Status, "Type:", order.Type);
}

Обмен.GetOrders ((()

exchange.GetOrders()получает все незавершенные заказы.Orderмассив структуры. ДляOrderструктуру, пожалуйста, обратитесь кexchange.GetOrder()Описание функции.exchangeУ вас нет ожидаемых заказов, звоните.exchange.GetOrders()чтобы вернуть пустой массив, а именно:[].

function main(){
    exchange.Sell(1000, 1)
    exchange.Sell(1000, 1)
    var orders = exchange.GetOrders()
    Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
        "DealAmount:", orders[0].DealAmount, "type:", orders[0].Type)
    Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
        "DealAmount:", orders[1].DealAmount, "type:", orders[1].Type)
}
def main():
    exchange.Sell(1000, 1)
    exchange.Sell(1000, 1)
    orders = exchange.GetOrders()
    Log("Information for unfinished order 1, ID:", orders[0]["Id"], "Price:", orders[0]["Price"], "Amount:", orders[0]["Amount"], 
        "DealAmount:", orders[0]["DealAmount"], "type:", orders[0]["Type"])
    Log("Information for unfinished order 2, ID:", orders[1]["Id"], "Price:", orders[1]["Price"], "Amount:", orders[1]["Amount"],
        "DealAmount:", orders[1]["DealAmount"], "type:", orders[1]["Type"])
void main() {
    exchange.Sell(1000, 1);
    exchange.Sell(1000, 1);
    auto orders = exchange.GetOrders();
    Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount, 
        "DealAmount:", orders[0].DealAmount, "type:", orders[0].Type);
    Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
        "DealAmount:", orders[1].DealAmount, "type:", orders[1].Type);
}

Вexchange.GetOrders()Функция получает незавершенную информацию о порядке текущего набораторговые парыСледует отметить, что криптовалютные фьючерсы имеют различия не только между торговыми парами, но и контрактными кодами.

// Test OKX contract tradings, to know whether "GetOrders" gets all unfinished contract orders
function main(){
    // The next weekly buy order; the price of the order minus 50 guarantees no execution; pending orders
    exchange.SetContractType("this_week")
    exchange.SetDirection("buy")
    var ticker = exchange.GetTicker()
    Log(ticker)
    exchange.Buy(ticker.Last - 50, 1)

    // The next quarterly sell order; the price plus 50 guarantees that it will not be executed, and the pending order has been switched to a quarterly contract
    exchange.SetContractType("quarter")
    exchange.SetDirection("sell")
    ticker = exchange.GetTicker()
    Log(ticker)
    exchange.Sell(ticker.Last + 50, 1)

    // Get the unfinished orders
    Log("orders", exchange.GetOrders())
}
def main():
    exchange.SetContractType("this_week")
    exchange.SetDirection("buy")
    ticker = exchange.GetTicker()
    Log(ticker)
    exchange.Buy(ticker["Last"] - 50, 1)

    exchange.SetContractType("quarter")
    exchange.SetDirection("sell")
    ticker = exchange.GetTicker()
    Log(ticker)
    exchange.Sell(ticker["Last"] + 50, 1)

    Log("orders", exchange.GetOrders())
void main() {
    exchange.SetContractType("this_week");
    exchange.SetDirection("buy");
    auto ticker = exchange.GetTicker();
    Log(ticker);
    exchange.Buy(ticker.Last - 50, 1);

    exchange.SetContractType("quarter");
    exchange.SetDirection("sell");
    ticker = exchange.GetTicker();
    Log(ticker);
    exchange.Sell(ticker.Last + 50, 1);

    Log("orders", exchange.GetOrders());
}

Полученная информация о незавершенном заказе:

[{"Id":17116430886,"Amount":1,"Price":808.4,"DealAmount":0,"AvgPrice":0,"Status":0,"Type":1,"ContractType":"quarter"}]

Можно видеть, что в криптовалютной торговле, заказы, полученныеexchange.GetOrders()являются только незавершенными заказами текущего контракта.

Обмен.УстановкаПрецизия(...)

exchange.SetPrecision(PricePrecision, AmountPrecision)устанавливает десятичную точность цены и сумму порядка символа; после установки он автоматически сокращается.PricePrecisionимеет номерный тип, используемый для контроля количества запятой в данных о ценах;AmountPrecisionимеет тип числа, используется для управления запятой после суммы заказа.PricePrecisionиAmountPrecisionФункция не поддерживается, и числовая точность обратного теста будет обработана автоматически.

function main(){
    // Set the decimal precision of the price to 2 digits, and set the precision of the quantity of the symbol order to 3 digits
    exchange.SetPrecision(2, 3)
}    
def main():
    exchange.SetPrecision(2, 3)
void main() {
    exchange.SetPrecision(2, 3);
}

обмен.Установка ставки ((Ставка)

exchange.SetRate(Rate)устанавливает обменный курс валюты обращения на бирже.Rateявляетсяnumberвозвращается значение:number type.

function main(){
    Log(exchange.GetTicker())
    // Set the exchange rate conversion
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    // Set to 1, without conversion
    exchange.SetRate(1)
}
def main():
    Log(exchange.GetTicker())
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    exchange.SetRate(1)
void main() {
    Log(exchange.GetTicker());
    exchange.SetRate(7);
    Log(exchange.GetTicker());
    exchange.SetRate(1);
}

Примечание:

  • Если вы установили значение обменного курса, используяexchange.SetRate(Rate), например 7, то вся информация о ценах, включая текущую рыночную цену, глубину и цену заказа, обращаемой валюты, представленной текущимexchangeОбъекты, будут умножены на установленный курс 7 для конвертации.

  • Например,exchangeявляется обменным курсом, выраженным в долларах США.exchange.SetRate(7)В случае, если данный показатель будет называться, все цены реальной торговли будут умножены на 7 и преобразованы в цены, близкие к CNY.

exchange.IO(…)

exchange.IO("api", httpMethod, resource, params, raw), вызвать другие функциональные интерфейсы обмена. Значение параметра:httpMehodявляется типа строки; он заполняет тип запроса, например:POSTилиGET. resourceимеет тип строки, она заполняет путь запроса.paramsявляется типа строки, он заполняет параметры запроса.rawявляется исходным параметром строки JSON и может быть пропущен.exchange.IO("api", httpMethod, resource, params, raw)При появлении ошибки и отказе в вызове, он возвращает нулевое значение (функция с сетевым запросом, напримерGetTicker()иGetAccount(), и т.д., возвращают нулевые значения при отказе в вызовах).exchange.IO("api", ...) function.

Для примера порядка партии OKX используйте параметрrawдля передачи параметров заказа:

function main() {
    var arrOrders = [
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
    ]
    
    // Call exchange.IO to directly access the platform batch ordering interface
    var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders))
    Log(ret)
}
import json
def main():
    arrOrders = [
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, 
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
    ]
    ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", json.dumps(arrOrders))
    Log(ret)
void main() {
    json arrOrders = R"([
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
        {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
    ])"_json;
    auto ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders.dump());
    Log(ret);
}

Чтобы использовать эту функцию, вы должны пойти на обмен, чтобы понятьAPIИнтерфейс обмена для расширения функций, которые FMZ не добавил (вы не должны беспокоиться о процессе шифрования параметров, подписи и проверки, когда вы отправляетеPOSTFMZ полностью обработал в нижнем слое, поэтому вам нужно только заполнить соответствующие параметры).

Примечание: Если ключевое значение вparamsпараметр (т.е. Http запрос параметр) является строкой, он должен быть завернут с единственными котировками (символ') с обеих сторон значения параметра. Например:bitfinex exchange.

var amount = 1
var price = 10
var basecurrency = "ltc"
function main () {
    // Notice that amount.toString() and price.toString() both have a ' character on the left and right
    var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit"
    var id = exchange.IO("api", "POST", "/v1/order/new", message)
}
amount = 1
price = 10
basecurrency = "ltc"
def main():
    message = "symbol=" + basecurrency + "&amount='" + str(amount) + "'&price='" + str(price) + "'&side=buy" + "&type=limit"
    id = exchange.IO("api", "POST", "/v1/order/new", message)
void main() {
    auto amount = 1.0;
    auto price = 10.0;
    auto basecurrency = "ltc";
    string message = format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price);
    auto id = exchange.IO("api", "POST", "/v1/order/new", message);
}

Пример доступаOKXинтерфейс:

function main(){
    var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
    Log(ret)
}
def main():
    ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
    Log(ret)
void main() {
    auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT");
    Log(ret);
}

Данные, возвращенные во время испытаний:

{"code":"0","data":[],"msg":""}

Другие настройкиexchange.IOФункция:

  • Переключение торговых пар текущей биржи

    exchange.IO("currency", "ETH_BTC")

    function main() {
        // For example, set the current trading pair of the exchange object on the bot to BTC_USDT, and print the current trading pair market
        Log(exchange.GetTicker())
        // Switch trading pair to LTC_BTC      
        exchange.IO("currency", "LTC_BTC")
        Log(exchange.GetTicker())
    }
    
    def main():
        Log(exchange.GetTicker())
        exchange.IO("currency", "LTC_BTC")
        Log(exchange.GetTicker())
    
    void main() {
        Log(exchange.GetTicker());
        exchange.IO("currency", "LTC_BTC");
        Log(exchange.GetTicker());
    }
    

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

    Примечание:

      1. Система backtest теперь поддерживает переключение торговых пар (только спотовые обменные объекты криптовалюты). Во время backtest следует отметить, что можно переключать только торговые пары одной и той же котировочной валюты.ETH_BTC, который может быть переключен только наLTC_BTC, нетLTC_USDT.
      1. Еслиwebsocketрежим протокола переключается на Huobi спот обмена объектов, вы не можете использоватьexchange.IO("currency", "XXX_YYY")чтобы обменять валюты.
      1. Для криптовалютных фьючерсных бирж, если торговые пары переключаются, вам нужно снова настроить контракт, чтобы определить, с каким контрактом вы хотите торговать.
      1. Вы также можете использовать новыйexchange.SetCurrency(Symbol)функцию переключения торговых пар и использованияexchange.IO("currency","XXX_YYY")метод для поддержания совместимости.
  • exchange.IOфункция переключает адрес базы API обмена (контракт RESET; некоторые обмены не поддерживают это). Теперь использованиеexchange.SetBase(Base)Функция поддерживается для переключения базового адреса API обмена и использованияexchange.IO("base","https://xxx.xxx.xxx")метод для поддержания совместимости.

    Например: когда объект обмена инкапсулирован, базовый адрес по умолчаниюhttps://api.huobipro.com, перейти на:https://api.huobi.pro, используйте следующий код.

    function main () {
        // exchanges[0] is the first exchange object added when the bot is added 
        exchanges[0].IO("base", "https://api.huobi.pro")        
    }
    
    def main():
        exchanges[0].IO("base", "https://api.huobi.pro")
    
    void main() {
        exchanges[0].IO("base", "https://api.huobi.pro");
    }
    

    Переключите базовый адрес обратно на:https://api.huobipro.com.

    function main () {
        exchanges[0].IO("base", "https://api.huobipro.com")
    }
    
    def main():
        exchanges[0].IO("base", "https://api.huobipro.com")
    

Больше