oparameter is set toký hiệuorký hiệu, thecầ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ốalgocũ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.gbktext.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 ((()

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()

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()

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 OScủa máy tính Apple:

GetOS:darwin/amd64

darwinlà tên củaMac OS system.

MD5 ((String)

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 ((...)

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ợSQLiteHệ thống trong cơ sở dữ liệu bot lưu bảng bao gồm:kvdb, cfg, log, profitchartChú ý: 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);
}
  • Các hoạt động thêm, xóa, truy vấn và sửa đổi được ghi trong 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("")
    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 (()

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)

EventLoop(timeout), trả về sau khi có bất kỳwebsocketcó thể đọc hoặcexchange.Go, HttpQuery_Govà 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ácEventhà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ủaEventLooptrong mã sẽ khởi động cơ chế nghe sự kiện.EventLoopCá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ếuEventLoopkhô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.EventLoopchức năng sẽ không ảnh hưởng đến hàng đợi cache củawebsockettại hệ thống cơ bản, cũng không phải là bộ nhớ cache củaexchange.Govà 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.EventLoophàm trả về, không có sự kiện trả về sẽ được tạo ra trongEventLoop function.

Mục đích chính củaEventLoopchứ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.EventLoopfunction trả về một sự kiện, bạn chỉ cần đi qua tất cả các nguồn dữ liệu.websocketkết nối và các đối tượng được tạo ra bởiexchange.GoBạ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);
}

Các chức năng tích hợp

_G(K, V)

_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àKVmỗ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.Kphải là một chuỗi, mà không phải là chữ cái nhạy cảm.Vcó thể là bất kỳJSONnộ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ềIDcủ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_Gchứ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 ((Thức thời gian, Fmt)

_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ố:Timestamplà một loại số, trong millisecond.Fmtlà kiểu chuỗi;Fmtmặ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()trongPythonchiế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 trongJavaScriptC ++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ủa1574993606000vớ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, chính xác)

_N(Num, Precision), một số dấu phẩy động được định dạng. Giá trị tham số:Numcó kiểu số;Precisionlà 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.1415và 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(...)

_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ượngfunctiontrả về giá trị null khi gọi hàm tham chiếu hoặcfalsesẽ 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_CKhoả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)

_Cross(Arr1, Arr2)trả về số thời gian chéo của mảngarr1arr2. 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));
}

img

Hình dung dữ liệu mô phỏng để quan sát

img

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)

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àu tùy chỉnh

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");
}

Thông tin nhật ký

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ụngsqlite3cơ 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 (robotví dụ: tệp cơ sở dữ liệu bot với ID130350là 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 db3) đến máy chủ mục tiêu chuyển giao, và đặt tên tệp theo ID bot tương ứng trên nền tảng. Bằng cách này, tất cả thông tin nhật ký của bot trước sẽ không bị mất do di chuyển sang thiết bị mới.

Lịch sử

Log(message)nghĩa là lưu một tin nhắn vào danh sách nhật ký. Giá trị tham số:messagecó 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à Email, TelegramWebHook trong Push settings sẽ được đẩy (mở các trang củaBảng điều khiển, Tài khoảnCài đặt nhấnbằng các mệnh lệnh để thiết lập ràng buộc).

Lưu ý:

  • Push không được hỗ trợ trong Debug Tool.
  • Đẩy không được hỗ trợ trong Backtest System.
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}

inbase64hình ảnh mã hóaChức năngLoghỗ 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`");
}

Loghỗ trợ inmatplotlib.pyplotcác đối tượng củaPythontrực tiếp, tức là, miễn là các đối tượng chứasavefigphươ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ăngLoghỗ 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 ((Lợi nhuận)

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 (()

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)

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ố:Msgcó 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ợ inbase64hì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ứasavefigPhươ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:

img

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:

img

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ộtinputmụ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 defValue), và bạn có thể nhập dữ liệu để gửi bằng lệnh nút. Ví dụ: khi chạy mã thử nghiệm sau, sau khi nhấp vào nút Open position, một hộp thoại với hộp đầu vào sẽ bật lên. Sau khi nhập111trong hộp nhập và nhấp vào OK,GetCommandchứ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" : [