Возвращает номер текущей версии системы.
Номер текущей версии системы, например:3.6
- Да.
строка
Версия ((()
function main() {
Log("version:", Version())
}
def main():
Log("version:", Version())
void main() {
Log("version:", Version());
}
Номер версии системы - это номер версии программы Docker
Функция сна, вызывающая паузу программы на некоторое время.
Сон ((миллисекунда)
Вmillisecond
Параметр используется для установки продолжительности сна и количества миллисекунд.
миллисекунды
Истинно
Номер
function main() {
Sleep(1000 * 10) // Wait for 10 seconds
Log("Waited for 10 seconds")
}
def main():
Sleep(1000 * 10)
Log("Waited for 10 seconds")
void main() {
Sleep(1000 * 10);
Log("Waited for 10 seconds");
}
Например, при выполненииSleep(1000)
Он поддерживает операции с временем сна менее 1 миллисекунды, например, настройкаSleep(0.1)
. Он поддерживает минимальный параметр0.000001
, т.е. наносекундная спячка, где 1 наносекунда равна1e-6
миллисекунд.
При написании стратегий вPython
язык,Sleep(millisecond)
Не рекомендуется использовать эту функцию для выборов с интервалом, операций с временем ожидания.time.sleep(second)
ФункцияPython
Это...time
Это потому, что использованиеtime.sleep(second)
функция в стратегии заставляет программу стратегии ждать определенный период времени фактически при обратном тестировании (не пропуская временные ряды системы обратного тестирования), поэтому она заставляет стратегию проводить обратное тестирование очень медленно.
Определить, является ли среда управления стратегией системой обратного тестирования.
Стратегия возвращает истинное значение, например:true
при запуске в среде системы обратного тестирования стратегия возвращает ложное значение, например:false
при работе в среде реального трейдинга.
Буль
Виртуальная?
function main() {
if (IsVirtual()) {
Log("The current backtest system environment.")
} else {
Log("The current live trading environment.")
}
}
def main():
if IsVirtual():
Log("The current backtest system environment.")
else:
Log("The current live trading environment.")
void main() {
if (IsVirtual()) {
Log("The current backtest system environment.");
} else {
Log("The current live trading environment.");
}
}
Определить, является ли текущая рабочая среда системой обратного тестирования, которая используется для совместимости с разницей между обратным тестированием и живой торговлей.
Отправь мне письмо.
Успешная доставка электронной почты возвращает истинное значение, например,true
, и неудачная доставка возвращает ложное значение, например,false
- Да.
Буль
Почта ((smtpСервер, smtpИмя пользователя, smtpПароль, mailTo, заголовок, тело)
Используется для определенияSMTP
адрес обслуживания отправителя электронной почты.
smtpServer
неправда
строка
Используется для указания адреса электронной почты отправителя.
smtpUsername (имя пользователя)
неправда
строка
ВSMTP
пароль для почтового ящика отправителя электронной почты.
smtpPassword (пароль)
неправда
строка
Используется для указания адреса электронной почты получателя.
mailTo
неправда
строка
Заголовок электронной почты.
Заголовок
неправда
строка
Корпус почты.
тело
неправда
строка
function main(){
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
}
def main():
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
void main() {
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
ВsmtpPassword
параметр устанавливает пароль дляSMTP
Сервис, а не пароль почтового ящика.
При установкеsmtpServer
параметр, если вам нужно изменить порт, вы можете добавить номер порта прямо в параметреsmtpServer
Например: QQ mailsmtp.qq.com:587
, который доступен для тестирования.
Если сообщается ошибка:unencryped connection
, вам нужно изменитьsmtpServer
В соответствии сMail
Формат параметра:ssl://xxx.com:xxx
, например,ssl
МетодSMTP
для почты QQ:ssl://smtp.qq.com:465
илиsmtp://xxx.com:xxx
- Да.
Это не работает в системе обратного тестирования.
{@fun/Global/Mail_Go Mail_Go} Я не знаю.
Асинхронная версияMail
function.
ВMail_Go
Функция возвращает одновременный объект сразу, и вы можете использоватьwait
Успешная доставка почты возвращает истинное значение, например,true
, и неудачная доставка возвращает ложное значение, например,false
- Да.
объект
Mail_Go ((smtpServer, smtpUsername, smtpPassword, mailTo, название, корпус)
Он используется для определенияSMTP
сервисный адрес отправителя электронной почты.
smtpServer
Истинно
строка
Он используется для указания адреса электронной почты отправителя электронной почты.
smtpUsername (имя пользователя)
Истинно
строка
ВSMTP
пароль для почтового ящика отправителя электронной почты.
smtpPassword (пароль)
Истинно
строка
Используется для указания адреса электронной почты получателя электронной почты.
mailTo
Истинно
строка
Заголовок электронной почты.
Заголовок
Истинно
строка
Корпус почты.
тело
Истинно
строка
function main() {
var r1 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var r2 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var ret1 = r1.wait()
var ret2 = r2.wait()
Log("ret1:", ret1)
Log("ret2:", ret2)
}
# Not supported.
// Not supported.
Это не работает в системе обратного тестирования.
{@fun/Global/Mail Mail} Я не знаю.
Профиль ошибок.
УстановитеErrorFilter (фильтр)
Регулярная строка выражений. фильтры неправда строка
function main() {
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
}
def main():
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
void main() {
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
}
Фильтрация распространенных ошибок.
function main() {
// A random query for a non-existent order with an id of 123, allowing the interface to report an error deliberately
var order = exchange.GetOrder("123")
Log(order)
// Filter http502 errors, GetOrder interface errors, after setting the error filter, the second call to GetOrder will no longer report errors
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
}
def main():
order = exchange.GetOrder("123")
Log(order)
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
void main() {
TId orderId;
Order order = exchange.GetOrder(orderId);
Log(order);
SetErrorFilter("502:|GetOrder");
order = exchange.GetOrder(orderId);
Log(order);
}
Отфильтровать сообщение об ошибке интерфейса.
Регистрации ошибок, совпадающие с этим регулярным выражением, не будут загружены в систему журналов. Вы можете вызвать его несколько раз (без ограничения на количество раз), чтобы установить несколько условий фильтра. Регулярные выражения, установленные несколько раз, будут накапливаться и вступать в силу одновременно. Вы можете установить пустую строку для сброса регулярного выражения, используемого для фильтрации журналов ошибок:SetErrorFilter("")
Фильтрованные журналы больше не записываются в файл базы данных, соответствующий идентификатору торговли в каталоге Docker, чтобы предотвратить частое сообщение об ошибках от раздутия файла базы данных.
Получите идентификатор торгового процесса.
Возвращение идентификатора торгового процесса. строка
GetPid ((()
function main(){
var id = GetPid()
Log(id)
}
def main():
id = GetPid()
Log(id)
void main() {
auto id = GetPid();
Log(id);
}
Получил последнее сообщение об ошибке.
Последнее сообщение об ошибке. строка
ПолучитьLastError()
function main(){
// Because the order number 123 does not exist, so there will be an error.
exchange.GetOrder("123")
var error = GetLastError()
Log(error)
}
def main():
exchange.GetOrder("123")
error = GetLastError()
Log(error)
void main() {
// Order ID type: TId, so you can't pass in a string, we place an order that doesn't meet the exchange specification to trigger
exchange.GetOrder(exchange.Buy(1, 1));
auto error = GetLastError();
Log(error);
}
Это не работает в системе обратного тестирования.
Получает команду стратегического взаимодействия.
Формат возвращенной команды:ControlName:Data
. ControlName
это название контрольного элемента, иData
Если интерактивный элемент управления не имеет входных ящиков, выпадающих ящиков и других компонентов (например, кнопка управления без входных ящиков), то возвращенный формат командыControlName
, который возвращает только название элемента управления.
строка
Получить команду ((()
function main(){
while(true) {
var cmd = GetCommand()
if (cmd) {
Log(cmd)
}
Sleep(1000)
}
}
def main():
while True:
cmd = GetCommand()
if cmd:
Log(cmd)
Sleep(1000)
void main() {
while(true) {
auto cmd = GetCommand();
if(cmd != "") {
Log(cmd);
}
Sleep(1000);
}
}
Выявляет команду взаимодействия и используетLog
Функция вывода команды взаимодействия при ее обнаружении.
function main() {
while (true) {
LogStatus(_D())
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
var arr = cmd.split(":")
if (arr[0] == "buy") {
Log("Buy, the control without number")
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1])
} else {
Log("Other controls trigger:", arr)
}
}
Sleep(1000)
}
}
def main():
while True:
LogStatus(_D())
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
arr = cmd.split(":")
if arr[0] == "buy":
Log("Buy, the control without number")
elif arr[0] == "sell":
Log("Sell, the control with the number of:", arr[1])
else:
Log("Other controls trigger:", arr)
Sleep(1000)
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void split(const string& s,vector<string>& sv,const char flag = ' ') {
sv.clear();
istringstream iss(s);
string temp;
while (getline(iss, temp, flag)) {
sv.push_back(temp);
}
return;
}
void main() {
while(true) {
LogStatus(_D());
auto cmd = GetCommand();
if (cmd != "") {
vector<string> arr;
split(cmd, arr, ':');
if(arr[0] == "buy") {
Log("Buy, the control without number");
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1]);
} else {
Log("Other controls trigger:", arr);
}
}
Sleep(1000);
}
}
Например, стратегия интерактивного управления добавляет контроль без поля ввода, интерактивный контроль называется:buy
, информация о описании контроля:buy
Продолжайте добавлением элемента управления с окном ввода. Интерактивный элемент управления называется:sell
и сообщение о описании контроля:sell
Код взаимодействия разработан в стратегии для ответа на различные элементы управления взаимодействием:
Это не работает в системе обратного тестирования.
Получить значение мета написано при генерации кода регистрации стратегии.
Meta
данные.
строка
GetMeta ((()
function main() {
// The maximum asset value of the denominated currency allowed by the strategy.
var maxBaseCurrency = null
// Get the metadata when creating the registration code.
var level = GetMeta()
// Detecting the conditions corresponding to Meta.
if (level == "level1") {
// -1 for unrestricted
maxBaseCurrency = -1
} else if (level == "level2") {
maxBaseCurrency = 10
} else if (level == "level3") {
maxBaseCurrency = 1
} else {
maxBaseCurrency = 0.5
}
while(1) {
Sleep(1000)
var ticker = exchange.GetTicker()
// Detect asset values
var acc = exchange.GetAccount()
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop executing strategy trading logic
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
}
}
def main():
maxBaseCurrency = null
level = GetMeta()
if level == "level1":
maxBaseCurrency = -1
elif level == "level2":
maxBaseCurrency = 10
elif level == "level3":
maxBaseCurrency = 1
else:
maxBaseCurrency = 0.5
while True:
Sleep(1000)
ticker = exchange.GetTicker()
acc = exchange.GetAccount()
if maxBaseCurrency != -1 and maxBaseCurrency < acc["Stocks"] + acc["FrozenStocks"]:
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
# Other trading logic
# Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
void main() {
auto maxBaseCurrency = 0.0;
auto level = GetMeta();
if (level == "level1") {
maxBaseCurrency = -1;
} else if (level == "level2") {
maxBaseCurrency = 10;
} else if (level == "level3") {
maxBaseCurrency = 1;
} else {
maxBaseCurrency = 0.5;
}
while(1) {
Sleep(1000);
auto ticker = exchange.GetTicker();
auto acc = exchange.GetAccount();
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop execution strategy trading logic.
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!");
continue;
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker);
}
}
Пример сценария применения: использованиеMeta
ограничить объем активов, которыми управляет стратегия.
Сценарий применения: необходимо сделать капитальные лимиты для разных стратегических арендаторов.Meta
значение, установленное при генерации регистрационного кода, не может превышать 190 символов, аGetMeta()
Если нет метаданных (Meta
) устанавливается при генерировании кода регистрации стратегии,GetMeta()
Функция возвращает null. Она не работает в системе обратного тестирования.
Для примитивныхSocket
Доступ, поддержкаtcp
, udp
, tls
, unix
Поддержка 4 популярных протоколов связи:mqtt
, nats
, amqp
, kafka
Поддержка подключения к базам данных:sqlite3
, mysql
, postgres
, clickhouse
.
ВDial()
Обычный вызов возвращает объект соединения, который имеет три метода:read
, write
иclose
.read
Для считывания данных используетсяwrite
С помощью этого метода передаются данные иclose
метод используется для закрытия соединения.
Вread
метод поддерживает следующие параметры:
ws.read()
.ws.read(2000)
указывает время задержки в две секунды (2000 миллисекунд).-1
означает, что функция возвращает сообщения немедленно, независимо от наличия или отсутствия сообщений, например:ws.read(-1)
- Да.
Передача параметра-2
означает, что функция возвращает сразу с сообщением или без него, но возвращается только последнее сообщение, а буферизированное сообщение отбрасывается.ws.read(-2)
.read()
описание буфера функции:
Входящие данные, отправляемые протоколом WebSocket, могут вызывать накопление данных, если временной интервал между стратегиейread()
Эти данные хранятся в буфере, который имеет структуру данных очереди с максимальным числом 2000.
Сценарий | Нет параметра | Параметр: -1 | Параметр: -2 | Параметр: 2000, в миллисекундах |
---|---|---|---|---|
Данные уже в буфере | Немедленно верните старые данные | Немедленно верните старые данные | Немедленно верните последние данные | Немедленно верните старые данные |
Нет данных в буфере | Возвращение при блокировке данных | Немедленно верните нуль | Немедленно верните нуль | Подождите 2000 мс, верните null, если нет данных, верните null, если есть данные |
Соединение WebSocket отключено или повторно подключено базовым | read() функция возвращает пустую строку, т.е.: |
объект
Выбрать адрес Назови (адрес, время выхода)
Адрес запроса. Адрес неправда строка секунды таймаута, Тайм-аут ложное Номер
function main(){
// Dial supports tcp://,udp://,tls://,unix://protocol, you can add a parameter to specify the number of seconds for the timeout
var client = Dial("tls://www.baidu.com:443")
if (client) {
// write can be followed by a numeric parameter to specify the timeout, write returns the number of bytes successfully sent
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while (true) {
// read can be followed by a numeric parameter specifying the timeout in milliseconds. Returning null indicates an error or timeout or that the socket has been closed
var buf = client.read()
if (!buf) {
break
}
Log(buf)
}
client.close()
}
}
def main():
client = Dial("tls://www.baidu.com:443")
if client:
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while True:
buf = client.read()
if not buf:
break
Log(buf)
client.close()
void main() {
auto client = Dial("tls://www.baidu.com:443");
if(client.Valid) {
client.write("GET / HTTP/1.1\nConnection: Closed\n\n");
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
Log(buf);
}
client.close();
}
}
Пример вызова функции Dial:
function main() {
LogStatus("Connecting...")
// Accessing WebSocket interface of Binance
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
// read returns only the data retrieved after the read call
var buf = client.read()
if (!buf) {
break
}
var table = {
type: 'table',
title: 'Ticker Chart',
cols: ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
rows: []
}
var obj = JSON.parse(buf)
_.each(obj, function(ticker) {
table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
})
LogStatus('`' + JSON.stringify(table) + '`')
}
client.close()
}
import json
def main():
LogStatus("Connecting...")
client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if not client:
Log("Connection failed, program exited")
return
while True:
buf = client.read()
if not buf:
break
table = {
"type" : "table",
"title" : "Ticker Chart",
"cols" : ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
"rows" : []
}
obj = json.loads(buf)
for i in range(len(obj)):
table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))])
LogStatus('`' + json.dumps(table) + '`')
client.close()
void main() {
LogStatus("Connecting...");
auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
if(!client.Valid) {
Log("Connection failed, program exited");
return;
}
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
json table = R"({
"type" : "table",
"title" : "Ticker Chart",
"cols" : ["Currency", "Highest", "Lowest", "Buy 1", "Sell 1", "Last traded price", "Volume", "Update time"],
"rows" : []
})"_json;
json obj = json::parse(buf);
for(auto& ele : obj.items()) {
table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"],
ele.value()["q"], _D(ele.value()["E"])});
}
LogStatus("`" + table.dump() + "`");
}
client.close();
}
Для доступа к интерфейсу WebSocket Binance:
var ws = null
function main(){
var param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
// When calling Dial function, specify reconnect=true to set reconnection mode and payload to be the message sent when reconnecting. When the WebSocket connection is disconnected, it will reconnect and send messages automatically.
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
var pingCyc = 1000 * 20
var lastPingTime = new Date().getTime()
while(true){
var nowTime = new Date().getTime()
var ret = ws.read()
Log("ret:", ret)
if(nowTime - lastPingTime > pingCyc){
var retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send : ping", "#FF0000")
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("exit")
}
import json
import time
ws = None
def main():
global ws
param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
pingCyc = 1000 * 20
lastPingTime = time.time() * 1000
while True:
nowTime = time.time() * 1000
ret = ws.read()
Log("ret:", ret)
if nowTime - lastPingTime > pingCyc:
retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send: ping", "#FF0000")
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("exit")
auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true");
void main() {
json param = R"({
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
})"_json;
objWS.write(param.dump());
if(objWS.Valid) {
uint64_t pingCyc = 1000 * 20;
uint64_t lastPingTime = Unix() * 1000;
while(true) {
uint64_t nowTime = Unix() * 1000;
auto ret = objWS.read();
Log("ret:", ret);
if(nowTime - lastPingTime > pingCyc) {
auto retPing = objWS.write("ping");
lastPingTime = nowTime;
Log("Send: ping", "#FF0000");
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
objWS.close();
Log("exit");
}
Доступ к интерфейсу OKX
var ws = null
function main(){
var param = {"sub": "market.btcusdt.detail", "id": "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
while(1){
var ret = ws.read()
Log("ret:", ret)
// Respond to heartbeat packet operations
try {
var jsonRet = JSON.parse(ret)
if(typeof(jsonRet.ping) == "number") {
var strPong = JSON.stringify({"pong" : jsonRet.ping})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
}
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("Execute the ws.close() function")
}
import json
ws = None
def main():
global ws
param = {"sub" : "market.btcusdt.detail", "id" : "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
while True:
ret = ws.read()
Log("ret:", ret)
# Respond to heartbeat packet operations
try:
jsonRet = json.loads(ret)
if "ping" in jsonRet and type(jsonRet["ping"]) == int:
strPong = json.dumps({"pong" : jsonRet["ping"]})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
except Exception as e:
Log("e:", e)
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("Execute the ws.close() function")
using namespace std;
void main() {
json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json;
auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump());
if(ws.Valid) {
while(true) {
auto ret = ws.read();
Log("ret:", ret);
// Respond to heartbeat packet operations
try
{
auto jsonRet = json::parse(ret);
if(jsonRet["ping"].is_number()) {
json pong = R"({"pong" : 0})"_json;
pong["pong"] = jsonRet["ping"];
auto strPong = pong.dump();
ws.write(strPong);
Log("Respond to ping, send pong:", strPong, "#FF0000");
}
} catch(exception &e)
{
Log("e:", e.what());
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
// ws.close();
Log("Execute the ws.close() function");
}
Доступ к интерфейсу Huobi's WebSocket:
function getLogin(pAccessKey, pSecretKey, pPassphrase) {
// Signature function for login
var ts = (new Date().getTime() / 1000).toString()
var login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey) // exchange.HMAC has been deprecated and is temporarily supported. Please use the latest exchange.Encode function instead.
}]
}
return login
}
var client_private = null
function main() {
// Because the read function uses a timeout setting, filtering the timeout reports errors that would otherwise be output with redundant errors
SetErrorFilter("timeout")
// Position channel subscription information
var posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
var accessKey = "xxx"
var secretKey = "xxx"
var passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000) // When logging in, you cannot subscribe to private channels immediately, you need to wait for server response
client_private.write(JSON.stringify(posSubscribe))
if (client_private) {
var lastPingTS = new Date().getTime()
while (true) {
var buf = client_private.read(-1)
if (buf) {
Log(buf)
}
// Detect disconnection, reconnect
if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
Log("Disconnection detected, close connection, reconnect")
client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(JSON.stringify(posSubscribe))
}
// Send heartbeat packets
var nowPingTS = new Date().getTime()
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping")
lastPingTS = nowPingTS
}
}
}
}
function onexit() {
var ret = client_private.close()
Log("Close the connection!", ret)
}
import json
import time
def getLogin(pAccessKey, pSecretKey, pPassphrase):
ts = str(time.time())
login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
}]
}
return login
client_private = None
def main():
global client_private
SetErrorFilter("timeout")
posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
accessKey = "xxx"
secretKey = "xxx"
passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
if client_private:
lastPingTS = time.time() * 1000
while True:
buf = client_private.read(-1)
if buf:
Log(buf)
if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0:
Log("Disconnection detected, close connection, reconnect")
ret = client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
nowPingTS = time.time() * 1000
if nowPingTS - lastPingTS > 10 * 1000:
client_private.write("ping")
lastPingTS = nowPingTS
def onexit():
ret = client_private.close()
Log("Close the connection!", ret)
auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) {
auto ts = std::to_string(Unix());
json login = R"({
"op": "login",
"args": [{
"apiKey": "",
"passphrase": "",
"timestamp": "",
"sign": ""
}]
})"_json;
login["args"][0]["apiKey"] = pAccessKey;
login["args"][0]["passphrase"] = pPassphrase;
login["args"][0]["timestamp"] = ts;
login["args"][0]["sign"] = exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey);
return login;
}
void main() {
SetErrorFilter("timeout");
json posSubscribe = R"({
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
})"_json;
auto accessKey = "xxx";
auto secretKey = "xxx";
auto passphrase = "xxx";
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
if (client_private.Valid) {
uint64_t lastPingTS = Unix() * 1000;
while (true) {
auto buf = client_private.read(-1);
if (buf != "") {
Log(buf);
}
if (buf == "") {
if (client_private.write(posSubscribe.dump()) == 0) {
Log("Disconnection detected, close connection, reconnect");
client_private.close();
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
}
}
uint64_t nowPingTS = Unix() * 1000;
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping");
lastPingTS = nowPingTS;
}
}
}
}
void onexit() {
client_private.close();
Log("exit");
}
Для доступа к интерфейсу аутентификации WebSocket OKX
var client = null
function main() {
// client = Dial("sqlite3://:memory:") // Using an in-memory database
client = Dial("sqlite3://test1.db") // Open/connect to the database file in the docker's directory
// record handle
var sqlite3Handle = client.fd()
Log("sqlite3Handle:", sqlite3Handle)
// Querying tables in the database
var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'")
Log(ret)
}
function onexit() {
Log("Execute client.close()")
client.close()
}
// Not supported
// Not supported
Объект соединения, возвращаемый функцией Dial при подключении к базе данных, имеет две уникальные для него функции метода:
exec(sqlString)
: Используется для выполнения SQL заявлений таким же образом, какDBExec()
function.fd()
:fd()
функция возвращает ручку (например, переменная ручка является рукой), которая будет использоваться другими потоками для повторного подключения (даже если объект, созданный Dial, уже был закрыт при исполненииclose()
с функцией закрытия соединения) путем прохождения ручки вDial()
функция, например,Dial(handle)
Подключение для повторного использования.
Ниже приведен пример функции Dial, соединяющейsqlite3
database.Подробная информацияaddress
параметр, разделенный|
символ после обычного адреса:wss://ws.okx.com:8443/ws/v5/public
Если есть.|
символы в строке параметров, затем||
Часть после этого - некоторые параметры параметров функции, и каждый параметр связан с&
Например,ss5
параметры прокси и сжатия могут быть установлены вместе следующим образом:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
Функции, поддерживаемые параметром адреса функции Dial | Описание параметров |
---|---|
Параметры, связанные с сжатием данных протокола WebSocket: compress=value parameter | compress - это метод сжатия, параметры сжатия: gzip_raw, gzip и т. д. Если метод gzip не является стандартным gzip, вы можете использовать расширенный метод: gzip_raw |
Параметры, относящиеся к сжатию данных протокола WebSocket: mode=value parameter | режим - это режим сжатия, параметр режима может быть двойным, отправка, recv. dual - это двустороннее сжатие, отправка сжатых данных, прием сжатых данных. отправка - это отправка сжатых данных. recv - это прием сжатых данных, локальная декомпрессия. |
Протокол WebSocket устанавливает базовые параметры, связанные с автоматическим воссоединением: reconnect=значение параметра | reconnect означает установить reconnect, reconnect=true означает включить reconnect. По умолчанию reconnect отсутствует, если этот параметр не установлен. |
Протокол WebSocket устанавливает базовые параметры, связанные с автоматическим воссоединением: interval=value parameter | интервал - это интервал повторных попыток, в миллисекундах, интервал=10000 - это интервал повторных попыток 10 секунд, по умолчанию 1 секунда, когда он не установлен, то есть интервал=1000. |
Протокол WebSocket устанавливает базовые параметры, связанные с автоматическим воссоединением: полезная нагрузка=значение параметра | полезная нагрузка - это сообщение подписки, которое необходимо отправить при повторном подключении WebSocket, например: полезная нагрузка=okokok. |
Параметры, относящиеся к носкам5 прокси: proxy=значение параметра | Прокси - это настройка прокси ss5, формат значения параметра: socks5://name:pwd@192.168.0.1:1080, имя - это имя пользователя сервера ss5, pwd - это пароль входа на сервер ss5, 1080 - это порт службы ss5. |
ВDial()
Функция поддерживается только для торговли в реальном времени.
При подключении к базе данных с помощью функции Dial строка подключения записывается со ссылкой на проект драйвера языка go для каждой базы данных.
Базы данных поддерживаются | Движущие проекты | Соединительная строка | Примечания |
---|---|---|---|
Склайт3 | github.com/mattn/go-sqlite3 | sqlite3://файл:test.db?cache=shared&mode=memory | Вsqlite3:// Префикс указывает, что используется база данных sqlite3, пример вызова:Dial("sqlite3://test1.db") |
mysql | github.com/go-sql-driver/mysql | mysql://username:yourpassword@tcp(localhost:3306)/yourdatabase?charset=utf8mb4 | – |
послерост | github.com/lib/pq | postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword host=localhost port=5432 | – |
Кликхаус | github.com/ClickHouse/clickhouse-go | clickhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase | – |
Пожалуйста, обратите внимание, что когдаpayload
содержание, установленное вaddress
параметр содержит символы=
или других специальных символов, это может повлиять на анализaddress
параметрDial
функция, например следующий пример.
Пример вызова частного интерфейса websocket backPack Exchange:
var client = null
function main() {
// Base64-encoded public key of the key pair, i.e. the access key configured on FMZ
var base64ApiKey = "xxx"
var ts = String(new Date().getTime())
var data = "instruction=subscribe×tamp=" + ts + "&window=5000"
// Since signEd25519 returns a base64 encoding, it contains the character "="
var signature = signEd25519(data)
// The payload may contain the character "=" after being encoded by JSON
payload = {
"method": "SUBSCRIBE",
"params": ["account.orderUpdate"],
"signature": [base64ApiKey, signature, ts, "5000"]
}
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
var buf = client.read()
Log(buf)
}
}
function onexit() {
client.close()
}
function signEd25519(data) {
return exchange.Encode("ed25519.seed", "raw", "base64", data, "base64", "{{secretkey}}")
}
Следующий вызов в коде работает нормально:
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
Если вы напишете это прямо вpayload
, он будет работать неправильно, например:
client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))
В настоящее время только JavaScript поддерживает использованиеmqtt
, nats
, amqp
, иkafka
Код стратегии языка JavaScript используется в качестве примера, чтобы показать использование четырех протоколов:mqtt
, nats
, amqp
, иkafka
:
// We need to configure and deploy proxy servers for each protocol first.
// For the sake of demonstration, the subscription (read operation) and publishing (write operation) of the topic test_topic are all performed in the current strategy.
var arrConn = []
var arrName = []
function main() {
LogReset(1)
conn_nats = Dial("nats://admin@127.0.0.1:4222?topic=test_topic")
conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
conn_amqp = Dial("amqp://q:admin@127.0.0.1:5672/?queue=test_Queue")
conn_kafka = Dial("kafka://localhost:9092/test_topic")
arrConn = [conn_nats, conn_amqp, conn_mqtt, conn_kafka]
arrName = ["nats", "amqp", "mqtt", "kafka"]
while (true) {
for (var i in arrConn) {
var conn = arrConn[i]
var name = arrName[i]
// Write data
conn.write(name + ", time: " + _D() + ", test msg.")
// Read data
var readMsg = conn.read(1000)
Log(name + " readMsg: ", readMsg, "#FF0000")
}
Sleep(1000)
}
}
function onexit() {
for (var i in arrConn) {
arrConn[i].close()
Log("close", arrName[i], "connect")
}
}
Подробная документация:Исследование FMZ: Практика протокола связи между стратегиями торговли в режиме реального времени
Отправьте запрос на http.
Возвращает данные ответа запроса.JSON
string, он может быть проанализированJSON.parse()
Функция вJavaScript
языковой стратегии,json::parse()
Функция вC++
Если в структуре опций значение отладки установлено на true, возвращаемое значение является объектом (JSON); если значение отладки установлено на false, возвращаемое значение является строкой.
строка, объект
HttpQuery ((url) HttpQuery ((url, параметры)
URL-адрес запроса HTTP. URL-адрес Истинно строка Например, настройки, связанные с запросом HTTP, могут быть структурированы следующим образом:
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
profile: "chrome_103",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
Отпечатки пальцев.
Поддерживаемые настройки включают следующие параметры:
chrome_:"chrome_103"
, "chrome_104"
, "chrome_105"
, "chrome_106"
, "chrome_107"
, "chrome_108"
, "chrome_109"
, "chrome_110"
, "chrome_111"
, "chrome_112"
, "chrome_117"
...
Сафари:"safari_15_6_1"
, "safari_16_0"
, "safari_ipad_15_6"
, "safari_ios_15_5"
, "safari_ios_15_6"
, "safari_ios_16_0"
...
Firefox_:"firefox_102"
, "firefox_104"
, "firefox_105"
, "firefox_106"
, "firefox_108"
, "firefox_110"
, "firefox_117"
...
опера_:"opera_89"
, "opera_90"
, "opera_91"
...
Заландо:"zalando_android_mobile"
, "zalando_ios_mobile"
...
Ники."nike_ios_mobile"
, "nike_android_mobile"
...
Облакостроитель:"cloudscraper"
...
Мммм."mms_ios"
...
mesh_:"mesh_ios"
, "mesh_ios_1"
, "mesh_ios_2"
, "mesh_android"
, "mesh_android_1"
, "mesh_android_2"
...
Подтверждение:"confirmed_ios"
, "confirmed_android"
...
Хорошо."okhttp4_android_7"
, "okhttp4_android_8"
, "okhttp4_android_9"
, "okhttp4_android_10"
, "okhttp4_android_11"
, "okhttp4_android_12"
, "okhttp4_android_13"
,true
,HttpQuery
Призыв функции возвращает полное сообщение ответа.false
, только данные вBody
сообщения ответа возвращается.profile
поле может быть оставлено в стороне.варианты ложное объект
function main(){
// An example of GET access without parameters
var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
Log(info)
// An example of GET access with parameters
var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"))
Log(ticker)
}
import json
import urllib.request
def main():
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8'))
Log(info)
ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8'))
Log(ticker)
void main() {
auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time"));
Log(info);
auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"));
Log(ticker);
}
Пример доступа к интерфейсу API публичного тикера OKX.
function main() {
// Setting proxy and sending an http request for this time, no username, no password, this http request will be sent through the proxy
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
// Setting proxy and sending an http request for this time, enter the user name and password, only the current call to HttpQuery takes effect, and then call HttpQuery again ("http://www.baidu.com") so that the proxy will not be used.
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
}
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
void main() {
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
}
Функция HttpQuery использует настройки прокси.
ВHttpQuery()
Функция поддерживает толькоJavaScript
, C++
язык,Python
язык может использоватьurllib
Библиотека для отправки запросов Http напрямую.HttpQuery()
используется в основном для доступа к интерфейсам биржи, которые не требуют подписи, например, общедоступным интерфейсам, таким как информация о тикерах.HttpQuery()
может использоваться в системе обратного тестирования для отправки запросов (толькоGET
Для получения данных, используемые в рамках реактестирования, используется 20 посещений различныхURLs
, иHttpQuery()
Когда те же самыеURL
Второй раз,HttpQuery()
Функция возвращает кэшированные данные, и больше не возникает фактических сетевых запросов.
{@fun/Global/HttpQuery_Go]
Отправляет запрос HTTP, асинхронную версиюHttpQuery
function.
ВHttpQuery_Go()
Функция немедленно возвращает одновременный объект, который может быть использован для получения результата запроса HTTP с использованиемwait
МетодJSON.parse()
Функция может быть использована для анализаJSON.parse()
Функция вJavaScript
языковой стратегии.
объект
HttpQuery_Go ((url) HttpQuery_Go ((url, параметры)
URL-адрес запроса HTTP. URL-адрес Истинно строка Например, настройки, связанные с запросом HTTP, могут быть структурированы следующим образом:
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
// profile: "",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
fingerprints.true
, этоHttpQuery_Go
Призыв функции возвращает полное сообщение ответа.false
, только данные вBody
сообщения ответа возвращается.profile
поле может быть оставлено в стороне.варианты ложное объект
function main() {
// Create the first asynchronous thread
var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
// Create the second asynchronous thread
var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
// Get the return value of the first asynchronous thread call
var tickers1 = r1.wait()
// Get the return value of the second asynchronous thread call
var tickers2 = r2.wait()
// Print results
Log("tickers1:", tickers1)
Log("tickers2:", tickers2)
}
# Not supported
// Not supported
Асинхронный доступ к общественному интерфейсу биржи для агрегированных данных тикеров.
ВHttpQuery_Go()
Функция поддерживает толькоJavaScript
,Python
язык может быть использован сurllib
Библиотека для отправки запросов Http напрямую.HttpQuery_Go()
используется в основном для доступа к интерфейсам, которые не требуют подписи на бирже, таким как общедоступные интерфейсы, такие как информация о тикерах.HttpQuery_Go
Функция не поддерживается системой обратного тестирования.
{@fun/Global/HttpQuery HttpQuery} (См. также:
Эта функция кодирует данные в соответствии с введенными параметрами.
ВEncode
функция возвращает данные после кодирования и шифрования.
строка
Зашифровка ((algo, inputFormat, outputFormat, data) Зашифровка ((algo, inputFormat, outputFormat, data, keyФормат, ключ)
Параметрalgo
- алгоритм, используемый при расчете кодирования.raw
(не используется алгоритм), "знак", algo
также поддерживает: algo
также поддерживает: алгоритм algo
может быть написано как ed25519.seed
расчеты.
что-то
неправда
строка
Используется для определения формата данныхdata
параметр.inputFormat
параметр может быть установлен как один из следующих:raw
, hex
, base64
, string
. hex
base64
кодируется, и outputFormat
параметр может быть установлен как один из следующих:raw
, hex
, base64
, string
. hex
base64
кодируется, и data
это данные, которые должны быть обработаны.
данные
неправда
строка
Используется для определения формата данныхkey
параметр.key
параметр может быть установлен как один из следующих:raw
, hex
, base64
, string
. hex
base64
кодируется, и key
секретный ключ, используемый дляHMAC
Параметрkey
требуется, когда параметрalgo
Установлено наsign
илиsignTx
.key
параметр не используется дляHMAC
шифрование, когдаalgo
параметр установлен на
function main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")) // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", null, "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")) // 313233
Log(Encode("raw", "raw", "base64", "123")) // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
def main():
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) # 6578616d706c65
Log(Encode("raw", "raw", "hex", "example", "", "")) # 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) # 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123", "", "")) # 313233
Log(Encode("raw", "raw", "base64", "123", "", "")) # MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
void main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")); // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")); // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")); // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")); // 313233
Log(Encode("raw", "raw", "base64", "123")); // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
Пример вызова функции Encode.
function main(){
var ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello") // e4bda0e5a5bd
Log(ret1)
var ret2 = Encode("text.decoder.utf8", "hex", "string", ret1)
Log(ret2)
var ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello") // c4e3bac3
Log(ret3)
var ret4 = Encode("text.decoder.gbk", "hex", "string", ret3)
Log(ret4)
}
def main():
ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello", "", "") # e4bda0e5a5bd
Log(ret1)
ret2 = Encode("text.decoder.utf8", "hex", "string", ret1, "", "")
Log(ret2)
ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello", "", "") # c4e3bac3
Log(ret3)
ret4 = Encode("text.decoder.gbk", "hex", "string", ret3, "", "")
Log(ret4)
void main(){
auto ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello"); // e4bda0e5a5bd
Log(ret1);
auto ret2 = Encode("text.decoder.utf8", "hex", "string", ret1);
Log(ret2);
auto ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello"); // c4e3bac3
Log(ret3);
auto ret4 = Encode("text.decoder.gbk", "hex", "string", ret3);
Log(ret4);
}
Параметрalgo
также поддерживает:
ВEncode()
Функция поддерживается только для живой торговли.key
иkeyFormat
параметры не переданы, тоkey
шифрование не используется.
Получите наносекундную временную отметку текущего момента.
ВUnixNano()
Функция возвращает наносекундный временной штемпель.
Номер
UnixNano ((()
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
Если вам нужно получить миллисекундные временные отметки, вы можете использовать следующий код:
{@fun/Global/Unix Unix}
Получите временную отметку текущего момента на втором уровне.
Возвращает временную отметку второго уровня. Номер
Unix ((()
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
{@fun/Global/UnixNano UnixNano} Я не знаю.
Получить информацию о устройстве, где расположен докер.
Информация о системе. строка
GetOS ((()
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
Например, призыв кGetOS()
функция для докера, работающего наMac OSоперационная система может вернуть:darwin/amd64
Потому что компьютеры Apple имеют несколько аппаратных архитектур.darwin
это названиеMac OS system.
Вычисляет хеш MD5 параметраdata
.
Хэш-значение MD5. строка
MD5 (данные)
Данные, требующие вычисления MD5. данные неправда строка
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
ЗвонитьMD5("hello world")
функция, возвращаемое значение:5eb63bbbe01eeed093cb22bb8f5acdc3
.
{@fun/Global/EncodeEncode} - Я не знаю.
Функции интерфейса базы данных.
Объект, содержащий результат выполнениякв. мзаявление, например:
{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}
объект
DBExec ((sql)
кв. мстрока заявлений. кв. м неправда строка
function main() {
var strSql = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
var ret = DBExec(strSql)
Log(ret)
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
}
def main():
arr = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
ret = DBExec(strSql)
Log(ret)
# Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
void main() {
string strSql = ":CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
auto ret = DBExec(strSql);
Log(ret);
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"));
}
Поддержка базы данных в памяти дляDBExec
параметры функции, если:кв. мЗаявление начинается с:
Он подходит для операций с базами данных, которые не требуют постоянного сохранения, например:
function main() {
var strSql = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
var ret = DBExec(strSql)
Log(ret)
}
def main():
arr = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
ret = DBExec(strSql)
Log(ret)
void main() {
string strSql = "CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
auto ret = DBExec(strSql);
Log(ret);
}
Создайте стол.
function main() {
var strSql = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
Log(DBExec(strSql))
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
}
def main():
arr = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
Log(DBExec(strSql))
# Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
# Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
# Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
void main() {
string strSql = "CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
Log(DBExec(strSql));
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"));
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}
Добавить, удалить, проверить и изменить записи в таблице.
ФункцияDBExec()
может работать с базой данных торговли в режиме реального времени (SQLite database) путем передачи параметров.SQLiteСистема зарезервировала таблицы в базе данных торгов:kvdb
, cfg
, log
, profit
, chart
, не используйте эти столы.СделкиНе рекомендуется выполнять такие операции, которые могут вызвать конфликты в системе.DBExec()
Функция поддерживается только для торговли в режиме реального времени.
{@fun/Global/_G _G}
Создайте UUID.
32-разрядный UUID. строка
UUID (()
function main() {
var uuid1 = UUID()
var uuid2 = UUID()
Log(uuid1, uuid2)
}
def main():
uuid1 = UUID()
uuid2 = UUID()
Log(uuid1, uuid2)
void main() {
auto uuid1 = UUID();
auto uuid2 = UUID();
Log(uuid1, uuid2);
}
ВUUID()
Функция поддерживает только прямую торговлю.
Слушайте события, он возвращается, когда есть какие-либоWebSocket
читаемые данные или одновременные задачи, такие как:exchange.Go()
, HttpQuery_Go()
, и т. д. завершены.
Если возвращенный объект не является нулевым,Event
содержится в содержании возврата - тип запуска события. Например, следующая структура значения возврата:
{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}
объект
EventLoop ((() СобытиеLoop ((Timeout)
Параметрtimeout
это время выхода, в миллисекундах.timeout
ждет, пока событие произойдет, прежде чем вернется, если оно установлено на 0, если оно больше 0, оно устанавливает событие, чтобы ждать задержки, и возвращает самое последнее событие сразу, если оно меньше 0.
Тайм-аут
ложное
Номер
function main() {
var routine_getTicker = exchange.Go("GetTicker")
var routine_getDepth = exchange.Go("GetDepth")
var routine_getTrades = exchange.Go("GetTrades")
// Sleep(2000), if the Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events, because after waiting for 2 seconds, the concurrent function has received the data, and the subsequent EventLoop listening mechanism started, it misses these events.
// These events will not be missed unless EventLoop(-1) is called at the beginning of the first line of code to first initialize the EventLoop's listening mechanism.
// Log("GetDepth:", routine_getDepth.wait()) If the wait function is called in advance to retrieve the result of a concurrent call to the GetDepth function, the event that the GetDepth function receives the result of the request will not be returned in the EventLoop function.
var ts1 = new Date().getTime()
var ret1 = EventLoop(0)
var ts2 = new Date().getTime()
var ret2 = EventLoop(0)
var ts3 = new Date().getTime()
var ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
}
import time
def main():
routine_getTicker = exchange.Go("GetTicker")
routine_getDepth = exchange.Go("GetDepth")
routine_getTrades = exchange.Go("GetTrades")
ts1 = time.time()
ret1 = EventLoop(0)
ts2 = time.time()
ret2 = EventLoop(0)
ts3 = time.time()
ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
void main() {
auto routine_getTicker = exchange.Go("GetTicker");
auto routine_getDepth = exchange.Go("GetDepth");
auto routine_getTrades = exchange.Go("GetTrades");
auto ts1 = Unix() * 1000;
auto ret1 = EventLoop(0);
auto ts2 = Unix() * 1000;
auto ret2 = EventLoop(0);
auto ts3 = Unix() * 1000;
auto ret3 = EventLoop(0);
Log("The first concurrent task completed was:", _D(ts1), ret1);
Log("The second concurrent task completed was:", _D(ts2), ret2);
Log("The third concurrent task completed was:", _D(ts3), ret3);
Ticker ticker;
Depth depth;
Trades trades;
routine_getTicker.wait(ticker);
routine_getDepth.wait(depth);
routine_getTrades.wait(trades);
Log("GetTicker:", ticker);
Log("GetDepth:", depth);
Log("GetTrades:", trades);
}
Первый звонокEventLoop()
Функция в коде инициирует механизм для этого прослушиваемого события, и если первыйEventLoop()
призыв начинается после обратного вызова события, он пропустит предыдущие события.EventLoop()
если функция не вызвана вовремя, чтобы вывести их во время выполнения программы, последующие вызовы событий за пределами кэша 500 будут потеряны.EventLoop()
функция не влияет на кэш очереди базовой системы WebSocket или кэши одновременных функций, таких какexchange.Go()
Для этих кэшей все еще необходимо использовать соответствующие методы для извлечения данных.EventLoop()
Функция для данных, которые были получены доEventLoop()
Основная цельEventLoop()
В этом случае, если вы хотите, чтобы ваша система получила новые сетевые данные, вы должны установить, что эта система получает новые сетевые данные.EventLoop()
функция возвращает событие, просто проходит через все источники данных.exchange.Go()
Попробуйте получить данные.EventLoop()
Функция поддерживает только прямую торговлю.
Слушать события в главной нитке при вызове из главной функцииmain()
В стратегиях, написанных вJavaScript
язык,threading.Thread()
функция создает нить, которая также может быть вызвана в функции выполнения thread
{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
В__Serve
Функция используется для создания службы HTTP, службы TCP и службы Websocket (на основе протокола HTTP).
Возвращает строку, которая записывает IP-адрес и порт созданной службы.127.0.0.1:8088
, [::]:8089
.
строка
__Serve ((serveURI, обработчик) __Serve ((serveURI, обработчик,...args)
ВserveURI
параметр используется для настройки протокола, IP-адреса, порта и других настроек связи службы, таких какhttp://0.0.0.0:8088?gzip=true
, то есть,http://:8088?gzip=true
.
serveURI
настройка параметров, таких какtcp://127.0.0.1:6666?tls=true
; вы можете добавить сертификаты и частные ключи, такие какtls=true&cert_pem=xxxx&cert_key_pem=xxxx
.serveURI
настройки параметров, например:http://127.0.0.1:6666?gzip=true
; вы можете установить настройки сжатия:gzip=true
- Да.
ВserveURI
параметр используется для Https, напримерhttps://127.0.0.1:6666?tls=true&gzip=true
; вы можете добавитьcert_pem
иcert_key_pem
параметры для загрузки сертификата.служитьURI
неправда
строка
Вhandler
Параметр используется для передачи в функции обработки маршрутизации (протокол HTTP), функции обработки сообщений (протокол TCP) и функции обработки потока (Websocket).
Функция обратного вызова, передаваемая параметромhandler
может определять несколько параметров, первым параметром является объект ctx (контекстный объект).
управляющий
неправда
Функция
Фактический параметр функции обратного вызова передается как параметрhandler
. Может быть несколько параметровarg
, например:
__Serve("http://:8088", function(ctx, a, b, c) {
Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)
Параметры1
, 2
, 3
прошел в, когда звонить__Serve()
функция соответствует параметрамa
, b
, c
прошел в функции обратного вызова.
арг ложное string, number, bool, object, array, function, null value и другие типы, поддерживаемые системой
function main() {
let httpServer = __Serve("http://:8088?gzip=true", function (ctx) {
Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
let path = ctx.path()
if (path == "/") {
ctx.write(JSON.stringify({
path: ctx.path(),
method: ctx.method(),
headers: ctx.headers(),
cookie: ctx.header("Cookie"),
remote: ctx.remoteAddr(),
query: ctx.rawQuery()
}))
} else if (path == "/tickers") {
let ret = exchange.GetTickers()
if (!ret) {
ctx.setStatus(500)
ctx.write(GetLastError())
} else {
ctx.write(JSON.stringify(ret))
}
} else if (path == "/wss") {
if (ctx.upgrade("websocket")) { // upgrade to websocket
while (true) {
let r = ctx.read(10)
if (r == "") {
break
} else if (r) {
if (r == "ticker") {
ctx.write(JSON.stringify(exchange.GetTicker()))
} else {
ctx.write("not support")
}
}
}
Log("websocket closed", ctx.remoteAddr())
}
} else {
ctx.setStatus(404)
}
})
let echoServer = __Serve("tcp://:8089", function (ctx) {
Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
while (true) {
let d = ctx.read()
if (!d) {
break
}
ctx.write(d)
}
Log("connect closed")
})
Log("http serve on", httpServer, "tcp serve on", echoServer)
for (var i = 0; i < 5; i++) {
if (i == 2) {
// test Http
var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
Log("retHttp:", retHttp)
} else if (i == 3) {
// test TCP
var tcpConn = Dial("tcp://127.0.0.1:8089")
tcpConn.write("Hello TCP Server")
var retTCP = tcpConn.read()
Log("retTCP:", retTCP)
} else if (i == 4) {
// test Websocket
var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
wsConn.write("ticker")
var retWS = wsConn.read(1000)
Log("retWS:", retWS)
// no depth
wsConn.write("depth")
retWS = wsConn.read(1000)
Log("retWS:", retWS)
}
Sleep(1000)
}
}
# Unsupported
// Unsupported
Websocket
Вы можете установить ветвь маршрутизации в пути и разработать код реализации дляWebsocket
Вы можете ознакомиться с образцом кода в этом разделе.Функция обратного вызова, передаваемая параметромhandler
получаетctx
параметр.ctx
параметр - это контекстный объект, используемый для получения и записи данных, с следующими методами:
HTTP/1.1
, tcp
.http://127.0.0.1:8088?num=123
, и функция обработки обратного вызова, передаваемая параметромhandler
доходы"123"
когдаctx.query("num")
называется.User-Agent
в заголовках текущей просьбы:ctx.header("User-Agent")
.GET
, POST
, и т.д.ctx
Контекстный объект к протоколу Websocket; возвращение булевого значения (правда), если переключение удалось, и булевого значения (ложь), если оно не удалось.read
Метод не поддерживается в обычном протоколе HTTP. Вы можете указать параметр задержкиtimeout_ms
в миллисекундах.JSON.stringify()
чтобы закодировать объект JSON в строку и затем написать его.WebSocket
протокол, вы можете использовать этот метод для передачи зашифрованной строки клиенту.{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
Функция выполняет глобальную функцию словаря, которая может быть сохранена.
Постоянно сохраненные данные ключевых значений вk-v
пары ключевых значений.
строка, число, bool, объект, массив, нулевое значение
_G() _G(k) _G(k, v)
Параметрk
является именем ключа в сохраненной паре ключей и значений и не чувствителен к большим и малым буквам.
k
ложное
строка, нулевое значение
Параметрv
является ключевым значением в сохраненной паре ключей-значений, которая может быть любыми данными, которые могут бытьJSON
сериализирована.
v
ложное
строка, число, bool, объект, массив, нулевое значение
function main(){
// Set a global variable num with a value of 1
_G("num", 1)
// Change a global variable num to the value of the string ok
_G("num", "ok")
// Delete the global variable num
_G("num", null)
// Returns the value of the global variable num
Log(_G("num"))
// Delete all global variables
_G(null)
// Return to live trading ID
var robotId = _G()
}
def main():
_G("num", 1)
_G("num", "ok")
_G("num", None)
Log(_G("num"))
_G(None)
robotId = _G()
void main() {
_G("num", 1);
_G("num", "ok");
_G("num", NULL);
Log(_G("num"));
_G(NULL);
// Not support auto robotId = _G();
}
Отдельная база данных для каждой торговли в режиме реального времени, данные, сохраненные_G()
В случае завершения обратного тестирования, данные, сохраненные в системе обратного тестирования_G()
При использовании_G()
Функция сохранения сохраненных данных должна использоваться разумно в соответствии с памятью и жестким диском аппаратного устройства и не должна злоупотребляться.
При звонке_G()
в режиме реального времени и никаких параметров не передается,_G()
функция возвращаетId
При звонке на_G()
функция, параметрv
передается как NULL, чтобы указать на удалениеk-v
При вызове_G()
функция, только параметрk
проходит в строке, и_G()
функция возвращает значение ключа, соответствующее сохраненному параметруk
Когда звонишь_G()
функция, только параметрk
передается в нулевом значении, что указывает на то, что все записиk-v
пара ключевых значений удаляется.k-v
пары ключей-значений были сохранены постоянно,_G()
функция вызвана снова, передавая имя ключа, который был сохранен постоянно в качестве параметраk
. Передача нового значения ключа в качестве параметраv
Обновлю это.k-v
пара ключевых значений.
{@fun/Global/DBExec DBExec}
Преобразует миллисекундные временные отметки илиDate
Объекты для временных строк.
Временная цепь. строка
_D ((() _D (отметка времени) _D ((часовой штамп, fmt)
Миллисекундная временная марка илиDate
Объект.
Временная печать
ложное
Номер, предмет
Форматировать строку,JavaScript
формат языка по умолчанию:yyyy-MM-dd hh:mm:ss
; Python
формат языка по умолчанию:%Y-%m-%d %H:%M:%S
; C++
формат языка по умолчанию:%Y-%m-%d %H:%M:%S
- Да.
ФМТ
ложное
строка
function main(){
var time = _D()
Log(time)
}
def main():
strTime = _D()
Log(strTime)
void main() {
auto strTime = _D();
Log(strTime);
}
Получить и распечатать текущую временную строку:
function main() {
Log(_D(1574993606000))
}
def main():
# Running this code on a server in Beijing time: 2019-11-29 10:13:26 , a docker on another server in another region results in: 2019-11-29 02:13:26
Log(_D(1574993606))
void main() {
Log(_D(1574993606000));
}
Время - 1574993606000, с использованием кода конверсии:
function main() {
Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss")) // 2019--11--29 10--13--26
}
def main():
# 1574993606 is timestamped in seconds.
Log(_D(1574993606, "%Y--%m--%d %H--%M--%S")) # 2019--11--29 10--13--26
void main() {
Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26
}
Форматирование с параметромfmt
отличается отJavaScript
, Python
, иC++
языки, как показано в следующих примерах:
Возвращает текущую временную строку без прохождения любых параметров._D()
Функция вPython
Стратегия, вы должны знать, что параметры прошли временные отметки второго уровня (миллисекундного уровня временных отметки в JavaScript и C ++ стратегии, где 1 секунда равна 1000 миллисекунд)._D()
функция для анализа временной последовательности с читаемой временной меткой в живой торговли, вы должны обратить внимание на часовой пояс и время настройки операционной системы, где расположена программа Docker._D()
функция анализирует временную метку в читаемую временную строку в зависимости от времени системы докера.
{@fun/Global/UnixNano UnixNano}, {@fun/Global/Unix Unix}
Форматируйте число с плавающей запятой.
Форматированное число с плавающей запятой в соответствии с настройкой точности. Номер
_N() _N(num) _N ((num, точность)
Номер с плавающей запятой, который нужно отформатировать.
число
неправда
Номер
Настройка точности форматирования, параметрprecision
является целым числом, и параметрprecision
По умолчанию 4.
точность
ложное
Номер
function main(){
var i = 3.1415
Log(i)
var ii = _N(i, 2)
Log(ii)
}
def main():
i = 3.1415
Log(i)
ii = _N(i, 2)
Log(ii)
void main() {
auto i = 3.1415;
Log(i);
auto ii = _N(i, 2);
Log(ii);
}
Например,_N(3.1415, 2)
удалит значение после3.1415
два знака за десятичной запятой и функция возвращает3.14
.
function main(){
var i = 1300
Log(i)
var ii = _N(i, -3)
// Check the logs and see that it is 1000
Log(ii)
}
def main():
i = 1300
Log(i)
ii = _N(i, -3)
Log(ii)
void main() {
auto i = 1300;
Log(i);
auto ii = _N(i, -3);
Log(ii);
}
Если вам нужно изменить все цифры N слева от запятой на 0, вы можете написать это так:
Параметрprecision
может быть положительным целым числом, отрицательным целым числом.
{@fun/Trade/exchange.SetPrecision exchange.SetPrecision} - Я не знаю.
Попробуйте заново функцию допустимости ошибок интерфейса.
Возвратное значение функции обратного вызова при ее выполнении. Все типы поддерживаются системой, кромеЛогическое ложное значениеинулевое значение.
_C (((pfn) _C ((pfn,...args)
Параметрpfn
является функцией ссылки, которая являетсяфункция обратного вызова- Да.
пфн
неправда
Функция
Параметры дофункции обратного вызова, может быть более одного параметраarg
. Тип и количество параметровarg
зависит от параметровфункция обратного вызова- Да.
арг
ложное
строка, число, bool, объект, массив, функция, все типы поддерживаются системой, такие как нулевые значения
function main(){
var ticker = _C(exchange.GetTicker)
// Adjust _C() function retry interval to 2 seconds
_CDelay(2000)
var depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
}
def main():
ticker = _C(exchange.GetTicker)
_CDelay(2000)
depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
void main() {
auto ticker = _C(exchange.GetTicker);
_CDelay(2000);
auto depth = _C(exchange.GetDepth);
Log(ticker);
Log(depth);
}
Для ошибочно-толерантных функций без параметров:
function main(){
var records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
}
def main():
records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
void main() {
auto records = _C(exchange.GetRecords, PERIOD_D1);
Log(records);
}
Для функций с параметрами, которые допускают ошибки:
var test = function(a, b){
var time = new Date().getTime() / 1000
if(time % b == 3){
Log("Eligible!", "#FF0000")
return true
}
Log("Retry!", "#FF0000")
return false
}
function main(){
var ret = _C(test, 1, 5)
Log(ret)
}
import time
def test(a, b):
ts = time.time()
if ts % b == 3:
Log("Eligible!", "#FF0000")
return True
Log("Retry!", "#FF0000")
return False
def main():
ret = _C(test, 1, 5)
Log(ret)
// C++ does not support fault tolerance for custom functions in this way
Он также может быть использован для отказоустойчивости пользовательских функций:
В_C()
function будет продолжать вызвать указанную функцию, пока она не вернется успешно (функция, на которую ссылается параметрpfn
доходынулевойилиложныйкогда вызовут, перепробует вызватьpfn
Например,_C(exchange.GetTicker)
. Интервал повторного попытки по умолчанию составляет 3 секунды, вы можете вызвать_CDelay()
функция для установки интервала повторных попыток._CDelay(1000)
средства для изменения интервала повторных попыток_C()
Функция на 1 секунду.
Пропускная способность к ошибкам может быть выполнена для, но не ограничивается, следующими функциями:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPositions()
Все могут быть вызваны_C()
Функция допустимости неисправностей_C()
функция не ограничивается вышеперечисленной функцией допустимости неисправности, параметромpfn
является ссылкой на функцию, а не вызовом функции.
Заметьте, что это_C(exchange.GetTicker)
, нет_C(exchange.GetTicker())
.Возвращает количество периодов пересечения массиваarr1
и массивarr2
.
Количество перекрестных периодов массиваarr1
и массивarr2
- Да.
Номер
_Кросс ((arr1, arr2)
Элементы - это массивы типаnumber
- Да.
Arr1
неправда
массив
Элементы - это массивы типаnumber
- Да.
arr2
неправда
массив
// Fast line indicator
var arr1 = [1,2,3,4,5,6,8,8,9]
// Slow line indicator
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}
Набор данных может быть смоделирован для проверки функции _Cross ((Arr1, Arr2):
Если возвращение значения_Cross()
Если функция является положительным числом, она указывает на период восходящего проникновения, если она является отрицательным числом, она указывает на период нисходящего проникновения, 0 означает то же самое, что текущая цена.Анализ и инструкции по использованию встроенной функции _Кросс.
ФункцияJSONParse()
используется для анализаJSON
strings.
JSON
Объект.
объект
JSONParse ((s)
JSON
Строка.
с
неправда
строка
function main() {
let s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("JSON.parse:", JSON.parse(s1)) // JSON.parse: {"num":8.754613216564988e+39}
Log("JSONParse:", JSONParse(s1)) // JSONParse: {"num":"8754613216564987646512354656874651651358"}
let s2 = '{"num": 123}'
Log("JSON.parse:", JSON.parse(s2)) // JSON.parse: {"num":123}
Log("JSONParse:", JSONParse(s2)) // JSONParse: {"num":123}
}
import json
def main():
s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("json.loads:", json.loads(s1)) # json.loads: map[num:8.754613216564987e+39]
Log("JSONParse:", JSONParse(s1)) # JSONParse: map[num:8754613216564987646512354656874651651358]
s2 = '{"num": 123}'
Log("json.loads:", json.loads(s2)) # json.loads: map[num:123]
Log("JSONParse:", JSONParse(s2)) # JSONParse: map[num:123]
void main() {
auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
Log("json::parse:", json::parse(s1));
// Log("JSONParse:", JSONParse(s1)); // The function is not supported.
auto s2 = "{\"num\":123}";
Log("json::parse:", json::parse(s2));
// Log("JSONParse:", JSONParse(s2)); // The function is not supported.
}
Строки JSON с большими значениями можно правильно анализировать, и это будет анализировать большие значения в виде типов строки.JSONParse()
функция не поддерживается в системе обратного тестирования.