oparameter is set to
ký hiệuor
ký hiệu, the
cần tham số key```.
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
}
Các thông sốalgo
cũng hỗ trợ mã hóa và giải mã các chuỗi, chẳng hạn nhưtext.encoder.utf8
, text.decoder.utf8
, text.encoder.gbk
vàtext.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()
trả về dấu thời gian cấp nano giây; nếu bạn cần lấy dấu thời gian cấp millisecond, bạn có thể sử dụng mã sau:
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
Unix()
trả về dấu thời gian trong giây.
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
GetOS()
trả về thông tin về hệ thống nơi docker nằm.
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
Lưu trữ đầu ra của docker chạy bởiMac OS
của máy tính Apple:
GetOS:darwin/amd64
darwin
là tên củaMac OS
system.
MD5(String)
; giá trị tham số: kiểu chuỗi.
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
Log output:
MD5 5eb63bbbe01eeed093cb22bb8f5acdc3
DBExec()
, giá trị tham số của nó có thể là chuỗi, số hoặc boolean, null và các loại khác; trả về giá trị: đối tượng với kết quả thực thi trong ngôn ngữ SQLite.DBExec()
, chức năng giao diện của cơ sở dữ liệu, thông qua các tham số truyền, có thể chạy cơ sở dữ liệu của bot (SQLite database). Nó nhận ra việc thêm, xóa, truy vấn và sửa đổi các hoạt động trên cơ sở dữ liệu bot, hỗ trợSQLite
Hệ thống trong cơ sở dữ liệu bot lưu bảng bao gồm:kvdb
, cfg
, log
, profit
vàchart
Chú ý: các chức năngDBExec()
chỉ hỗ trợ robot thực sự.
Hỗ trợ cơ sở dữ liệu bộ nhớ
Đối với các thông số chức năngDBExec
, nếusqltuyên bố bắt đầu với:
, các hoạt động trong cơ sở dữ liệu bộ nhớ sẽ nhanh hơn mà không cần ghi các tệp. Nó phù hợp với các hoạt động cơ sở dữ liệu mà không cần lưu trữ lâu dài, ví dụ:
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;"));
}
Tạo bảng
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()
, trả về một UUID độc đáo 32 bit, chức năng này chỉ có sẵn cho các bot thực sự.
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)
, trả về sau khi có bất kỳwebsocket
có thể đọc hoặcexchange.Go
, HttpQuery_Go
và các nhiệm vụ đồng thời khác được hoàn thành.timeout
được thiết lập thành 0, chờ một sự kiện xảy ra trước khi trả về. Nếu lớn hơn 0, thiết lập thời gian chờ sự kiện. Nếu nhỏ hơn 0, trả về sự kiện mới nhất ngay lập tức. Nếu đối tượng trả về không phải lànull
, cácEvent
hàm chứa trong nội dung được trả về là loại sự kiện được kích hoạt.
Cuộc gọi đầu tiên củaEventLoop
trong mã sẽ khởi động cơ chế nghe sự kiện.EventLoop
Các cấu trúc hàng đợi được đóng gói bởi hệ thống cơ bản sẽ lưu trữ tối đa 500 cuộc gọi lại sự kiện. NếuEventLoop
không được gọi kịp thời để loại bỏ trong quá trình thực thi chương trình, các cuộc gọi trở lại sau đó ngoài bộ nhớ cache 500 sẽ bị mất.EventLoop
chức năng sẽ không ảnh hưởng đến hàng đợi cache củawebsocket
tại hệ thống cơ bản, cũng không phải là bộ nhớ cache củaexchange.Go
và các chức năng đồng thời khác. Đối với các bộ nhớ cache này, bạn vẫn cần sử dụng các phương pháp riêng của họ để lấy dữ liệu.EventLoop
hàm trả về, không có sự kiện trả về sẽ được tạo ra trongEventLoop
function.
Mục đích chính củaEventLoop
chức năng là để thông báo cho lớp chiến lược rằng hệ thống cơ bản đã nhận được dữ liệu mạng mới.EventLoop
function trả về một sự kiện, bạn chỉ cần đi qua tất cả các nguồn dữ liệu.websocket
kết nối và các đối tượng được tạo ra bởiexchange.Go
Bạn có thể tham khảo một thiết kế thư viện lớp nguồn mở:liên kết thư viện lớp.
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)
, với chức năng của một từ điển toàn cầu có thể được lưu, hỗ trợ cả backtest và bot. Sau khi backtest, dữ liệu được lưu sẽ được xóa.
Cấu trúc dữ liệu làKV
mỗi bot có một cơ sở dữ liệu riêng biệt. nó sẽ luôn tồn tại sau khi khởi động lại hoặc khi docker thoát ra.K
phải là một chuỗi, mà không phải là chữ cái nhạy cảm.V
có thể là bất kỳJSON
nội dung có thể phân loại._G()
được gọi và không có tham số được truyền trong hoạt động bot, các chức năng_G()
trả vềID
của robot hiện tại.
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();
}
Lưu ý:
Khi sử dụng_G
chức năng để lưu dữ liệu, nó nên được sử dụng hợp lý theo bộ nhớ và không gian đĩa cứng của thiết bị phần cứng, và không nên bị lạm dụng.quá tải bộ nhớ problem.
_D(Timestamp, Fmt)
, trả về các chuỗi thời gian tương ứng của dấu thời gian được chỉ định. Giá trị tham số:Timestamp
là một loại số, trong millisecond.Fmt
là kiểu chuỗi;Fmt
mặc định là:yyyy-MM-dd hh:mm:ss
; trả về giá trị: kiểu chuỗi.
Nó trả về chuỗi dấu thời gian được chỉ định và trả về thời gian hiện tại mà không vượt qua bất kỳ thông số nào; ví dụ:_D()
hoặc_D(1478570053241)
, trong đó định dạng mặc định làyyyy-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);
}
Lưu ý:
Khi sử dụng_D()
trongPython
chiến lược, chúng ta cần phải chú ý rằng các thông số được chuyển vào là dấu thời gian trong giây (các dấu thời gian ở mức độ millisecond trongJavaScript
vàC ++
các chiến lược, và 1 giây = 1000 mili giây).
Trong bot, khi sử dụng chức năng_D()
để phân tích một chuỗi thời gian với một dấu thời gian có thể đọc, bạn cần phải chú ý đến múi giờ trong hệ điều hành của chương trình docker._D()
phân tích một dấu thời gian như một chuỗi thời gian có thể đọc dựa trên thời gian của hệ thống dock.
Ví dụ, phân tích một dấu thời gian của1574993606000
với mã:
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)
, một số dấu phẩy động được định dạng. Giá trị tham số:Num
có kiểu số;Precision
là kiểu số nguyên. Trả về giá trị: kiểu số.
Ví dụ:_N(3.1415, 2)
sẽ xóa giá trị sau hai vị trí thập phân của3.1415
và quay lại3.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);
}
Nếu bạn cần thay đổi các chữ số N bên trái của dấu thập phân thành 0, bạn có thể viết:
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…)
là một chức năng thử lại, được sử dụng cho khả năng chịu lỗi của các giao diện về việc thu thập thông tin thị trường và mua lại các đơn đặt hàng chưa hoàn thành, v.v.
Giao diện sẽ gọi chức năng được chỉ định liên tục cho đến khi nó trả về thành công (đối tượngfunction
trả về giá trị null khi gọi hàm tham chiếu hoặcfalse
sẽ thử lại cuộc gọi). Ví dụ,_ C(exchange. GetTicker)
, khoảng thời gian thử lại mặc định là 3 giây, có thể gọi chức năng_CDelay (...)
để thiết lập khoảng thời gian thử lại, chẳng hạn như_CDelay (1000)
nghĩa là chức năng thay đổi_C
Khoảng thời gian thử lại 1 giây.
Đối với các chức năng sau:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPosition()
Tất cả chúng đều có thể được gọi để làm dung nạp lỗi theo chức năng_C(...)
. Chức năng_C(function, args...)
không giới hạn trong khả năng chịu lỗi của các chức năng được liệt kê ở trên.function
được trích dẫn không được gọi, và chú ý rằng nó là_C(exchange.GetTicker)
, không_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);
}
Đối với các hàm có tham số, khi sử dụng_C(...)
để làm dung nạp lỗi:
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);
}
Nó cũng có thể được sử dụng để xử lý dung nạp lỗi tùy chỉnh:
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)
trả về số thời gian chéo của mảngarr1vàarr2. Một số dương là thời gian tăng, và một số âm là thời gian giảm, và 0 có nghĩa là giống như giá hiện tại. Giá trị tham số: mảng loại số.
Bạn có thể mô phỏng một bộ dữ liệu để kiểm tra các chức năng_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));
}
Hình dung dữ liệu mô phỏng để quan sát
Hướng dẫn cụ thể:Chức năng tích hợp _ Phân tích chéo và hướng dẫn
JSONParse(strJson)
, hàm được sử dụng để phân tích chuỗi JSON. Các chuỗi JSON có chứa số lớn có thể được phân tích chính xác, và số lớn sẽ được phân tích thành các loại chuỗi. Hệ thống backtesting không hỗ trợ chức năng này.
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
}
Mỗi chuỗi tin nhắn có thể kết thúc với một giá trị RGB như:#ff0000
, đại diện cho màu tiền cảnh được hiển thị. Nếu nó ở định dạng như#ff0000112233
, sáu mặt sau cuối cùng đại diện cho màu nền.
function main() {
Log("Red", "#FF0000")
}
def main():
Log("Red", "#FF0000")
void main() {
Log("Red", "#FF0000");
}
Khi bot đang chạy, thông tin nhật ký được ghi lại trong cơ sở dữ liệu của bot, sử dụngsqlite3
cơ sở dữ liệu. các tập tin cơ sở dữ liệu tìm thấy trong thiết bị với chương trình docker, và vị trí chính xác của các tập tin là trong từ điển của chương trình docker (robot
ví dụ: tệp cơ sở dữ liệu bot với ID130350
là trong thư mục../logs/storage/130350
(..
là từ điển mà docker củarobot
được đặt), và tên tệp cơ sở dữ liệu là130350.db3
.
Các nhật ký trong hệ thống backtest có thể được tải xuống bằng cách nhấp vào [Đăng ký tải xuống] nút ở góc dưới bên phải của trang backtest sau khi kết thúc backtest.
Khi bạn cần chuyển bot đến một máy chủ docker trên một máy chủ khác, bạn có thể di chuyển các tệp cơ sở dữ liệu của bot (tệp cơ sở dữ liệu với phần mở rộng
Log(message)
nghĩa là lưu một tin nhắn vào danh sách nhật ký. Giá trị tham số:message
có thể là bất kỳ loại nào.
Nếu bạn thêm ký tự@
sau chuỗi, tin nhắn sẽ nhập vào hàng đợi đẩy và được đẩy đến tài khoản WeChat hiện tại của nền tảng FMZ Quant Trading, và
Lưu ý:
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@");
}
WebHookĐẩy:
Sử dụng chương trình dịch vụ DEMO được viết trongGolang
:
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)
}
ĐặtWebHook
: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ
Sau khi chạy chương trình dịch vụ, thực hiện chiến lược và đẩy thông tin:
function main() {
Log("msg", "@")
}
def main():
Log("msg", "@")
void main() {
Log("msg", "@");
}
Nhận thông tin đẩy, và chương trình dịch vụ in thông tin:
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}
inbase64
hình ảnh mã hóaChức năngLog
hỗ trợ in các hình ảnh được mã hóa trongbase64
, bắt đầu với`
, và kết thúc với`
Ví dụ:
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
hỗ trợ inmatplotlib.pyplot
các đối tượng củaPython
trực tiếp, tức là, miễn là các đối tượng chứasavefig
phương pháp, bạn có thể sử dụngLog
để in trực tiếp, ví dụ:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
Chuyển ngôn ngữ tự động của nhật ký inChức năngLog
hỗ trợ chuyển đổi ngôn ngữ; khi chức năng phát ra văn bản, nó sẽ tự động chuyển sang ngôn ngữ tương ứng theo cài đặt ngôn ngữ trên trang nền tảng. Ví dụ:
function main() {
Log("[trans]Chinese|abc[/trans]")
}
def main():
Log("[trans]Chinese|abc[/trans]")
void main() {
Log("[trans]Chinese|abc[/trans]");
}
LogProfit(Profit)
ghi lại giá trị lợi nhuận, in giá trị lợi nhuận và vẽ đường cong lợi nhuận theo giá trị lợi nhuận.Lợi nhuậnlà kiểu số.
Nếu hàm kết thúc với ký tự&
, nó chỉ có thể thực hiện vẽ biểu đồ lợi nhuận, và không in nhật ký lợi nhuận, chẳng hạn như:LogProfit(10, '&')
.
LogProfitReset()
xóa tất cả các nhật ký lợi nhuận; bạn có thể lấy một tham số giá trị số nguyên để chỉ định số lượng các mục được dành riêng.
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)
, thông tin không được lưu trong danh sách nhật ký, chỉ thông tin trạng thái hiện tại của bot được cập nhật; nó được hiển thị trên nhật ký và có thể được gọi nhiều lần để cập nhật trạng thái. Giá trị tham số:Msg
có thể là bất kỳ loại nào.
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)
hỗ trợ inbase64
hình ảnh mã hóa, bắt đầu với`
và kết thúc với`
, như:LogStatus("`data:image/png;base64,AAAA`")
.
LogStatus(Msg)
hỗ trợ nhập khẩu trực tiếpPython
Ừ.matplotlib.pyplot
đối tượng, miễn là đối tượng chứasavefig
Phương pháp, bạn có thể truyền vào các chức năngLogStatus(Msg)
, như:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
Ví dụ đầu ra dữ liệu trong thanh trạng thái:
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() + "`");
}
Thiết lập các chức năng vô hiệu hóa và mô tả của các nút thanh trạng thái:
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() + "`");
}
Đặt kiểu của các nút thanh trạng thái:
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() + "`");
}
Kết hợp chức năngGetCommand()
để xây dựng chức năng tương tác của các nút thanh trạng thái:
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);
}
}
Khi xây dựng một nút thanh trạng thái cho tương tác, dữ liệu đầu vào cũng được hỗ trợ, và lệnh tương tác cuối cùng được thu thập bởi cácGetCommand()
chức năng.
Để thêm mộtinput
mục vào cấu trúc dữ liệu của một nút điều khiển trong thanh trạng thái, ví dụ: thêm"input": {"name": "Number of opening orders", "type": "number", "defValue": 1}
đến{"type": "button", "cmd": "open", "name": "open position"}
, bạn có thể làm cho nút bật lên một hộp thoại với một kiểm soát hộp đầu vào khi nhấp (Giá mặc định trong hộp đầu vào là 1, được đặt bởi dữ liệu 111
trong hộp nhập và nhấp vào GetCommand
chức năng sẽ thu thập thông điệp: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);
}
}
Kết hợp các ô trong bảng vẽ bởiLogStatus(Msg)
chức năng:
Sự sáp nhập theo chiều ngang
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" : [