oparameter is set to
tandaor
tandaTx, the
parameter key`` diperlukan.
function main(){
Log(Encode("md5", "raw", "hex", "hello"))
Log(Encode("sha512", "raw", "base64", "hello"))
Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)"))
Log(Encode("raw", "string", "hex", "example")) // 6578616d706c65
Log(Encode("raw", "hex", "string", "6578616d706c65")) // example
}
def main():
Log(Encode("md5", "raw", "hex", "hello", "", ""))
Log(Encode("sha512", "raw", "base64", "hello", "", ""))
Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)", "", ""))
Log(Encode("raw", "string", "hex", "example", "", ""))
Log(Encode("raw", "hex", "string", "6578616d706c65", "", ""))
void main(){
Log(Encode("md5", "raw", "hex", "hello"));
Log(Encode("sha512", "raw", "base64", "hello"));
Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)"));
Log(Encode("raw", "string", "hex", "example")); // 6578616d706c65
Log(Encode("raw", "hex", "string", "6578616d706c65")); // example
}
Parameteralgo
juga menyokong pengekodan dan penyahkodan rentetan, sepertitext.encoder.utf8
, text.decoder.utf8
, text.encoder.gbk
dantext.decoder.gbk
.
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);
}
UnixNano()
mengembalikan cap masa tahap nanodetik; jika anda perlu mendapatkan cap masa tahap milidetik, anda boleh menggunakan kod berikut:
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
Unix()
Mengembalikan stempel masa dalam saat.
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
GetOS()
Mengembalikan maklumat mengenai sistem di mana docker terletak.
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
Keluaran log dari docker yang dijalankan olehMac OS
daripada komputer Apple:
GetOS:darwin/amd64
darwin
adalah namaMac OS
system.
MD5(String)
; nilai parameter: jenis rentetan.
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
Keluaran log:
MD5 5eb63bbbe01eeed093cb22bb8f5acdc3
DBExec()
, nilai parameternya boleh menjadi rentetan, nombor atau boolean, null dan jenis lain; nilai pulangan: objek dengan hasil pelaksanaan dalam bahasa SQLite.DBExec()
, fungsi antara muka pangkalan data, melalui lulus parameter, boleh menjalankan pangkalan data bot (pangkalan data SQLite). Ia merealisasikan penambahan, penghapusan, pertanyaan dan pengubahsuaian operasi pada pangkalan data bot, menyokongSQLite
Sistem dalam pangkalan data bot menyimpan jadual termasuk:kvdb
, cfg
, log
, profit
danchart
; tidak menggunakan mana-mana jadual yang disebutkan di atas.DBExec()
Hanya menyokong bot sebenar.
Menyokong pangkalan data memori
Untuk parameter fungsiDBExec
, jikasqlPernyataan bermula dengan:
, operasi dalam pangkalan data memori akan lebih cepat tanpa menulis fail. Ia sesuai untuk operasi pangkalan data tanpa keperluan untuk penyimpanan jangka panjang, sebagai contoh:
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 the 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 the 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 the data
Log(DBExec(":SELECT * FROM TEST_TABLE;"));
}
Membuat jadual
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 the data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
// Modify the data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
// Delete the 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 the data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
# Modify the data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
# Delete the 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 the data
Log(DBExec("SELECT * FROM TEST_TABLE;"));
// Modify the data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
// Delete the data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}
UUID()
, mengembalikan UUID unik 32-bit, fungsi ini hanya tersedia untuk bot sebenar.
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);
}
EventLoop(timeout)
, kembali selepas terdapat apa-apawebsocket
boleh dibaca atauexchange.Go
, HttpQuery_Go
dan tugas-tugas serentak yang lain diselesaikan.timeout
ditetapkan kepada 0, tunggu acara berlaku sebelum kembali. Jika lebih besar daripada 0, tetapkan masa tunggu acara. Jika kurang daripada 0, kembalikan acara terkini dengan segera. Jika objek yang dikembalikan tidaknull
, yangEvent
Fungsi ini hanya tersedia untuk perdagangan bot sebenar.
Panggilan pertamaEventLoop
dalam kod akan memulakan mekanisme mendengar peristiwa. Jika panggilan pertamaEventLoop
jika program ini dimulakan selepas panggilan balik acara, acara sebelumnya akan terlepas. struktur antrian yang dikemas dalam sistem yang mendasari akan cache sehingga 500 panggilan balik acara.EventLoop
tidak dipanggil pada masa untuk penyingkiran semasa pelaksanaan program, panggilan semula acara kemudian di luar 500 cache akan hilang.EventLoop
fungsi tidak akan mempengaruhi barisan cachewebsocket
pada sistem yang mendasari, atau cacheexchange.Go
dan fungsi serentak yang lain. untuk cache ini, anda masih perlu menggunakan kaedah mereka sendiri untuk mendapatkan data. untuk data yang telah diambil sebelumEventLoop
fungsi pulangan, tiada peristiwa pulangan akan dihasilkan dalamEventLoop
function.
Tujuan utamaEventLoop
fungsi adalah untuk memaklumkan lapisan strategi bahawa sistem asas telah menerima data rangkaian baru.EventLoop
fungsi mengembalikan peristiwa, anda hanya perlu melintasi semua sumber data.websocket
sambungan dan objek yang dicipta olehexchange.Go
Anda boleh merujuk kepada reka bentuk perpustakaan kelas sumber terbuka:pautan perpustakaan kelas.
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, the subsequent EventLoop function will miss the previous events, because after waiting for 2 seconds, the concurrent function has received the data, and the EventLoop monitoring mechanism will start later, and these events will be missed
// Unless you start calling EventLoop(-1) on the first line of code, first initialize the listening mechanism of EventLoop, you will not miss these events
// Log("GetDepth:", routine_getDepth.wait()) If the wait function is called in advance to get the result of the concurrent call of the GetDepth function, the event that the GetDepth function receives the request result 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);
}
_G(K, V)
, dengan fungsi kamus global yang boleh disimpan, menyokong kedua-dua backtest dan bot.
Struktur data adalahKV
setiap bot mempunyai pangkalan data yang berasingan. ia akan sentiasa wujud selepas memulakan semula atau apabila docker keluar.K
mestilah rentetan, yang tidak sensitif huruf besar.V
boleh menjadi apa-apaJSON
Apabila fungsi_G()
dipanggil dan tiada parameter yang dihantar dalam operasi bot, fungsi_G()
mengembalikanID
daripada bot semasa.
function main(){
// Set a global variable num with a value of 1
_G("num", 1)
// Change a global variable num with the value "ok"
_G("num", "ok")
// Delete global variable num
_G("num", null)
// Return the value of the global variable num
Log(_G("num"))
// Delete all global variables
_G(null)
// Return bot 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);
// does not support auto robotId = _G();
}
Nota:
Apabila menggunakan_G
fungsi untuk menyimpan data, ia harus digunakan dengan munasabah mengikut memori dan ruang cakera keras peranti perkakasan, dan tidak boleh disalahgunakan.Penumpukan memori problem.
_D(Timestamp, Fmt)
, mengembalikan rentetan masa yang sepadan dengan stempel masa yang ditentukan. Nilai parameter:Timestamp
adalah jenis numerik, dalam milidetik.Fmt
adalah jenis rentetan;Fmt
lalai kepada:yyyy-MM-dd hh:mm:ss
; nilai pulangan: jenis rentetan.
Ia mengembalikan rentetan stempel masa yang ditentukan, dan mengembalikan masa semasa tanpa lulus sebarang parameter; contohnya:_D()
atau_D(1478570053241)
, di mana format lalai adalahyyyy-MM-dd hh:mm:ss
.
function main(){
var time = _D()
Log(time)
}
def main():
strTime = _D()
Log(strTime)
void main() {
auto strTime = _D();
Log(strTime);
}
Nota:
Apabila digunakan_D()
dalamPython
strategi, kita perlu memberi perhatian bahawa parameter yang dihantar adalah timestamps dalam kedua (timestamps tahap milidetik dalamJavaScript
danC ++
strategi, dan 1 saat = 1000 milidetik).
Dalam bot, apabila menggunakan fungsi_D()
untuk menganalisis rentetan masa dengan cap masa yang boleh dibaca, anda perlu memberi perhatian kepada zon masa dalam sistem operasi program docker. fungsi_D()
Menganalisis stempel masa sebagai rentetan masa yang boleh dibaca berdasarkan masa sistem docker.
Sebagai contoh, menganalisis stempel masa1574993606000
dengan kod:
function main() {
Log(_D(1574993606000))
}
def main():
# Beijing time server runs: 2019-11-29 10:13:26, and the docker on another server in another region runs this code will get the results: 2019-11-29 02:13:26
Log(_D(1574993606))
void main() {
Log(_D(1574993606000));
}
_N(Num, Precision)
, nombor koma terapung berformat. Nilai parameter:Num
adalah jenis nombor;Precision
adalah jenis bilangan bulat. Nilai balik: jenis nombor.
Contohnya:_N(3.1415, 2)
akan memadamkan nilai selepas dua tempat perpuluhan3.1415
dan kembali3.14
.
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);
}
Jika anda perlu menukar N digit di sebelah kiri titik perpuluhan kepada 0, anda boleh menulis:
function main(){
var i = 1300
Log(i)
var ii = _N(i, -3)
// Checking the log shows 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);
}
_C(function, argsā¦)
adalah fungsi cubaan semula, digunakan untuk toleransi ralat antara muka mengenai mendapatkan maklumat pasaran dan memperoleh pesanan yang belum selesai, dll.
Antara muka akan memanggil fungsi yang ditentukan secara berterusan sehingga ia kembali dengan berjaya (parameterfunction
mengembalikan nilai null apabila memanggil fungsi rujukan ataufalse
akan cuba panggilan semula). Sebagai contoh,_ C(exchange. GetTicker)
, selang cuba semula lalai adalah 3 saat, yang boleh memanggil fungsi_CDelay (...)
untuk menetapkan selang percubaan semula, seperti_CDelay (1000)
bermaksud fungsi perubahan_C
Percubaan semula untuk 1 saat.
Untuk fungsi berikut:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPosition()
Mereka semua boleh dipanggil untuk melakukan toleransi ralat oleh fungsi_C(...)
. Fungsi_C(function, args...)
tidak terhad kepada toleransi ralat fungsi yang disenaraikan di atas.function
adalah dipetik tidak dipanggil, dan memberi perhatian bahawa ia adalah_C(exchange.GetTicker)
, tidak_C(exchange.GetTicker())
.
function main(){
var ticker = _C(exchange.GetTicker)
// Adjust _C() function's 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 dengan parameter, apabila menggunakan_C(...)
untuk melakukan toleransi ralat:
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);
}
Ia juga boleh digunakan untuk penanganan toleransi ralat fungsi tersuai:
var test = function(a, b){
var time = new Date().getTime() / 1000
if(time % b == 3){
Log("Meet the criteria! ", "#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("Meet the criteria!", "#FF0000")
return True
Log("Retry!", "#FF0000")
return False
def main():
ret = _C(test, 1, 5)
Log(ret)
// C++ does not support this method for fault tolerance of custom functions.
_Cross(Arr1, Arr2)
mengembalikan bilangan tempoh persimpangan arrayarr1danarr2. nombor positif adalah tempoh kenaikan, dan nombor negatif adalah tempoh penurunan, dan 0 bermaksud sama dengan harga semasa. nilai parameter: pelbagai jenis nombor.
Anda boleh mensimulasikan satu set data untuk menguji fungsi_Cross(Arr1, 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));
}
Melihat data simulasi untuk pemerhatian
Arahan khusus:Fungsi terbina dalam _Analisis silang dan arahan
JSONParse(strJson)
, fungsi ini digunakan untuk menganalisis rentetan JSON. rentetan JSON yang mengandungi nombor besar boleh dianalisis dengan betul, dan nombor besar akan dianalisis ke dalam jenis rentetan. Sistem backtesting tidak menyokong fungsi ini.
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
}
Setiap rentetan mesej boleh berakhir dengan nilai RGB seperti:#ff0000
, yang mewakili warna latar depan yang akan dipaparkan. Jika ia dalam format seperti#ff0000112233
, enam bahagian belakang terakhir mewakili warna latar belakang.
function main() {
Log("Red", "#FF0000")
}
def main():
Log("Red", "#FF0000")
void main() {
Log("Red", "#FF0000");
}
Apabila bot berjalan, maklumat log dicatat dalam pangkalan data bot, yang menggunakansqlite3
fail pangkalan data terletak di dalam peranti dengan program docker, dan lokasi yang tepat fail adalah dalam kamus program docker (robot
contoh: fail pangkalan data bot dengan ID130350
berada dalam direktori../logs/storage/130350
(..
adalah kamus di mana pelabuhan darirobot
terletak), dan nama fail pangkalan data adalah130350.db3
.
Log dalam sistem backtest boleh dimuat turun dengan mengklik [Muat turun log] butang di sudut kanan bawah halaman backtest selepas backtest selesai.
Apabila anda perlu memindahkan bot ke docker pada pelayan lain, anda boleh memindahkan fail pangkalan data bot (fail pangkalan data dengan sambungan
Log(message)
bermaksud menyimpan mesej ke dalam senarai log. Nilai parameter:message
boleh menjadi apa-apa jenis.
Jika anda menambah watak@
selepas rentetan, mesej akan memasuki antrian push dan akan didorong ke akaun WeChat semasa platform FMZ Quant Trading, dan
Nota:
function main() {
Log("Hello FMZ Quant!@")
Sleep(1000 * 5)
// Add the string to #ff0000, print the log in red, and push the message
Log("Hello, #ff0000@")
}
def main():
Log("Hello FMZ Quant!@")
Sleep(1000 * 5)
Log("Hello, #ff0000@")
void main() {
Log("Hello FMZ Quant!@");
Sleep(1000 * 5);
Log("Hello, #ff0000@");
}
WebHookTekan:
Gunakan program perkhidmatan DEMO yang ditulis dalamGolang
:
package main
import (
"fmt"
"net/http"
)
func Handle (w http.ResponseWriter, r *http.Request) {
defer func() {
fmt.Println("req:", *r)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
SetWebHook
: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ
Selepas menjalankan program perkhidmatan, melaksanakan strategi dan tekan maklumat:
function main() {
Log("msg", "@")
}
def main():
Log("msg", "@")
void main() {
Log("msg", "@");
}
Menerima maklumat dorong, dan program perkhidmatan mencetak maklumat:
listen http://localhost:9090
req: {GET /data?data=Hello_FMZ HTTP/1.1 1 1 map[User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xx.x.xxxx.xxx Safari/537.36] Accept-Encoding:[gzip]] {} <nil> 0 [] false 1XX.XX.X.XX:9090 map[] map[] <nil> map[] XXX.XX.XXX.XX:4xxx2 /data?data=Hello_FMZ <nil> <nil> <nil> 0xc420056300}
Cetakbase64
imej dikodkanFungsiLog
menyokong mencetak imej yang dikodkan dalambase64
, bermula mereka dengan`
, dan berakhir dengan`
Contohnya:
function main() {
Log("`data:image/png;base64,AAAA`")
}
def main():
Log("`data:image/png;base64,AAAA`")
void main() {
Log("`data:image/png;base64,AAAA`");
}
Log
menyokong mencetakmatplotlib.pyplot
objek-objekPython
secara langsung, iaitu, selagi objek mengandungisavefig
kaedah, anda boleh menggunakanLog
untuk mencetak secara langsung, contohnya:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
Pertukaran bahasa automatik log cetakFungsiLog
menyokong pertukaran bahasa; apabila fungsi output teks, ia akan beralih ke bahasa yang sepadan secara automatik mengikut tetapan bahasa pada halaman platform. Sebagai contoh:
function main() {
Log("[trans]Chinese|abc[/trans]")
}
def main():
Log("[trans]Chinese|abc[/trans]")
void main() {
Log("[trans]Chinese|abc[/trans]");
}
LogProfit(Profit)
merakam nilai keuntungan, mencetak nilai keuntungan, dan melukis lengkung keuntungan mengikut nilai keuntungan.Keuntunganadalah jenis nombor.
Jika fungsi berakhir dengan watak&
, ia hanya boleh merealisasikan melukis carta keuntungan, dan tidak mencetak log keuntungan, seperti:LogProfit(10, '&')
.
LogProfitReset()
menghapuskan semua log keuntungan; anda boleh mengambil parameter nilai bilangan bulat untuk menentukan bilangan item yang disediakan.
function main() {
// Print 30 points on the income chart, then reset, and only retain the last 10 points
for(var i = 0; i < 30; i++) {
LogProfit(i)
Sleep(500)
}
LogProfitReset(10)
}
def main():
for i in range(30):
LogProfit(i)
Sleep(500)
LogProfitReset(10)
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i);
Sleep(500);
}
LogProfitReset(10);
}
LogStatus(Msg)
, maklumat tidak disimpan dalam senarai log, hanya maklumat status semasa bot dikemas kini; ia dipaparkan di atas log dan boleh dipanggil beberapa kali untuk mengemas kini status. Nilai parameter:Msg
boleh menjadi apa-apa jenis.
function main() {
LogStatus('This is a normal status prompt')
LogStatus('This is a status prompt in red font # ff0000')
LogStatus('This is a multi-line status message \n I am the second line')
}
def main():
LogStatus('This is a normal status prompt')
LogStatus('This is a status prompt in red font # ff0000')
LogStatus('This is a multi-line status message \nI am the second line')
void main() {
LogStatus("This is a normal status prompt");
LogStatus("This is a status prompt in red font # ff0000");
LogStatus("This is a multi-line status message \nI am the second line");
}
LogStatus(Msg)
menyokong percetakanbase64
gambar berkod, bermula dengan`
dan berakhir dengan`
, seperti:LogStatus("`data:image/png;base64,AAAA`")
.
LogStatus(Msg)
menyokong import langsungPython
...matplotlib.pyplot
objek, selagi objek mengandungisavefig
kaedah, anda boleh lulus dalam fungsiLogStatus(Msg)
, seperti:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
Contoh output data dalam bar status:
function main() {
var table = {type: 'table', title: 'Position Information', cols: ['Column1', 'Column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
// After the JSON order is serialized, add the character "`" on both sides, which is regarded as a complex message format (currently supporting tables)
LogStatus('`' + JSON.stringify(table) + '`')
// Table information can also appear in multiple lines
LogStatus('First line message\n`' + JSON.stringify(table) + '`\nThird line message')
// That supports multiple tables displayed at the same time, and that will be displayed in a group with TAB
LogStatus('`' + JSON.stringify([table, table]) + '`')
// You can also construct a button in the table, and the strategy uses "GetCommand" to receive the content of the cmd attribute
var table = {
type: 'table',
title: 'Position operation',
cols: ['Column1', 'Column2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'close position'}]
]
}
LogStatus('`' + JSON.stringify(table) + '`')
// Or create a separate button
LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'close position'}) + '`')
// You can customize the button style (button attribute of bootstrap)
LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'close position'}) + '`')
}
import json
def main():
table = {"type": "table", "title": "Position Information", "cols": ["Column1", "Column2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('First line message\n`' + json.dumps(table) + '`\nThird line message')
LogStatus('`' + json.dumps([table, table]) + '`')
table = {
"type" : "table",
"title" : "Position operation",
"cols" : ["Column1", "Column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close position"}]
]
}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "close position"}) + '`')
LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "close position"}) + '`')
void main() {
json table = R"({"type": "table", "title": "Position Information", "cols": ["Column1", "Column2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("First line message\n`" + table.dump() + "`\nThird line message");
json arr = R"([])"_json;
arr.push_back(table);
arr.push_back(table);
LogStatus("`" + arr.dump() + "`");
table = R"({
"type" : "table",
"title" : "Position operation",
"cols" : ["Column1", "Column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close position"}]
]
})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "close position"})"_json.dump() + "`");
LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "close position"})"_json.dump() + "`");
}
Tetapkan fungsi mematikan dan penerangan butang bar status:
function main() {
var table = {
type: "table",
title: "Test the disable and description functions of status bar buttons",
cols: ["Column1", "Column2", "Column3"],
rows: []
}
var button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
var button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true}
var button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false}
table.rows.push([button1, button2, button3])
LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "Test the disable and description functions of status bar buttons",
"cols": ["Column1", "Column2", "Column3"],
"rows": []
}
button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": True}
button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": False}
table["rows"].append([button1, button2, button3])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type": "table",
"title": "Test the disable and description functions of status bar buttons",
"cols": ["Column1", "Column2", "Column3"],
"rows": []
})"_json;
json button1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"})"_json;
json button2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true})"_json;
json button3 = R"({"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false})"_json;
json arr = R"([])"_json;
arr.push_back(button1);
arr.push_back(button2);
arr.push_back(button3);
table["rows"].push_back(arr);
LogStatus("`" + table.dump() + "`");
}
Tetapkan gaya butang bar status:
function main() {
var table = {
type: "table",
title: "status bar button style",
cols: ["default", "raw", "success", "information", "warning", "danger"],
rows: [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "raw"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "information"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
}
LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "status bar button style",
"cols": ["default", "raw", "success", "information", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "raw"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "information"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
}
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type": "table",
"title": "status bar button style",
"cols": ["default", "raw", "success", "information", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "raw"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "information"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
})"_json;
LogStatus("`" + table.dump() + "`");
}
Gabungkan fungsiGetCommand()
untuk membina fungsi interaktif butang bar status:
function test1() {
Log("Call a custom function")
}
function main() {
while (true) {
var table = {
type: 'table',
title: 'operation',
cols: ['Column1', 'Column2', 'Action'],
rows: [
['a', '1', {
'type': 'button',
'cmd': "CoverAll",
'name': 'close position'
}],
['b', '1', {
'type': 'button',
'cmd': 10,
'name': 'Send value'
}],
['c', '1', {
'type': 'button',
'cmd': _D(),
'name': 'Call a function'
}],
['d', '1', {
'type': 'button',
'cmd': 'test1',
'name': 'Call a custom function'
}]
]
}
LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')
var str_cmd = GetCommand()
if (str_cmd) {
Log("Received interactive data str_cmd:", "Types of:", typeof(str_cmd), "Value:", str_cmd)
if(str_cmd == "test1") {
test1()
}
}
Sleep(500)
}
}
import json
def test1():
Log("Call a custom function")
def main():
while True:
table = {
"type": "table",
"title": "Operation",
"cols": ["Column1", "Column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "close position"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send value"
}],
["c", "1", {
"type": "button",
"cmd": _D(),
"name": "Call a function"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Call a custom function"
}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
str_cmd = GetCommand()
if str_cmd:
Log("Received interactive data str_cmd", "Types:", type(str_cmd), "Value:", str_cmd)
if str_cmd == "test1":
test1()
Sleep(500)
void test1() {
Log("Call a custom function");
}
void main() {
while(true) {
json table = R"({
"type": "table",
"title": "Operation",
"cols": ["Column1", "Column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "close position"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send value"
}],
["c", "1", {
"type": "button",
"cmd": "",
"name": "Call a function"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Call a custom function"
}]
]
})"_json;
table["rows"][2][2]["cmd"] = _D();
LogStatus(_D(), "\n", "`" + table.dump() + "`");
auto str_cmd = GetCommand();
if(str_cmd != "") {
Log("Received interactive data str_cmd", "Type:", typeid(str_cmd).name(), "Value:", str_cmd);
if(str_cmd == "test1") {
test1();
}
}
Sleep(500);
}
}
Apabila membina butang bar status untuk interaksi, data input juga disokong, dan arahan interaktif akhirnya ditangkap olehGetCommand()
fungsi.
Untuk menambahinput
item kepada struktur data kawalan butang dalam bar status, contohnya, menambah"input": {"name": "Number of opening orders", "type": "number", "defValue": 1}
kepada{"type": "button", "cmd": "open", "name": "open position"}
, anda boleh membuat butang muncul kotak dialog dengan kawalan kotak input apabila diklik (nilai lalai dalam kotak input adalah 1, yang ditetapkan oleh data 111
dalam kotak input dan mengklik GetCommand
fungsi akan menangkap mesej:open:111
.
function main() {
var tbl = {
type: "table",
title: "operation",
cols: ["column 1", "column2"],
rows: [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of opening positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
while (true) {
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
}
Sleep(1000)
}
}
import json
def main():
tbl = {
"type": "table",
"title": "operation",
"cols": ["column 1", "column 2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of opening positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
while True:
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
Sleep(1000)
void main() {
json tbl = R"({
"type": "table",
"title": "operation",
"cols": ["column 1", "column 2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of opening positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
})"_json;
LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
while(true) {
auto cmd = GetCommand();
if(cmd != "") {
Log("cmd:", cmd);
}
Sleep(1000);
}
}
Gabungkan sel-sel dalam jadual yang digambar olehLogStatus(Msg)
fungsi:
Penggabungan mendatar
function main() {
var table = {
type: 'table',
title: 'position operation',
cols: ['Column1', 'Column2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'close position'}]
]
}
var ticker = exchange.GetTicker()
// Add a row of data, merge the first and second cells, and output the ticker variable in the merged cell
table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"])
LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
table = {
"type" : "table",
"title" : "position operation",
"cols" : ["Column1", "Column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close position"}]
]
}
ticker = exchange.GetTicker()
table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "position operation",
"cols" : ["Column1", "Column2", "Action"],
"rows" : [