Mengembalikan nomor versi sistem saat ini.
Nomor versi sistem saat ini, seperti3.6
Aku tidak tahu.
string
Versi ((()
function main() {
Log("version:", Version())
}
def main():
Log("version:", Version())
void main() {
Log("version:", Version());
}
Nomor versi sistem adalah nomor versi dari program docker.
Fungsi tidur, menyebabkan program berhenti sejenak.
Tidur (millisecond)
Peraturanmillisecond
parameter digunakan untuk mengatur durasi tidur dan jumlah milidetik.
Milisekund
benar
nomor
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");
}
Sebagai contoh, ketika menjalankanSleep(1000)
fungsi, program akan tidur selama 1 detik.Sleep(0.1)
. Ini mendukung parameter minimum dari0.000001
, yaitu hibernasi nanodetik, di mana 1 nanodetik sama dengan1e-6
Milisekund.
Ketika menulis strategi diPython
bahasa,Sleep(millisecond)
fungsi harus digunakan untuk intervall polling, waktu untuk menunggu operasi.time.sleep(second)
fungsi dariPython
Itu adalahtime
ini karena menggunakantime.sleep(second)
fungsi dalam strategi membuat program strategi menunggu untuk periode waktu sebenarnya ketika backtesting (tidak melewatkan seri waktu dari sistem backtesting), sehingga menyebabkan strategi untuk backtest sangat lambat.
Tentukan apakah lingkungan operasi strategi adalah sistem backtesting.
Strategi mengembalikan nilai sebenarnya, misalnya:true
Strategi ini mengembalikan nilai palsu, misalnya:false
ketika berjalan di lingkungan perdagangan langsung.
bool
Apakah Virtual ((()
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.");
}
}
Tentukan apakah lingkungan berjalan saat ini adalah sistem backtesting, yang digunakan untuk kompatibel dengan perbedaan antara backtesting dan perdagangan langsung.
Kirim email.
Pengiriman email yang berhasil mengembalikan nilai yang sebenarnya, misalnya,true
, dan pengiriman gagal mengembalikan nilai palsu, misalnya,false
Aku tidak tahu.
bool
Mail ((smtpServer, smtpUsername, smtpPassword, mailTo, judul, tubuh)
Digunakan untuk menentukanSMTP
alamat layanan pengirim email.
smtpServer
benar
string
Digunakan untuk menentukan alamat email pengirim email.
smtpNama pengguna
benar
string
PeraturanSMTP
kata sandi untuk kotak surat pengirim email.
smtpPassword
benar
string
Digunakan untuk menentukan alamat email penerima email.
mailTo
benar
string
Alamat email.
Judul
benar
string
Tubuh email.
tubuh
benar
string
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");
}
PeraturansmtpPassword
parameter menetapkan kata sandi untukSMTP
layanan, bukan kata sandi kotak surat.
Saat mengatursmtpServer
parameter, jika Anda perlu mengubah port, Anda dapat menambahkan nomor port langsung di parametersmtpServer
. Misalnya: QQ mailsmtp.qq.com:587
, yang tersedia untuk pengujian.
Jika kesalahan dilaporkan:unencryped connection
, Anda perlu memodifikasismtpServer
dariMail
Format parameter adalah:ssl://xxx.com:xxx
, misalnya,ssl
metodeSMTP
untuk QQ mail:ssl://smtp.qq.com:465
atausmtp://xxx.com:xxx
Aku tidak tahu.
Ini tidak bekerja di sistem backtesting.
{@fun/Global/Mail_Go Mail_Go}
Versi asinkron dariMail
function.
PeraturanMail_Go
fungsi mengembalikan objek bersamaan segera, dan Anda dapat menggunakanwait
metode dari objek bersamaan untuk mendapatkan hasil pengiriman surat. pengiriman surat yang sukses mengembalikan nilai benar, misalnya,true
, dan pengiriman gagal mengembalikan nilai palsu, misalnya,false
Aku tidak tahu.
objek
Mail_Go ((smtpServer, smtpUsername, smtpPassword, mailTo, judul, body)
Ini digunakan untuk menentukanSMTP
alamat layanan pengirim email.
smtpServer
benar
string
Ini digunakan untuk menentukan alamat email pengirim email.
smtpNama pengguna
benar
string
PeraturanSMTP
kata sandi untuk kotak surat pengirim email.
smtpPassword
benar
string
Ini digunakan untuk menentukan alamat email penerima email.
mailTo
benar
string
Alamat email.
Judul
benar
string
Tubuh email.
tubuh
benar
string
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.
Ini tidak bekerja di sistem backtesting.
{@fun/Global/Mail Mail}
Log kesalahan filter.
SetErrorFilter ((filter)
Senar ekspresi reguler. Filter benar string
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");
}
Menyaring kesalahan umum.
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);
}
Menyaring pesan kesalahan antarmuka.
Log kesalahan yang cocok dengan ekspresi reguler ini tidak akan diunggah ke sistem log. Anda dapat memanggilnya beberapa kali (tidak ada batasan jumlah kali) untuk mengatur beberapa kondisi filter. Ekspresi reguler yang ditetapkan beberapa kali akan dikumpulkan dan berlaku pada saat yang sama. Anda dapat mengatur string kosong untuk mengatur ulang ekspresi reguler yang digunakan untuk menyaring log kesalahan:SetErrorFilter("")
. Log yang disaring tidak lagi ditulis ke file database yang sesuai dengan ID perdagangan langsung di direktori docker untuk mencegah laporan kesalahan yang sering dari membengkak file database.
Dapatkan ID proses perdagangan langsung.
Kembalikan ID proses perdagangan langsung. string
GetPid ((()
function main(){
var id = GetPid()
Log(id)
}
def main():
id = GetPid()
Log(id)
void main() {
auto id = GetPid();
Log(id);
}
Dapatkan pesan kesalahan terakhir.
Pesan kesalahan terakhir. string
GetLastError ((()
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);
}
Ini tidak bekerja di sistem backtesting.
Dapatkan perintah interaksi strategi.
Format perintah kembali adalahControlName:Data
. ControlName
adalah nama kontrol, danData
adalah data yang dimasukkan ke dalam kontrol. Jika kontrol interaktif tidak memiliki kotak input, kotak drop-down dan komponen lain (misalnya kontrol tombol tanpa kotak input) maka format perintah yang dikembalikan adalahControlName
, yang hanya mengembalikan nama kontrol.
string
GetCommand ((()
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);
}
}
Mendeteksi perintah interaksi dan menggunakanLog
fungsi untuk output perintah interaksi ketika terdeteksi.
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);
}
}
Misalnya, strategi kontrol interaktif menambahkan kontrol tanpa kotak input, kontrol interaktif diberi nama:buy
, informasi deskripsi kontrol adalah:buy
, yang merupakan kontrol tombol. Lanjutkan dengan menambahkan kontrol dengan kotak input. Kontrol interaktif bernama:sell
dan pesan deskripsi kontrol adalah:sell
, yang merupakan kontrol interaktif yang merupakan kombinasi dari tombol dan kotak input. kode interaksi dirancang dalam strategi untuk menanggapi kontrol interaksi yang berbeda:
Ini tidak bekerja di sistem backtesting.
Dapatkan nilai Meta ditulis saat menghasilkan kode pendaftaran strategi.
Meta
data.
string
DapatkanMeta
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);
}
}
Contoh skenario aplikasi: PenggunaanMeta
untuk membatasi jumlah aset yang dioperasikan oleh strategi.
Skenario aplikasi: perlu melakukan batas modal untuk penyewa strategi yang berbeda.Meta
nilai yang ditetapkan saat menghasilkan kode pendaftaran tidak dapat melebihi 190 karakter danGetMeta()
Jika tidak ada metadata (Meta
) ditetapkan saat menghasilkan kode pendaftaran strategi,GetMeta()
Fungsi ini tidak berfungsi di sistem backtesting.
Untuk primitifSocket
akses, mendukungtcp
, udp
, tls
, unix
Mendukung 4 protokol komunikasi populer:mqtt
, nats
, amqp
, kafka
. Dukungan untuk menghubungkan ke database:sqlite3
, mysql
, postgres
, clickhouse
.
PeraturanDial()
fungsi mengembalikan null jika waktu habis. panggilan normal mengembalikan objek koneksi yang memiliki tiga metode:read
, write
danclose
.read
metode digunakan untuk membaca data,write
metode digunakan untuk mengirim data danclose
metode digunakan untuk menutup koneksi.
Peraturanread
Metode ini mendukung parameter berikut:
ws.read()
.ws.read(2000)
menentukan timeout dua detik (2000 millisecond).-1
berarti bahwa fungsi mengembalikan langsung, terlepas dari kehadiran atau tidak adanya pesan, misalnya:ws.read(-1)
Aku tidak tahu.
Mengirim parameter-2
berarti bahwa fungsi mengembalikan segera dengan atau tanpa pesan, tetapi hanya pesan terbaru yang dikembalikan, dan pesan yang disimpen dibuang.ws.read(-2)
.read()
deskripsi buffer fungsi:
Data masuk yang didorong oleh protokol WebSocket dapat menyebabkan akumulasi data jika interval waktu antara strategiread()
Data ini disimpan di buffer, yang memiliki struktur data antrian dengan maksimum 2000. Setelah 2000 dilampaui, data terbaru dimasukkan ke buffer dan data tertua dihapus.
Skenario | Tidak ada parameter | Parameter: -1 | Parameter: -2 | Parameter: 2000, dalam milidetik |
---|---|---|---|---|
Data sudah di buffer | Kembalikan data tertua segera | Kembalikan data tertua segera | Kembali data terbaru segera | Kembalikan data tertua segera |
Tidak ada data di buffer | Kembali saat diblokir ke data | Kembali null segera | Kembali null segera | Tunggu 2000 ms, kembali null jika tidak ada data, kembali null jika ada data |
Koneksi WebSocket terputus atau dihubungkan kembali oleh yang mendasarinya | read() function mengembalikan string kosong, yaitu: |
objek
Pilih (Alamat) Pilih (alamat, waktu)
Alamat permintaan. alamat benar string detik timeout, timeout palsu Nomor
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();
}
}
Contoh panggilan fungsi 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();
}
Untuk mengakses antarmuka ticker 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");
}
Akses ke antarmuka ticker WebSocket 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");
}
Akses ke antarmuka ticker WebSocket Huobi
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");
}
Untuk mengakses 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
Objek koneksi yang dikembalikan oleh fungsi Dial saat terhubung ke database memiliki dua fungsi metode yang unik untuknya:
exec(sqlString)
: Digunakan untuk mengeksekusi pernyataan SQL dengan cara yang mirip denganDBExec()
function.fd()
: Thefd()
fungsi mengembalikan pegangan (misalnya, variabel pegangan adalah pegangan) yang akan digunakan oleh thread lain untuk terhubung kembali (bahkan jika objek yang dibuat oleh Dial telah ditutup oleh pelaksanaanclose()
fungsi untuk menutup koneksi) dengan melewati pegangan keDial()
fungsi, misalnya,Dial(handle)
Gunakan kembali koneksi.
Berikut ini adalah contoh dari fungsi Dial menghubungkan kesqlite3
database.Rincian dariaddress
parameter, dipisahkan oleh|
simbol setelah alamat normal:wss://ws.okx.com:8443/ws/v5/public
Jika ada.|
karakter dalam string parameter, kemudian||
Bagian setelah itu adalah beberapa pengaturan parameter fungsi, dan setiap parameter terhubung dengan&
karakter. Misalnya,ss5
Parameter proxy dan kompresi dapat disatukan sebagai berikut:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
Fungsi yang didukung oleh parameter alamat dari fungsi Dial | Deskripsi parameter |
---|---|
Parameter yang terkait dengan kompresi data protokol WebSocket: compress=parameter value | compress adalah metode kompresi, pilihan parameter compress adalah: gzip_raw, gzip, dll. Jika metode gzip tidak standar gzip, Anda dapat menggunakan metode diperpanjang: gzip_raw |
Parameter yang terkait dengan kompresi data protokol WebSocket: mode=nilai parameter | mode adalah mode kompresi, parameter mode dapat dual, send, recv. dual adalah kompresi dua arah, mengirim data terkompresi, menerima data terkompresi. send adalah mengirim data terkompresi. recv adalah menerima data terkompresi, dekompresi lokal. |
Protokol WebSocket menetapkan parameter terkait auto-reconnect yang mendasari: reconnect=parameter value | reconnect adalah apakah untuk mengatur reconnect, reconnect=true adalah untuk mengaktifkan reconnect. |
Protokol WebSocket menetapkan parameter terkait auto-reconnect yang mendasari: interval=nilai parameter | interval adalah interval percobaan ulang, dalam milidetik, interval=10000 adalah interval percobaan ulang 10 detik, default adalah 1 detik ketika tidak diatur, yaitu interval=1000. |
Protokol WebSocket menetapkan parameter terkait auto-reconnect yang mendasari: payload=parameter value | payload adalah pesan langganan yang perlu dikirim saat WebSocket dihubungkan kembali, misalnya: payload=okokok. |
Parameter yang terkait dengan kaus kaki5 proxy: proxy=nilai parameter | Proxy adalah pengaturan proxy ss5, format nilai parameter: socks5://name:pwd@192.168.0.1:1080, nama adalah nama pengguna server ss5, pwd adalah password login server ss5, 1080 adalah port layanan ss5. |
PeraturanDial()
Fungsi hanya didukung untuk perdagangan langsung.
Saat terhubung ke database menggunakan fungsi Dial, string koneksi ditulis dengan referensi ke proyek driver bahasa go untuk setiap database.
Basis data yang didukung | Proyek Penggerak | Senar koneksi | Pengamatan |
---|---|---|---|
Sqlite3 | github.com/mattn/go-sqlite3 | sqlite3://file:test.db?cache=shared&mode=memory | Peraturansqlite3:// Prefiks menunjukkan bahwa database sqlite3 sedang digunakan, contoh panggilan:Dial("sqlite3://test1.db") |
MySQL | github.com/go-sql-driver/mysql | mysql://username:yourpassword@tcp(localhost:3306) /database Anda?charset=utf8mb4 | – |
Tumbuh | github.com/lib/pq | postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword host=localhost port=5432 | – |
rumah klik | github.com/ClickHouse/clickhouse-go | klikhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase | – |
Harap dicatat bahwa ketikapayload
konten yang ditetapkan dalamaddress
parameter berisi karakter=
atau karakter khusus lainnya, dapat mempengaruhi analisis dariaddress
parameter dariDial
fungsi, seperti contoh berikut.
contoh panggilan backPack Exchange websocket private interface:
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}}")
}
Panggilan berikut dalam kode bekerja dengan baik:
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
Jika Anda menulisnya langsung dipayload
, tidak akan berfungsi dengan baik, misalnya:
client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))
Saat ini, hanya JavaScript mendukung penggunaanmqtt
, nats
, amqp
, dankafka
kode strategi bahasa JavaScript digunakan sebagai contoh untuk menunjukkan penggunaan empat protokol:mqtt
, nats
, amqp
, dankafka
:
// 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")
}
}
Referensi dokumentasi rinci:Menjelajahi FMZ: Praktik Protokol Komunikasi Antara Strategi Perdagangan Langsung
Kirim permintaan Http.
Mengembalikan data respons dari permintaan. Jika nilai yang dikembalikan adalahJSON
string, itu dapat dianalisis olehJSON.parse()
Fungsi dalamJavaScript
strategi bahasa, dan olehjson::parse()
Fungsi dalamC++
Jika debug ditetapkan menjadi true dalam struktur opsi, nilai pengembalian adalah objek (JSON); jika debug ditetapkan menjadi false, nilai pengembalian adalah string.
string, objek
HttpQuery (URL) HttpQuery ((url, opsi)
URL permintaan HTTP. Url benar string Pengaturan terkait permintaan HTTP, misalnya, dapat disusun sebagai berikut:
{
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
Sidik jari.
Pengaturan yang didukung termasuk opsi berikut:
chrome_:"chrome_103"
, "chrome_104"
, "chrome_105"
, "chrome_106"
, "chrome_107"
, "chrome_108"
, "chrome_109"
, "chrome_110"
, "chrome_111"
, "chrome_112"
, "chrome_117"
...
Safari_:"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_:"opera_89"
, "opera_90"
, "opera_91"
...
Zalando:"zalando_android_mobile"
, "zalando_ios_mobile"
...
Nike_:"nike_ios_mobile"
, "nike_android_mobile"
...
gedung pencakar langit:"cloudscraper"
...
mms_:"mms_ios"
...
mesh_:"mesh_ios"
, "mesh_ios_1"
, "mesh_ios_2"
, "mesh_android"
, "mesh_android_1"
, "mesh_android_2"
...
Konfirmasi_:"confirmed_ios"
, "confirmed_android"
...
Oke."okhttp4_android_7"
, "okhttp4_android_8"
, "okhttp4_android_9"
, "okhttp4_android_10"
, "okhttp4_android_11"
, "okhttp4_android_12"
, "okhttp4_android_13"
,true
, yangHttpQuery
panggilan fungsi mengembalikan pesan jawaban penuh.false
, hanya data dalamBody
dari pesan balasan dikembalikan.profile
lapangan dapat dilewatkan.pilihan palsu objek
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);
}
Contoh mengakses antarmuka API ticker publik 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/");
}
Fungsi HttpQuery menggunakan pengaturan proxy.
PeraturanHttpQuery()
Fungsi hanya mendukungJavaScript
, C++
bahasa,Python
bahasa dapat menggunakanurllib
Perpustakaan untuk mengirim permintaan Http langsung.HttpQuery()
digunakan terutama untuk mengakses antarmuka pertukaran yang tidak memerlukan tanda tangan, seperti antarmuka publik seperti informasi ticker.HttpQuery()
dapat digunakan dalam sistem backtesting untuk mengirim permintaan (hanyaGET
Backtesting terbatas pada penggunaan 20 kunjungan ke berbagaiURLs
, danHttpQuery()
kunjungan akan cache data.URL
diakses untuk kedua kalinya,HttpQuery()
fungsi mengembalikan data yang di-cache dan tidak ada lagi permintaan jaringan yang sebenarnya terjadi.
{@fun/Global/HttpQuery_Go HttpQuery_Go}
Mengirim permintaan HTTP, versi asinkron dariHttpQuery
function.
PeraturanHttpQuery_Go()
fungsi segera mengembalikan objek bersamaan yang dapat digunakan untuk mendapatkan hasil permintaan HTTP menggunakanwait
metode dariJSON.parse()
fungsi dapat digunakan untuk menganalisisJSON.parse()
Fungsi dalamJavaScript
strategi bahasa.
objek
HttpQuery_Go ((url) HttpQuery_Go ((url, opsi)
URL permintaan HTTP. Url benar string Pengaturan terkait permintaan HTTP, misalnya, dapat disusun sebagai berikut:
{
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
, iniHttpQuery_Go
panggilan fungsi mengembalikan pesan jawaban penuh.false
, hanya data dalamBody
dari pesan balasan dikembalikan.profile
lapangan dapat dilewatkan.pilihan palsu objek
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
Akses asinkron ke antarmuka publik pertukaran untuk data ticker agregat.
PeraturanHttpQuery_Go()
Fungsi hanya mendukungJavaScript
, yangPython
bahasa dapat digunakan denganurllib
Perpustakaan untuk mengirim permintaan Http langsung.HttpQuery_Go()
digunakan terutama untuk mengakses antarmuka yang tidak memerlukan tanda tangan di bursa, seperti antarmuka publik seperti informasi ticker.HttpQuery_Go
fungsi tidak didukung dalam sistem backtesting.
{@fun/Global/HttpQuery HttpQuery}
Fungsi ini mengkodekan data sesuai dengan parameter yang diteruskan.
PeraturanEncode
fungsi mengembalikan data setelah pengkodean dan enkripsi.
string
Encode ((algo, inputFormat, outputFormat, data) Encode ((algo, inputFormat, outputFormat, data, kunciFormat, kunci)
Parameteralgo
adalah algoritma yang digunakan dalam perhitungan pengkodean. Pengaturan dukungan adalah:raw
(tidak ada algoritma yang digunakan), "tanda", algo
juga mendukung: algo
juga mendukung: algo
dapat ditulis sebagai ed25519.seed
perhitungan.
sesuatu
benar
string
Digunakan untuk menentukan format data daridata
parameter.inputFormat
parameter dapat ditetapkan sebagai salah satu dari berikut:raw
, hex
, base64
, string
. hex
dikodekan, base64
dikodekan, dan outputFormat
parameter dapat ditetapkan sebagai salah satu dari berikut:raw
, hex
, base64
, string
. hex
dikodekan, base64
dikodekan, dan data
adalah data yang akan diproses.
data
benar
string
Digunakan untuk menentukan format data darikey
parameter.key
parameter dapat ditetapkan sebagai salah satu dari berikut:raw
, hex
, base64
, string
. hex
dikodekan, base64
dikodekan, dan key
adalah kunci rahasia yang digunakan untukHMAC
Enkripsi.key
diperlukan ketika parameteralgo
diatur untuksign
atausignTx
.key
parameter tidak digunakan untukHMAC
Enkripsi ketikaalgo
parameter ditetapkan menjadi
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
}
Contoh panggilan fungsi 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);
}
Parameteralgo
juga mendukung:
PeraturanEncode()
fungsi hanya didukung untuk perdagangan langsung.key
dankeyFormat
parameter tidak lulus, makakey
Enkripsi tidak digunakan.
Dapatkan tanda waktu nanodetik saat ini.
PeraturanUnixNano()
Fungsi mengembalikan tanda waktu nanodetik.
Nomor
UnixNano ((()
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
Jika Anda perlu mendapatkan time stamp millisecond, Anda dapat menggunakan kode berikut:
{@fun/Global/Unix Unix}
Dapatkan time stamp saat ini di tingkat kedua.
Mengembalikan timestamp tingkat dua. Nomor
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}
Dapatkan informasi sistem dari perangkat di mana docker terletak.
Informasi sistem. string
GetOS()
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
Sebagai contoh, panggilan keGetOS()
fungsi untuk docker yang berjalan padaMac OSsistem operasi mungkin kembali:darwin/amd64
Karena komputer Apple memiliki beberapa arsitektur hardware.darwin
adalah nama dariMac OS system.
Menghitung hash MD5 dari parameterdata
.
Nilai hash MD5. string
MD5 (data)
Data yang membutuhkan perhitungan MD5. data benar string
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
MenelponMD5("hello world")
fungsi, nilai yang dikembalikan adalah:5eb63bbbe01eeed093cb22bb8f5acdc3
.
{@fun/Global/Encode Encode}
Fungsi antarmuka database.
Sebuah objek yang berisi hasil dari eksekusiSqlpernyataan, misalnya:
{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}
objek
DBExec ((sql)
Sqlstring pernyataan. Sql benar string
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;"));
}
Dukungan database di memori, untukDBExec
parameter fungsi, jikaSqlpernyataan dimulai dengan:
kemudian dioperasikan dalam database in-memory, akan lebih cepat tanpa menulis file.
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);
}
Buat meja.
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));
}
Tambahkan, hapus, periksa dan ubah catatan dalam tabel.
FungsiDBExec()
dapat mengoperasikan database perdagangan langsung (database SQLite) dengan melewati parameter.SQLiteSistem cadangan tabel di basis data perdagangan langsung:kvdb
, cfg
, log
, profit
, chart
, jangan bekerja di meja ini.Transaksitidak didukung dan tidak dianjurkan untuk melakukan operasi tersebut, yang dapat menyebabkan konflik dalam sistem.DBExec()
Fungsi hanya didukung untuk perdagangan langsung.
{@fun/Global/_G _G}
Buat UUID.
UUID 32 bit. string
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);
}
PeraturanUUID()
Fungsi hanya mendukung perdagangan langsung.
Dengarkan untuk peristiwa, itu kembali ketika adaWebSocket
data yang dapat dibaca atau tugas bersamaan, sepertiexchange.Go()
, HttpQuery_Go()
, dll telah selesai.
Jika objek yang dikembalikan bukan nilai nol,Event
yang terkandung dalam konten pengembalian adalah jenis pemicu peristiwa. Misalnya struktur nilai pengembalian berikut:
{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}
objek
EventLoop ((() EventLoop (timeout)
Parametertimeout
adalah pengaturan timeout, dalam milidetik.timeout
menunggu suatu peristiwa terjadi sebelum kembali jika ditetapkan menjadi 0. Jika lebih besar dari 0, mengatur peristiwa untuk menunggu waktu habis, dan mengembalikan peristiwa terbaru segera jika kurang dari 0.
timeout
palsu
nomor
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);
}
Panggilan pertama untukEventLoop()
fungsi dalam kode menginisialisasi mekanisme untuk acara yang didengarkan, dan jika yang pertamaEventLoop()
call dimulai setelah event callback, itu akan melewatkan acara sebelumnya. sistem yang mendasari membungkus struktur antrian yang cache maksimum 500 callback acara.EventLoop()
fungsi tidak dipanggil pada waktunya untuk mengambil mereka keluar selama eksekusi program, kemudian callback acara di luar 500 cache akan hilang.EventLoop()
fungsi tidak mempengaruhi antrian cache dari sistem dasar WebSocket atau cache fungsi bersamaan sepertiexchange.Go()
Untuk cache ini, masih perlu menggunakan metode masing-masing untuk mengambil data.EventLoop()
fungsi untuk data yang telah diambil sebelumEventLoop()
Tujuan utama dariEventLoop()
fungsi adalah untuk memberi tahu lapisan strategi bahwa data jaringan baru telah diterima oleh sistem yang mendasari.EventLoop()
fungsi mengembalikan suatu peristiwa, hanya melintasi semua sumber data.exchange.Go()
mencoba untuk mendapatkan data.EventLoop()
Fungsi hanya mendukung perdagangan langsung.
Dengarkan acara di thread utama ketika dipanggil dari fungsi utamamain()
. Dalam strategi yang ditulis dalamJavaScript
bahasa,threading.Thread()
fungsi membuat thread, yang juga dapat dipanggil dalam fungsi eksekusi thread
{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
Peraturan__Serve
fungsi digunakan untuk membuat layanan HTTP, layanan TCP, dan layanan Websocket (berdasarkan protokol HTTP).
Mengembalikan string yang mencatat alamat IP dan port dari layanan yang dibuat.127.0.0.1:8088
, [::]:8089
.
string
__Serve (serveURI, pengelola) __Serve ((serveURI, handler,...args)
PeraturanserveURI
parameter digunakan untuk mengkonfigurasi protokol, alamat IP, port dan pengaturan lain dari layanan mengikat, sepertihttp://0.0.0.0:8088?gzip=true
, yaitu,http://:8088?gzip=true
.
serveURI
pengaturan parameter, sepertitcp://127.0.0.1:6666?tls=true
; Anda dapat menambahkan sertifikat dan kunci pribadi, sepertitls=true&cert_pem=xxxx&cert_key_pem=xxxx
.serveURI
pengaturan parameter, sepertihttp://127.0.0.1:6666?gzip=true
; Anda dapat mengatur pengaturan kompresi:gzip=true
Aku tidak tahu.
PeraturanserveURI
parameter digunakan untuk Https, sepertihttps://127.0.0.1:6666?tls=true&gzip=true
; Anda dapat menambahkancert_pem
dancert_key_pem
parameter untuk memuat sertifikat.melayaniURI
benar
string
Peraturanhandler
Parameter digunakan untuk lulus dalam fungsi pemrosesan routing (Http protokol), fungsi pemrosesan pesan (TCP protokol), dan fungsi pemrosesan Stream (Websocket).
Fungsi callback yang diteruskan oleh parameterhandler
dapat mendefinisikan beberapa parameter, parameter pertama adalah objek ctx (objek konteks).
pengelola
benar
fungsi
Parameter sebenarnya dari fungsi callback yang dilewati sebagai parameterhandler
Mungkin ada beberapa parameter.arg
, misalnya:
__Serve("http://:8088", function(ctx, a, b, c) {
Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)
Parameter1
, 2
, 3
melewati saat memanggil__Serve()
fungsi sesuai dengan parametera
, b
, c
dilewati dalam fungsi callback.
arg palsu string, number, bool, object, array, function, null value dan tipe lain yang didukung oleh sistem
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
layanan diimplementasikan berdasarkan protokol Http. Anda dapat mengatur cabang routing di jalur dan merancang kode implementasi untukWebsocket
Anda dapat melihat contoh kode di bagian ini.Fungsi callback yang diteruskan oleh parameterhandler
menerimactx
parameter.ctx
parameter adalah objek konteks yang digunakan untuk mendapatkan dan menulis data, dengan metode berikut:
HTTP/1.1
, tcp
.http://127.0.0.1:8088?num=123
, dan fungsi pemrosesan callback yang diteruskan oleh parameterhandler
kembali"123"
kapan?ctx.query("num")
disebut.User-Agent
dalam judul permintaan saat ini:ctx.header("User-Agent")
.GET
, POST
, dll.ctx
objek konteks ke protokol Websocket; mengembalikan nilai Boolean (benar) jika switch berhasil, dan nilai Boolean (palsu) jika gagal.read
metode tidak didukung dalam protokol HTTP biasa. Anda dapat menentukan parameter timeouttimeout_ms
dalam milidetik.JSON.stringify()
untuk mengenkode objek JSON ke dalam string dan kemudian menulisnya.WebSocket
protokol, Anda dapat menggunakan metode ini untuk melewati string yang dienkode ke klien.{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
Fungsi ini mengimplementasikan fungsi kamus global yang dapat disimpan. Struktur data adalah tabel KV yang secara permanen disimpan di file database lokal docker.
Data nilai kunci yang disimpan secara permanen dik-v
Pasangan kunci-nilai.
string, nomor, bool, objek, array, nilai nol
_G() _G(k) _G(k, v)
Parameterk
adalah nama kunci dalam pasangan kunci-nilai yang disimpan, dan tidak sensitif huruf besar.
k
palsu
string, nilai nol
Parameterv
adalah nilai kunci dalam pasangan kunci-nilai yang disimpan, yang bisa menjadi data apa pun yang dapatJSON
Serial.
v
palsu
string, nomor, bool, objek, array, nilai nol
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();
}
Sebuah database terpisah untuk setiap perdagangan langsung, data yang disimpan oleh_G()
fungsi akan selalu ada jika strategi dimulai kembali atau docker berhenti berjalan._G()
Saat menggunakan_G()
fungsi untuk mempertahankan data yang disimpan, harus digunakan secara wajar sesuai dengan memori dan ruang hard disk perangkat keras, dan tidak boleh disalahgunakan.
Saat menelepon_G()
fungsi dalam perdagangan hidup dan tidak ada parameter yang dilewati,_G()
fungsi mengembalikanId
saat ini perdagangan langsung._G()
fungsi, parameterv
dilewatkan sebagai nol untuk menunjukkan penghapusank-v
Ketika memanggil_G()
fungsi, hanya parameterk
diteruskan dalam string, dan_G()
fungsi mengembalikan nilai kunci yang sesuai dengan parameter yang disimpank
. Ketika memanggil_G()
fungsi, hanya parameterk
diberikan dalam nilai nol, menunjukkan bahwa semua catatan darik-v
key-value pair dihapus.k-v
pasangan kunci-nilai telah disimpan terus menerus,_G()
fungsi dipanggil lagi, lulus dalam nama kunci yang telah disimpan terus-menerus sebagai parameterk
. Mengirim nilai kunci baru sebagai parameterv
akan memperbarui ituk-v
Pasangan kunci-nilai.
{@fun/Global/DBExec DBExec}
Mengkonversi millisecond timestamps atauDate
objek untuk string waktu.
String waktu. string
_D() _ D (Templat waktu) _D ((timestamp, fmt)
Stempel waktu milidetik atauDate
objek.
Stempel waktu
palsu
Nomor, objek
Format string,JavaScript
Format bahasa default:yyyy-MM-dd hh:mm:ss
; Python
Format bahasa default:%Y-%m-%d %H:%M:%S
; C++
Format bahasa default:%Y-%m-%d %H:%M:%S
Aku tidak tahu.
fmt
palsu
string
function main(){
var time = _D()
Log(time)
}
def main():
strTime = _D()
Log(strTime)
void main() {
auto strTime = _D();
Log(strTime);
}
Dapatkan dan cetak string waktu saat ini:
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));
}
Stempel waktu adalah 1574993606000, menggunakan konversi kode:
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
}
Format dengan parameterfmt
berbeda untukJavaScript
, Python
, danC++
bahasa, seperti yang ditunjukkan dalam contoh berikut:
Mengembalikan string waktu saat ini tanpa melewati parameter._D()
Fungsi dalamPython
strategi, Anda perlu menyadari bahwa parameter yang dilewatkan adalah timestamps tingkat kedua (timestamps tingkat milidetik dalam strategi JavaScript dan C ++, di mana 1 detik sama dengan 1000 milidetik)._D()
fungsi untuk menganalisis string waktu dengan timestamp yang dapat dibaca dalam perdagangan langsung, Anda perlu memperhatikan zona waktu dan pengaturan waktu dari sistem operasi di mana program docker terletak._D()
Fungsi ini menganalisis timestamp ke dalam string waktu yang dapat dibaca tergantung pada waktu dari sistem docker.
{@fun/Global/UnixNano UnixNano}, {@fun/Global/Unix Unix}
Formatkan nomor tanda gerak.
Nomor koma mengambang yang diformat sesuai dengan pengaturan presisi. nomor
_N() _N(nomor) _N ((num, presisi)
Nomor tanda mengapung yang perlu diformat.
Nomor
benar
Nomor
Pengaturan presisi untuk pemformatan, parameterprecision
adalah bilangan bulat, dan parameterprecision
default ke 4.
Keakuratan
palsu
Nomor
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);
}
Sebagai contoh,_N(3.1415, 2)
akan menghapus nilai setelah3.1415
dua tempat desimal dan fungsi kembali3.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);
}
Jika Anda perlu mengubah semua N digit ke kiri dari titik desimal ke 0, Anda dapat menulisnya seperti ini:
Parameterprecision
bisa menjadi bilangan bulat positif, bilangan bulat negatif.
{@fun/Trade/exchange.SetPrecision exchange.SetPrecision}
Coba lagi fungsi untuk toleransi kesalahan antarmuka.
Nilai yang dikembalikan dari fungsi callback saat dijalankan. Semua tipe didukung oleh sistem kecualinilai logis palsudannilai nol.
_C (((pfn) _C ((pfn,...args)
Parameterpfn
adalah referensi fungsi, yang merupakanFungsi callbackAku tidak tahu.
pfn
benar
fungsi
Parameter untukfungsi callback, mungkin ada lebih dari satu parameterarg
. Jenis dan jumlah parameterarg
tergantung pada parameter dariFungsi callbackAku tidak tahu.
arg
palsu
string, number, bool, object, array, function, semua jenis didukung oleh sistem, seperti nilai nol
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);
}
Untuk fungsi toleransi kesalahan tanpa parameter:
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);
}
Untuk fungsi dengan parameter yang toleransi kesalahan:
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
Hal ini juga dapat digunakan untuk toleransi kesalahan fungsi kustom:
Peraturan_C()
fungsi akan terus memanggil fungsi yang ditentukan sampai kembali dengan sukses (fungsi yang dirujuk oleh parameterpfn
kembalinolataupalsuketika dipanggil akan mencoba memanggil lagipfn
Misalnya:_C(exchange.GetTicker)
. Interval uji ulang default adalah 3 detik, Anda dapat memanggil_CDelay()
fungsi untuk mengatur interval percobaan ulang._CDelay(1000)
berarti untuk mengubah interval percobaan ulang dari_C()
fungsi ke 1 detik.
Toleransi kesalahan dapat dilakukan untuk, namun tidak terbatas pada, fungsi berikut:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPositions()
Semua dapat dipanggil oleh_C()
fungsi untuk toleransi kesalahan._C()
fungsi tidak terbatas pada fungsi yang tercantum di atas toleransi kesalahan, parameterpfn
adalah referensi fungsi daripada panggilan fungsi.
Perhatikan bahwa itu_C(exchange.GetTicker)
, tidak_C(exchange.GetTicker())
.Mengembalikan jumlah titik persimpangan arrayarr1
dan arrayarr2
.
Jumlah periode silang dari arrayarr1
dan arrayarr2
Aku tidak tahu.
Nomor
_Cross ((arr1, arr2)
Elemen adalah array tipenumber
Aku tidak tahu.
arr1
benar
Array
Elemen adalah array tipenumber
Aku tidak tahu.
arr2
benar
Array
// 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));
}
Satu set data dapat disimulasikan untuk menguji fungsi _Cross ((Arr1, Arr2):
Jika nilai pengembalian_Cross()
fungsi adalah angka positif, ini menunjukkan periode penetrasi ke atas, jika ini adalah angka negatif, ini menunjukkan periode penetrasi ke bawah, 0 berarti sama dengan harga saat ini.Analisis dan instruksi penggunaan tentang fungsi bawaan _Cross.
FungsiJSONParse()
digunakan untuk menganalisisJSON
strings.
JSON
objek.
objek
JSONParse (s)
JSON
tali.
s
benar
string
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 string dengan nilai besar dapat dianalisis dengan benar, dan akan dianalisis nilai besar sebagai jenis string.JSONParse()
fungsi tidak didukung dalam sistem backtest.