O recurso está a ser carregado... Carregamento...

Registo

Registo

Registros de saída.

Registo (...msgs)

O parâmetromsgé o conteúdo da saída e o parâmetromsgpodem ser passadas mais de uma. msg Falso string, número, bool, objeto, matriz, qualquer tipo suportado pelo sistema, como zero.

function main() {
    Log("msg1", "msg2", "msg3")
}
def main():
    Log("msg1", "msg2", "msg3")
void main() {
    Log("msg1", "msg2", "msg3");
}

MúltiplosmsgOs parâmetros podem ser transmitidos:

function main() {
    Log("Hello, FMZ Quant!@")
    Sleep(1000 * 5)
    // Add #ff0000 to the string to 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@");
}

Ele suporta a definição da cor da mensagem de saída, se usarmos a definição de cor e empurrar ao mesmo tempo, precisamos definir a cor primeiro e usar@Caracter para definir o último empurrão.

function main() {
    Log("`data:image/png;base64,AAAA`")
}
def main():
    Log("`data:image/png;base64,AAAA`")
void main() {
    Log("`data:image/png;base64,AAAA`");
}

OLog()Função de impressãobase64imagens codificadas, começando com`e termina com`, por exemplo:

import matplotlib.pyplot as plt 
def main(): 
    plt.plot([3,6,2,4,7,1]) 
    Log(plt)

OLog()função suporta a impressão directa dePythonÉ...matplotlib.pyplotO objecto contém osavefigO método de impressão pode ser impresso diretamente utilizando oLogfunção, por exemplo:

function main() {
    Log("[trans]中文|abc[/trans]")
}
def main():
    Log("[trans]中文|abc[/trans]")
void main() {
    Log("[trans]中文|abc[/trans]");
}

OLog()A função suporta a comutação de idiomas.Log()A função produz texto que irá mudar para a língua correspondente automaticamente com base na configuração da língua na página da plataforma, por exemplo:

OLog()A função produz uma mensagem de log na área de log do sistema de negociação ao vivo ou backtesting, e o log é salvo na base de dados de negociação ao vivo quando a negociação ao vivo está em execução.Log()função produz uma mensagem de log terminando com o@Push para o endereço de e-mail, endereço WebHook, etc configurado noPush ConfiguraçõesA transferência de mensagens não é suportada porFerramentas de depuraçãoHá um limite de frequência para o push de mensagens. As regras de restrição específicas são as seguintes: dentro de um ciclo de 20 segundos de uma negociação ao vivo, apenas a última mensagem de push será retida e empurrada, e outras mensagens serão filtradas e não empurradas (a saída de log de push pela função Log será impressa e exibida normalmente na área de log). ParaWebHookPush, você pode usar o programa de serviço escrito porGolang:

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

ConjuntoWebHookemPush Configurações: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ- Não. Depois de executar o escritoGolangprograma de serviço, começamos a executar a estratégia de negociação ao vivo, o seguinte é a estratégia escrita emJavaScriptA estratégia é executada através daLog()função e empurrando a mensagem:

function main() {
    Log("msg", "@")
}

Um programa de serviço escrito noGolangA linguagem recebe o push e o programa de serviço imprime a mensagem:

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

Não, não, não, não, não.

LogProfit

Registre o valor de lucro e lucro, imprima o valor de lucro e lucro e trace a curva de retorno com base no valor de lucro e lucro.

LogProfit (lucro) LogProfit ((lucro,...args)

O parâmetroprofitsão os dados relativos às receitas, que são dados pelo algoritmo de conceção e pelo cálculo da estratégia. lucro verdade Número Parâmetro alargado para a saída de informações acessórias para o registo de receitas,argOs parâmetros podem ser transmitidos para mais de um. arg Falso string, número, bool, objeto, matriz, qualquer tipo suportado pelo sistema, como zero.

function main() {
    // Print 30 points on the earnings chart
    for(var i = 0; i < 30; i++) {
        LogProfit(i, '&')
        Sleep(500)
    }
}
def main():
    for i in range(30):
        LogProfit(i, '&')
        Sleep(500)
void main() {
    for(int i = 0; i < 30; i++) {
        LogProfit(i, '&');
        Sleep(500);
    }
}

OLogProfitfunção, se terminar com o caractere&, elabora apenas o gráfico de receitas e não imprime o registo de receitas.

Não, não, não, não.

LogProfitReset

Limpa todos os registos de receitas, gráficos de receitas.

LogProfitReset (em inglês) LogProfitReset (remain)

OremainO parâmetro é utilizado para especificar o número de entradas de registo (valor inteiro) a manter. permanecer Falso Número

function main() {
    // Print 30 points on the revenue chart, then reset and keep only 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);
}

Não, não, não, não.

LogStatus

Informações de saída na barra de estado do sistema de backtesting ou página de negociação em tempo real.

LogStatus ((...msgs)

O parâmetromsgé o conteúdo da saída e o parâmetromsgpodem ser passadas mais de uma. msg Falso string, número, bool, objeto, matriz, qualquer tipo suportado pelo sistema, como zero.

function main() {
    LogStatus('This is a general status alert')
    LogStatus('This is a status alert in red font #ff0000')
    LogStatus('This is a multi-line status message \n I am the second line')
}
def main():
    LogStatus('This is a general status alert')
    LogStatus('This is a status alert in red font #ff0000')
    LogStatus('This is a multi-line status message \n I am the second line')
void main() {
    LogStatus("This is a general status alert");
    LogStatus("This is a status alert in red font #ff0000");
    LogStatus("This is a multi-line status message \n I am the second line");
}

Suporta a definição da cor do conteúdo de saída:

function main() {
    var table = {type: 'table', title: 'Position information', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    // JSON serialization with the ` character on both sides, as a complex message format (support tables currently)
    LogStatus('`' + JSON.stringify(table) + '`')                    
    // Table information can also appear in multiple rows
    LogStatus('First line of message\n`' + JSON.stringify(table) + '`\n third line of message')
    // It supports multiple tables at the same time, will be displayed in a group with TAB
    LogStatus('`' + JSON.stringify([table, table]) + '`')
    
    // You can also construct a button in the form, and use the GetCommand strategy to receive the contents of the cmd attribute                                
    var table = { 
        type: 'table', 
        title: 'Position operations', 
        cols: ['Column 1', 'Column 2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}]
        ]
    }
    LogStatus('`' + JSON.stringify(table) + '`') 
    // Or construct a separate button
    LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`') 
    // Customizable button style (bootstrap's button attribute)
    LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`')
}
import json
def main():
    table = {"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('First line of message\n`' + json.dumps(table) + '`\n third line of message')
    LogStatus('`' + json.dumps([table, table]) + '`')            

    table = {
        "type" : "table", 
        "title" : "Position operations", 
        "cols" : ["Column 1", "Column 2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
        ] 
    }
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "Close out positions"}) + '`')
    LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"}) + '`')
void main() {
    json table = R"({"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("First line of message\n`" + table.dump() + "`\n third line of message");
    json arr = R"([])"_json;
    arr.push_back(table);
    arr.push_back(table);
    LogStatus("`" + arr.dump() + "`");            

    table = R"({
        "type" : "table", 
        "title" : "Position operations", 
        "cols" : ["Column 1", "Column 2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
        ] 
    })"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
    LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
}

Exemplo de saída de dados na barra de estado:

function main() {
    var table = {
        type: "table",
        title: "status bar button style",
        cols: ["default", "original", "success", "info", "warning", "danger"], 
        rows: [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
                {"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", "original", "success", "info", "warning", "danger"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
                {"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", "original", "success", "info", "warning", "danger"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
            ]
        ]
    })"_json;
    LogStatus("`" + table.dump() + "`");
}

Suporta o design de controles de botões na barra de status (estrutura de botões antiga):

function main() {
    var table = {
        type: "table",
        title: "Status bar button disable, description function test",
        cols: ["Column 1", "Column 2", "Column 3"], 
        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 enable", "disabled": false}
    table.rows.push([button1, button2, button3])
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "Status bar button disable, description function test",
        "cols": ["Column 1", "Column 2", "Column 3"], 
        "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 enable", "disabled": False}
    table["rows"].append([button1, button2, button3])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "Status bar button disable, description function test",
        "cols": ["Column 1", "Column 2", "Column 3"], 
        "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 enable", "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() + "`");
}

Configure a função de descrição desativada do botão da barra de estado (estrutura do botão antigo):

function test1() {
    Log("Calling custom functions")
}            

function main() {
    while (true) {
        var table = {
            type: 'table',
            title: 'operation',
            cols: ['column1', 'column2', 'Action'],
            rows: [
                ['a', '1', {
                    'type': 'button',                       
                    'cmd': "CoverAll",                      
                    'name': 'Close out positions'                           
                }],
                ['b', '1', {
                    'type': 'button',
                    'cmd': 10,                              
                    'name': 'Send values'
                }],
                ['c', '1', {
                    'type': 'button',
                    'cmd': _D(),                          
                    'name': 'Calling functions'
                }],
                ['d', '1', {
                    'type': 'button',
                    'cmd': 'test1',       
                    'name': 'Calling custom functions'
                }]
            ]
        }
        LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')            

        var str_cmd = GetCommand()
        if (str_cmd) {
            Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd)
            if(str_cmd == "test1") {
                test1()
            }
        }            

        Sleep(500)
    }
}
import json
def test1():
    Log("Calling custom functions")            

def main():
    while True:
        table = {
            "type": "table", 
            "title": "operation", 
            "cols": ["column1", "column2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "Close out positions"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "Send values" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": _D(),
                    "name": "Calling functions" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "Calling custom functions" 
                }]
            ]
        }            

        LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
        str_cmd = GetCommand()
        if str_cmd:
            Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd)
            if str_cmd == "test1":
                test1()
        Sleep(500)
void test1() {
    Log("Calling custom functions");
}            

void main() {
    while(true) {
        json table = R"({
            "type": "table", 
            "title": "operation", 
            "cols": ["column1", "column2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "Close out positions"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "Send values" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": "",
                    "name": "Calling functions" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "Calling custom functions" 
                }]
            ]
        })"_json;
        table["rows"][2][2]["cmd"] = _D();
        LogStatus(_D(), "\n", "`" + table.dump() + "`");
        auto str_cmd = GetCommand();
        if(str_cmd != "") {
            Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd);
            if(str_cmd == "test1") {
                test1();
            }
        }
        Sleep(500);
    }
}

Em combinação com oGetCommand()função, construir a função de interação do botão da barra de estado (estrutura do botão antigo):

function main() {
    var tbl = {
        type: "table",
        title: "operation",
        cols: ["column1", "column2"],
        rows: [
            ["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open 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": ["column1", "column2"],
        "rows": [
            ["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open 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": ["column1", "column2"],
        "rows": [
            ["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open 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);
    }
}

Os dados de entrada também são suportados ao construir botões de barra de estado para interação, e os comandos de interação são capturados peloGetCommand()adicionarinputelementos (estrutura de botão antigo) para a estrutura de dados do comando do botão na barra de status, por exemplo, adicionando"input": {"name": "number of open positions", "type": "number", "defValue": 1}para{"type": "button", "cmd": "open", "name": "open position"}fará com que apareça um popup com um controle de caixa de entrada quando o botão for clicado (o valor padrão na caixa de entrada é 1, que é os dados definidos pordefValuePor exemplo, quando o seguinte código de teste é executado, depois de clicar no botão "open position", uma janela pop-up com uma caixa de entrada aparece.GetCommand()A função irá então capturar a mensagem:open:111.

function main() {
    var tbl = {
        type: "table",
        title: "Demonstrate grouping button control",
        cols: ["operation"],
        rows: []
    }

    // Creating a grouping button control structure
    var groupBtn = {
        type: "button",
        cmd: "open",
        name: "open positions",
        group: [
            {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
            {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
            {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
            {"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
        ]
    }

    // test button 1
    var testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
    var testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}

    // Add groupBtn to tbl
    tbl.rows.push([groupBtn])
    // It supports multiple buttons in a cell of a status bar table, i.e. the data in a cell is an array of button structures: [testBtn1, testBtn2].
    tbl.rows.push([[testBtn1, testBtn2]])

    while (true) {
        LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + JSON.stringify(groupBtn) + "`")
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)
        }
        Sleep(5000)
    }
}
import json

def main():
    tbl = {
        "type": "table",
        "title": "Demonstrate grouping button control",
        "cols": ["operation"],
        "rows": []
    }

    groupBtn = {
        "type": "button",
        "cmd": "open",
        "name": "open positions",
        "group": [
            {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
            {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
            {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
            {"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": True}
        ]
    }

    testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
    testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}

    tbl["rows"].append([groupBtn])
    tbl["rows"].append([[testBtn1, testBtn2]])

    while True:
        LogStatus("`" + json.dumps(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + json.dumps(groupBtn) + "`")
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
        Sleep(5000)
void main() {
    json tbl = R"({
        "type": "table", 
        "title": "Demonstrate grouping button control", 
        "cols": ["operation"],
        "rows": []
    })"_json;

    json groupBtn = R"({
        "type": "button", 
        "name": "open positions", 
        "cmd": "open", 
        "group": [
            {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
            {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
            {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
            {"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
    ]})"_json;

    json testBtn1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."})"_json;
    json testBtn2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}})"_json;
    
    tbl["rows"].push_back({groupBtn});
    tbl["rows"].push_back({{testBtn1, testBtn2}});
    
    while(true) {
        LogStatus("`" + tbl.dump() + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + groupBtn.dump() + "`");
        auto cmd = GetCommand();
        if(cmd != "") {
            Log("cmd:", cmd);
        }
        Sleep(5000);
    }
}

Suporta controles de botões agrupados (estrutura de botões antiga), funcionalmente consistente combotões da barra de estado que suportam a entrada de dadosOs comandos interativos são finalmente capturados peloGetCommand()A diferença é que com o"group"configuração de campo, quando o botão é clicado para desencadear a interação, o diálogo que aparece na página contém um conjunto degrupode controles de entrada configurados para inserir um grupo de dados de uma só vez. Alguns pontos a observar sobre o"group"campo na estrutura do comando do botão da barra de estado e do comando do botão do grupo:

  • OtypePropriedade em grupo suporta apenas os seguintes quatro tipos, e odefValueproperty é o valor padrão. selected: Um comando de caixa suspensa que utiliza o|símbolo para separar cada opção numa caixa suspensa conforme definida. número: controlo numérico da caixa de entrada. string: controlo da caixa de entrada de string. boolean: controlo da caixa de selecção, verificado para (boolean) true, não verificado para (boolean) false.
  • Controles das definições de dependência de suporte de entrada interativo: Por exemplo, no seguinte exemplo:"name": "tradePrice@orderType==1"A definição, o que faz ocomércioPriceO controlo de entrada só está disponível quando oordem TipoO controlo "drop-down" é selecionado comoOrdem pendente.
  • Suporte de nome de controle bilíngue para entradas interativas For example, in the following example: description : descreve o modo de ordem type setting, use|símbolos para separar o conteúdo da descrição em chinês e em inglês.
  • name, descriptionem grupo ename, descriptionna estrutura do botão não têm as mesmas definições, embora tenham os mesmos nomes de campo. A definição denameA definição de grupo também é diferente da definição denameem entrada.
  • Quando o comando do botão de grupo é acionado, o conteúdo da interação é enviado no formato do valor do campo cmd do botão e dos dados associados ao campo do grupo, como a saída doLog("cmd:", cmd)Declaração no seguinte exemplo de ensaio:cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}, ou seja, o que é devolvido peloGetCommand()Função quando ocorre uma interação:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}.
  • OtypePropriedade do comando do botão suporta apenas:"button"- Não. Os comandos de botão que suportam dados de entrada, ou seja, comandos com oinputconjunto de propriedades, otypePropriedade na informação de configuração doinputcampo suporta múltiplos tipos de controlo. Considere os seguintes exemplos:
function main() {
    // Status bar button control (set input field to implement) testBtn1 button triggered by the page in the drop-down box control using the options field to set options, using the defValue field to set the default options. This is different from the other examples in this chapter, which use defValue to set the options directly.
    var testBtn1 = {
        type: "button",
        name: "testBtn1",
        cmd: "cmdTestBtn1",
        input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1}
    }

    /* 
      Status bar button control (set input field implementation) testBtn2 button triggered by the page in the drop-down box control using the options field to set the options, options field in the options field not only supports the string,
      the use of the ```{text: "description", value: "value"}``` structure is also supported. Use the defValue field to set the default option, which can be multiple choice (multiple choice via array structure). Multiple choice requires setting the additional field multiple to a true value.
    */
    var testBtn2 = {
        type: "button", 
        name: "testBtn2",
        cmd: "cmdTestBtn2",
        input: {
            name: "testBtn2MultiComboBox", 
            type: "selected", 
            description: "Implementing dropdown box multi-selection", 
            options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}],
            defValue: ["A", "C"],
            multiple: true
        }
    }

    // Status bar grouping button control (set group field implementation) testBtn3 button triggered by the page in the drop-down box control using the options field to set options, also supports the direct use of defValue set options.
    var testBtn3 = {
        type: "button",                     
        name: "testBtn3",
        cmd: "cmdTestBtn3", 
        group: [
            {name: "comboBox1", label: "labelComboBox1", description: "Dropdown box 1", type: "selected", defValue: 1, options: ["A", "B"]}, 
            {name: "comboBox2", label: "labelComboBox2", description: "Dropdown box 2", type: "selected", defValue: "A|B"}, 
            {name: "comboBox3", label: "labelComboBox3", description: "Dropdown box 3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]}, 
            {
                name: "comboBox4", 
                label: "labelComboBox4", 
                description: "Dropdown box 4", 
                type: "selected", 
                defValue: ["A", "C"], 
                multiple: true, 
                options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}, {text: "Option D", value: "D"}]
            }
        ]
    }
    while (true) {
        LogStatus("`" + JSON.stringify(testBtn1) + "`\n", "`" + JSON.stringify(testBtn2) + "`\n", "`" + JSON.stringify(testBtn3) + "`\n")
        var cmd = GetCommand()
        if (cmd) {
            Log(cmd)
        }
        Sleep(5000)
    }
}
import json

def main():
    testBtn1 = {
        "type": "button",
        "name": "testBtn1",
        "cmd": "cmdTestBtn1",
        "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}
    }

    testBtn2 = {
        "type": "button", 
        "name": "testBtn2",
        "cmd": "cmdTestBtn2",
        "input": {
            "name": "testBtn2MultiComboBox", 
            "type": "selected", 
            "description": "Implementing dropdown box multi-selection", 
            "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],
            "defValue": ["A", "C"],
            "multiple": True
        }
    }

    testBtn3 = {
        "type": "button",                     
        "name": "testBtn3",
        "cmd": "cmdTestBtn3", 
        "group": [
            {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, 
            {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"}, 
            {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]}, 
            {
                "name": "comboBox4", 
                "label": "labelComboBox4", 
                "description": "Dropdown box 4", 
                "type": "selected", 
                "defValue": ["A", "C"], 
                "multiple": True, 
                "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}]
            }
        ]
    }

    while True:
        LogStatus("`" + json.dumps(testBtn1) + "`\n", "`" + json.dumps(testBtn2) + "`\n", "`" + json.dumps(testBtn3) + "`\n")
        cmd = GetCommand()
        if cmd:
            Log(cmd)
        Sleep(5000)
void main() {
    json testBtn1 = R"({
        "type": "button",
        "name": "testBtn1",
        "cmd": "cmdTestBtn1",
        "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}
    })"_json;
    
    json testBtn2 = R"({
        "type": "button", 
        "name": "testBtn2",
        "cmd": "cmdTestBtn2",
        "input": {
            "name": "testBtn2MultiComboBox", 
            "type": "selected", 
            "description": "Implementing dropdown box multi-selection", 
            "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],
            "defValue": ["A", "C"],
            "multiple": true
        }
    })"_json;
    
    json testBtn3 = R"({
        "type": "button",                     
        "name": "testBtn3",
        "cmd": "cmdTestBtn3", 
        "group": [
            {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, 
            {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"}, 
            {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]}, 
            {
                "name": "comboBox4", 
                "label": "labelComboBox4", 
                "description": "Dropdown box 4", 
                "type": "selected", 
                "defValue": ["A", "C"], 
                "multiple": true, 
                "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}]
            }
        ]
    })"_json;
    
    while (true) {
        LogStatus("`" + testBtn1.dump() + "`\n", "`" + testBtn2.dump() + "`\n", "`" + testBtn3.dump() + "`\n");
        auto cmd = GetCommand();
        if (cmd != "") {
            Log(cmd);
        }
        Sleep(5000);
    }
}

Quando o comando do botão de grupo da barra de estado (implementadogroupcampo) e o comando do botão da barra de estado (implementadoinputcampo) são clicados para desencadear a interação (estrutura de botão antigo), o controle da caixa suspensa na caixa de diálogo que aparece na página também suporta múltiplas seleções.

var symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]

function createBtn(tmp, group) {
    var btn = JSON.parse(JSON.stringify(tmp))

    _.each(group, function(eleByGroup) {
        btn["group"].unshift(eleByGroup)
    })

    return btn
}

function main() {
    var arrManager = []

    _.each(symbols, function(symbol) {
        arrManager.push({
            "symbol": symbol,
        })
    })

    // Btn
    var tmpBtnOpen = {
        "type": "button",
        "cmd": "open",
        "name": "Open a position and place an order",
        "group": [{
            "type": "selected",
            "name": "tradeType",
            "label": "Order type",
            "description": "Market order, limit order",
            "default": 0,
            "group": "Trading setup",
            "settings": {
                "options": ["Market order", "Limit order"],
                "required": true,
            }
        }, {
            "type": "selected",
            "name": "direction",
            "label": "Trading direction",
            "description": "Buy, sell",
            "default": "buy",
            "group": "Trading setup",
            "settings": {
                "render": "segment",
                "required": true,
                "options": [{"name": "buy", "value": "buy"}, {"name": "sell", "value": "sell"}],
            }
        }, {
            "type": "number",
            "name": "price",
            "label": "price",
            "description": "The price of the order",
            "group": "Trading setup",
            "filter": "tradeType==1",
            "settings": {
                "required": true,
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "Order quantity",
            "description": "Order quantity",
            "group": "Trading setup",
            "settings": {
                "required": true,
            }
        }],
    }

    while (true) {
        var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}

        _.each(arrManager, function(m) {
            var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Trading instruments", "default": m["symbol"], "settings": {"required": true}}])
            tbl["rows"].push([m["symbol"], btnOpen])
        })

        var cmd = GetCommand()
        if (cmd) {
            Log("Receive interaction:", cmd)

            // Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
            // According to the first colon: the previous instruction determines which button template triggers the message
            var arrCmd = cmd.split(":", 2)
            if (arrCmd[0] == "open") {
                var msg = JSON.parse(cmd.slice(5))
                Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", msg["tradeType"] == 0 ? "Market order" : "Limit order", msg["tradeType"] == 0 ? ", Order price: current market price" : ", Order price:" + msg["price"], ", Order quantity:", msg["amount"])
            }
        }

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}
import json

symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]

def createBtn(tmp, group):
    btn = json.loads(json.dumps(tmp))
    for eleByGroup in group:
        btn["group"].insert(0, eleByGroup)
    return btn

def main():
    arrManager = []

    for symbol in symbols:
        arrManager.append({"symbol": symbol})

    # Btn
    tmpBtnOpen = {
        "type": "button",
        "cmd": "open",
        "name": "Open a position and place an order",
        "group": [{
            "type": "selected",
            "name": "tradeType",
            "label": "Order type",
            "description": "Market order, limit order",
            "default": 0,
            "group": "Trading setup",
            "settings": {
                "options": ["Market order", "Limit order"],
                "required": True,
            }
        }, {
            "type": "selected",
            "name": "direction",
            "label": "Trading direction",
            "description": "Buy, sell",
            "default": "buy",
            "group": "Trading Setup",
            "settings": {
                "render": "segment",
                "required": True,
                "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
            }
        }, {
            "type": "number",
            "name": "price",
            "label": "price",
            "description": "The price of the order",
            "group": "Trading Setup",
            "filter": "tradeType==1",
            "settings": {
                "required": True,
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "Order quantity",
            "description": "Order quantity",
            "group": "Trading Setup",
            "settings": {
                "required": True,
            }
        }],
    }

    while True:
        tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}
        for m in arrManager:
            btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": True}}])
            tbl["rows"].append([m["symbol"], btnOpen])

        cmd = GetCommand()

        if cmd != "" and cmd != None:
            Log("Receive interaction:", cmd) 

            # Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
            # According to the first colon: the previous instruction determines which button template triggers the message
            arrCmd = cmd.split(":")
            if arrCmd[0] == "open":
                msg = json.loads(cmd[5:])
                Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", "Market order" if msg["tradeType"] == 0 else "Limit order", ", Order price: current market price" if msg["tradeType"] == 0 else ", Order price:" + str(msg["price"]), ", Order quantity:", msg["amount"])
        
        # Output status bar information
        LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
        Sleep(1000)
// Omit...

Use a estrutura de botões mais recente para construir os botões na tabela da barra de status. Para mais informações, consulte:Guia do utilizador - Controles interativos na barra de estado.

function main() {
    var table = { 
        type: 'table', 
        title: 'position operation', 
        cols: ['column1', 'column2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'close positions'}]
        ]
    } 
    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 positions"}]
        ]
    }
    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" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close positions"}]
        ]
    })"_json;            

    auto ticker = exchange.GetTicker();
    json jsonTicker = R"({"Buy": 0, "Sell": 0, "High": 0, "Low": 0, "Volume": 0, "Last": 0, "Time": 0})"_json;
    jsonTicker["Buy"] = ticker.Buy;
    jsonTicker["Sell"] = ticker.Sell;
    jsonTicker["Last"] = ticker.Last;
    jsonTicker["Volume"] = ticker.Volume;
    jsonTicker["Time"] = ticker.Time;
    jsonTicker["High"] = ticker.High;
    jsonTicker["Low"] = ticker.Low;            

    json arr = R"([{"body": {}, "colspan": 2}, "abc"])"_json;
    arr[0]["body"] = jsonTicker;
    table["rows"].push_back(arr);
    LogStatus("`" + table.dump() + "`");
}

Combinação horizontal de células dentro do quadro traçado peloLogStatus()Função:

function main() {
    var table = { 
        type: 'table', 
        title: 'table demo', 
        cols: ['columnA', 'columnB', 'columnC'], 
        rows: [ 
            ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}]
        ]
    }             

    var ticker = exchange.GetTicker()
    var name = exchange.GetName()            

    table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"])
    table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"])
    // A3 is merged by the first cell in the previous row
    table.rows.push(["B4", "C4"])
    // A2 is merged by the first cell of the previous row
    table.rows.push(["B5", "C5"])                                            
    table.rows.push(["A6", "B6", "C6"])
    LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
    table = {
        "type" : "table", 
        "title" : "table demo", 
        "cols" : ["columnA", "columnB", "columnC"], 
        "rows" : [
            ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
        ]
    }
    
    ticker = exchange.GetTicker()
    name = exchange.GetName()
    
    table["rows"].append([{"body": "A2 + B2:" + json.dumps(ticker), "colspan": 2}, "C2"])
    table["rows"].append([{"body": "A3 + A4 + A5:" + name, "rowspan": 3}, "B3", "C3"])
    table["rows"].append(["B4", "C4"])
    table["rows"].append(["B5", "C5"])
    table["rows"].append(["A6", "B6", "C6"])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type" : "table", 
        "title" : "table demo", 
        "cols" : ["columnA", "columnB", "columnC"], 
        "rows" : [
            ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
        ]
    })"_json;
    // For testing purposes, the code is short and easy to read, and the constructed data is used here
    json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json;
    auto name = exchange.GetName();
    json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json;
    arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump();
    json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json;
    arr2[0]["body"] = "A3 + A4 + A5:" + name;
    table["rows"].push_back(arr1);
    table["rows"].push_back(arr2);
    table["rows"].push_back(R"(["B4", "C4"])"_json);
    table["rows"].push_back(R"(["B5", "C5"])"_json);
    table["rows"].push_back(R"(["A6", "B6", "C6"])"_json);
    LogStatus("`" + table.dump() + "`");
}

Mergulhar verticalmente as células na tabela desenhada peloLogStatus()Função:

function main() {
    var table1 = {type: 'table', title: 'table1', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    var table2 = {type: 'table', title: 'table2', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    LogStatus('`' + JSON.stringify([table1, table2]) + '`')
}
import json
def main():
    table1 = {"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    table2 = {"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus("`" + json.dumps([table1, table2]) + "`")
void main() {
    json table1 = R"({"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json table2 = R"({"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json arr = R"([])"_json;
    arr.push_back(table1);
    arr.push_back(table2);
    LogStatus("`" + arr.dump() + "`");
}

Exibição de paginação da tabela da barra de estado:

function main(){
    var tab1 = {
        type : "table",
        title : "table1",
        cols : ["1", "2"],
        rows : []
    }
    var tab2 = {
        type : "table",
        title : "table2",
        cols : ["1", "2", "3"],
        rows : []
    }
    var tab3 = {
        type : "table",
        title : "table3",
        cols : ["A", "B", "C"],
        rows : []
    }            

    tab1.rows.push(["jack", "lucy"])
    tab2.rows.push(["A", "B", "C"])
    tab3.rows.push(["A", "B", "C"])            

    LogStatus('`' + JSON.stringify(tab1) + '`\n' + 
        '`' + JSON.stringify(tab2) + '`\n' +
        '`' + JSON.stringify(tab3) + '`')
  
    Log("exit")
}
import json
def main():
    tab1 = {
        "type": "table", 
        "title": "table1", 
        "cols": ["1", "2"], 
        "rows": []
    }
    tab2 = {
        "type": "table", 
        "title": "table2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    }
    tab3 = {
        "type": "table", 
        "title": "table3", 
        "cols": ["A", "B", "C"], 
        "rows": []
    }            

    tab1["rows"].append(["jack", "lucy"])
    tab2["rows"].append(["A", "B", "C"])
    tab3["rows"].append(["A", "B", "C"])
    LogStatus("`" + json.dumps(tab1) + "`\n" + 
        "`" + json.dumps(tab2) + "`\n" + 
        "`" + json.dumps(tab3) + "`")
void main() {
    json tab1 = R"({
        "type": "table", 
        "title": "table1", 
        "cols": ["1", "2"], 
        "rows": []
    })"_json;
    json tab2 = R"({
        "type": "table", 
        "title": "table2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    })"_json;
    json tab3 = R"({
        "type": "table", 
        "title": "table3", 
        "cols": ["A", "B", "C"], 
        "rows": []
    })"_json;
    tab1["rows"].push_back(R"(["jack", "lucy"])"_json);
    tab2["rows"].push_back(R"(["A", "B", "C"])"_json);
    tab3["rows"].push_back(R"(["A", "B", "C"])"_json);
    LogStatus("`" + tab1.dump() + "`\n" + 
        "`" + tab2.dump() + "`\n" +
        "`" + tab3.dump() + "`");
}

Além de exibir tabelas em páginas, várias tabelas também podem ser exibidas em uma ordem de cima para baixo:

function main() {
    var tbl = {
        type : "table",
        title : "test scroll",
        scroll : "auto",
        cols : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", 
            "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
        rows : []
    }

    for (var i = 1 ; i < 100 ; i++) {
        tbl.rows.push([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, 
            "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i])
    }
    
    LogStatus("`" + JSON.stringify(tbl) + "`")
}
import json

def main():
    tbl = {
        "type" : "table",
        "title" : "test scroll",
        "scroll" : "auto",
        "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", 
            "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
        "rows" : []
    }

    for index in range(1, 100):
        i = str(index)
        tbl["rows"].append([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, 
            "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i])
    
    LogStatus("`" + json.dumps(tbl) + "`")
void main() {
    json table = R"({
        "type" : "table",
        "title" : "test scroll",
        "scroll" : "auto",
        "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", 
            "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
        "rows" : []
    })"_json;

    for (int index = 1; index < 100; ++index) {
        std::string i = std::to_string(index);
        table["rows"].push_back({i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i,
            "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i});
    }

    LogStatus("`" + table.dump() + "`");
}

Suporte para definir o modo de rolagem horizontal e vertical da tabela de barra de estado.scrollatributo de"auto", quando o número de linhas verticais da tabela de barras de estado exceder 20 linhas, o conteúdo será rolado.scrollO atributo pode ser usado para aliviar o problema de atraso de escrever uma grande quantidade de dados na barra de status durante a negociação ao vivo.

A produção de informação a partir daLogStatus()A função quando a negociação ao vivo está em execução não é salvada no banco de dados de negociação ao vivo, mas atualiza apenas o conteúdo da barra de status da negociação ao vivo atual. OLogStatus()Função de impressãobase64imagens codificadas, começando com`e termina com`Por exemplo:LogStatus("`data:image/png;base64,AAAA`")- Não. OLogStatus()Função de suporte de passagemmatplotlib.pyplotobjetos diretamente noPython, desde que o objeto contenha osavefigmétodo, pode ser passado como um parâmetro para oLogStatus()função, por exemplo:

import matplotlib.pyplot as plt 
def main():
    plt.plot([3,6,2,4,7,1])
    LogStatus(plt) 

Quando a estratégia está executando negociação ao vivo, se você passar pelo histórico na página de negociação ao vivo, a barra de status vai dormir e parar de atualizar.base64imagens codificadas na barra de status, e também suporta a saídabase64Como os dados da cadeia da imagem codificada são geralmente muito longos, o código de amostra não é mostrado.

Não, não, não.

EnableLog

Ativar ou desactivar o registo das informações de encomenda.

AtivarLog (ativado)

Se oenableO parâmetro é definido como falso, por exemplo:false, o registo de encomendas (ou seja, o registo gerado por funções comoexchange.Buy()) não é impressa nem inscrita na base de dados das negociações em tempo real. permitir verdade Bool

function main() {
    EnableLog(false)
}
def main():
    EnableLog(False)
void main() {
    EnableLog(false);
}

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.CancelOrder exchange.CancelOrder}

Gráfico

Personalizar a função de desenho de gráficos.

Objeto gráfico. Objeto

Gráfico (opções)

OoptionsO parâmetro é a configuração do gráfico.Chart()Parâmetro de funçãooptionsé umJSONSerializávelHighStocksParâmetro paraHighcharts.StockChart- Um extra.__isStockatributo é adicionado sobre o parâmetro nativo, e se__isStock:falseSe o gráfico de referência for especificado, ele é exibido como um gráfico normal.__isStockatributo é definido em um valor falso, por exemplofalse, ou seja, o gráfico utilizado é umHighchartsSe o__isStockAtributo é definido para um valor verdadeiro, por exemplotrue, ou seja, o gráfico utilizado é umHighstocksgráfico (por defeito)__isStockÉ verdade, por exemplo.true) Pode consultar oBiblioteca de gráficos HighStocks- Não. opções verdade Objeto, matriz de objetos

function main() {
    var cfgA = {
        extension: {
            layout: 'single', // No grouping, display separately, default to group 'group'
            height: 300, // Specify the height
        },
        title: {
            text: 'handicap chart'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'buy one',
            data: [],
        }, {
            name: 'sell one',
            data: [],
        }]
    }
    var cfgB = {
        title: {
            text: 'spread chart'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'spread',
            type: 'column',
            data: [],
        }]
    }            

    var cfgC = {
        __isStock: false,
        title: {
            text: 'pie chart'
        },
        series: [{
            type: 'pie',
            name: 'one',
            data: [
                ["A", 25],
                ["B", 25],
                ["C", 25],
                ["D", 25],
            ]  // Instead of updating the initial data with the add function, the sequence can be updated by changing the chart configuration directly.
        }]
    };
    var cfgD = {
        extension: {
            layout: 'single',
            col: 8, // Specify the cell value for the width, the total value is 12
            height: '300px',
        },
        title: {
            text: 'handicap chart'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: 'buy one',
            data: [],
        }, {
            name: 'sell one',
            data: [],
        }]
    }
    var cfgE = {
        __isStock: false,
        extension: {
            layout: 'single',
            col: 4,
            height: '300px',
        },
        title: {
            text: 'pie chart2'
        },
        series: [{
            type: 'pie',
            name: 'one',
            data: [
                ["A", 25],
                ["B", 25],
                ["C", 25],
                ["D", 25],
            ]
        }]
    };            

    var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]);
    chart.reset()
        // Add a number of points to the pie chart, add can only update the data points added by add, built-in data points cannot be updated later.
    chart.add(3, {
        name: "ZZ",
        y: Math.random() * 100
    });
    while (true) {
        Sleep(1000)
        var ticker = exchange.GetTicker()
        if (!ticker) {
            continue;
        }
        var diff = ticker.Sell - ticker.Buy
        cfgA.subtitle = {
            text: 'buy one ' + ticker.Buy + ', sell one ' + ticker.Sell,
        };
        cfgB.subtitle = {
            text: 'spread ' + diff,
        };            

        chart.add([0, [new Date().getTime(), ticker.Buy]]);
        chart.add([1, [new Date().getTime(), ticker.Sell]]);
        // Equivalent to updating the first data series of the second chart
        chart.add([2, [new Date().getTime(), diff]]);
        chart.add(4, [new Date().getTime(), ticker.Buy]);
        chart.add(5, [new Date().getTime(), ticker.Buy]);
        cfgC.series[0].data[0][1] = Math.random() * 100;
        cfgE.series[0].data[0][1] = Math.random() * 100;
        // update is actually the same as resetting the chart's configuration
        chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]);
    }
}            
import random
import time
def main():
    cfgA = {
        "extension" : {
            "layout" : "single", 
            "height" : 300,
            "col" : 8
        }, 
        "title" : {
            "text" : "handicap chart"
        },
        "xAxis" : {
            "type" : "datetime" 
        }, 
        "series" : [{
            "name" : "buy one",
            "data" : []
        }, {
            "name" : "sell one", 
            "data" : []
        }]
    }                

    cfgB = {
        "title" : {
            "text" : "spread chart"
        }, 
        "xAxis" : {
            "type" : "datetime",
        }, 
        "series" : [{
            "name" : "spread", 
            "type" : "column", 
            "data" : []
        }]
    }                

    cfgC = {
        "__isStock" : False,
        "title" : {
            "text" : "pie chart"
        }, 
        "series" : [{
            "type" : "pie", 
            "name" : "one", 
            "data" : [
                ["A", 25],
                ["B", 25],
                ["C", 25],
                ["D", 25],
            ]
        }]
    }                

    cfgD = {
        "extension" : {
            "layout" : "single",
            "col" : 8,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "handicap chart"
        }, 
        "series" : [{
            "name" : "buy one", 
            "data" : []
        }, {
            "name" : "sell one",
            "data" : []
        }]
    }                

    cfgE = {
        "__isStock" : False, 
        "extension" : {
            "layout" : "single", 
            "col" : 4,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "pie chart2"
        },
        "series" : [{
            "type" : "pie",
            "name" : "one", 
            "data" : [
                ["A", 25], 
                ["B", 25], 
                ["C", 25], 
                ["D", 25]
            ]
        }]
    }
    
    chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE])
    chart.reset()
    chart.add(3, {
        "name" : "ZZ",
        "y" : random.random() * 100
    })
    
    while True:
        Sleep(1000)
        ticker = exchange.GetTicker()
        if not ticker :
            continue
        diff = ticker["Sell"] - ticker["Buy"]
        cfgA["subtitle"] = {
            "text" : "buy one" + str(ticker["Buy"]) + "sell one" + str(ticker["Sell"])
        }
        cfgB["subtitle"] = {
            "text" : "spread " + str(diff)
        }
        
        chart.add(0, [time.time() * 1000, ticker["Buy"]])
        chart.add(1, [time.time() * 1000, ticker["Sell"]])
        chart.add(2, [time.time() * 1000, diff])
        chart.add(4, [time.time() * 1000, ticker["Buy"]])
        chart.add(5, [time.time() * 1000, ticker["Buy"]])
        cfgC["series"][0]["data"][0][1] = random.random() * 100
        cfgE["series"][0]["data"][0][1] = random.random() * 100
void main() {
    json cfgA = R"({
        "extension" : {
            "layout" : "single", 
            "height" : 300,
            "col" : 8
        }, 
        "title" : {
            "text" : "handicap chart"
        },
        "xAxis" : {
            "type" : "datetime" 
        }, 
        "series" : [{
            "name" : "buy one",
            "data" : []
        }, {
            "name" : "sell one", 
            "data" : []
        }]
    })"_json;                

    json cfgB = R"({
        "title" : {
            "text" : "spread chart"
        }, 
        "xAxis" : {
            "type" : "datetime"
        }, 
        "series" : [{
            "name" : "spread", 
            "type" : "column", 
            "data" : []
        }]
    })"_json;    
    
    json cfgC = R"({
        "__isStock" : false,
        "title" : {
            "text" : "pie chart"
        }, 
        "series" : [{
            "type" : "pie", 
            "name" : "one", 
            "data" : [
                ["A", 25],
                ["B", 25],
                ["C", 25],
                ["D", 25]
            ]
        }]
    })"_json;    
    
    json cfgD = R"({
        "extension" : {
            "layout" : "single",
            "col" : 8,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "handicap chart"
        }, 
        "series" : [{
            "name" : "buy one", 
            "data" : []
        }, {
            "name" : "sell one",
            "data" : []
        }]
    })"_json;    
    
    json cfgE = R"({
        "__isStock" : false, 
        "extension" : {
            "layout" : "single", 
            "col" : 4,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "pie chart2"
        },
        "series" : [{
            "type" : "pie",
            "name" : "one", 
            "data" : [
                ["A", 25], 
                ["B", 25], 
                ["C", 25], 
                ["D", 25]
            ]
        }]
    })"_json;            

    auto chart = Chart({cfgA, cfgB, cfgC, cfgD, cfgE});
    chart.reset();
    json zz = R"({
        "name" : "ZZ", 
        "y" : 0
    })"_json;
    zz["y"] = rand() % 100;
    chart.add(3, zz);
    
    while(true) {
        Sleep(1000);
        auto ticker = exchange.GetTicker();
        if(!ticker.Valid) {
            continue;
        }
        auto diff = ticker.Sell - ticker.Buy;
        json cfgASubTitle = R"({"text" : ""})"_json;
        cfgASubTitle["text"] = format("buy one %f , sell one %f", ticker.Buy, ticker.Sell);
        cfgA["subtitle"] = cfgASubTitle;
        
        json cfgBSubTitle = R"({"text" : ""})"_json;
        cfgBSubTitle["text"] = format("spread %f", diff);
        cfgB["subtitle"] = cfgBSubTitle;            

        chart.add(0, {Unix() * 1000, ticker.Buy});
        chart.add(1, {Unix() * 1000, ticker.Sell});
        chart.add(2, {Unix() * 1000, diff});
        chart.add(4, {Unix() * 1000, ticker.Buy});
        chart.add(5, {Unix() * 1000, ticker.Buy});
        cfgC["series"][0]["data"][0][1] = rand() % 100;
        cfgE["series"][0]["data"][0][1] = rand() % 100;
        chart.update({cfgA, cfgB, cfgC, cfgD, cfgE});
    }
}

Configuração de desenho de gráficos múltiplos:

  • extension.layoutatributo Se o atributo for definido com o valor single, os gráficos não serão empilhados (não exibidos como guias), mas serão exibidos separadamente (em azulejos).
  • extension.heightatributo O atributo é usado para definir a altura do gráfico, como um valor numérico ou como 300px.
  • extension.colatributo O atributo é usado para definir a largura do gráfico, a largura da página é dividida em 12 células, conjunto 8, ou seja, o gráfico ocupa 8 largura de células.
// This chart is an object in the JavaScript language, and before using the Chart function, we need to declare an object variable chart to configure the chart. var chart = {                                           
    // This field marks whether the chart is a general chart or not, if you are interested, you can change it to false and run it.
    __isStock: true,                                    
    // Scaling tool
    tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},    
    // title
    title : { text : 'spread analysis chart'},                       
    // selection range
    rangeSelector: {                                    
        buttons:  [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
        selected: 0,
        inputEnabled: false
    },
    // Coordinate axis horizontal axis that is: x-axis, the current setting type is: time
    xAxis: { type: 'datetime'},                         
    // Coordinate axis vertical axis that is: y-axis, default value adjusted with the size of the data
    yAxis : {                                           
        // title
        title: {text: 'spread'},                           
        // Whether to enable the right vertical axis
        opposite: false                                 
    },
    // Data series, this sttribute holds the individual data series (lines, K-charts, labels, etc...)
    series : [                                          
        // The index is 0, and the data array holds the data of the index series
        {name : "line1", id : "line1,buy1Price", data : []},                          
        // Index is 1, set dashStyle:'shortdash' i.e.: set the dashed line
        {name : "line2", id : "line2,lastPrice", dashStyle : 'shortdash', data : []}  
    ]
} function main(){
    // Call the Chart function to initialize the chart
    var ObjChart = Chart(chart)         
    // Clear out
    ObjChart.reset()                      
    while(true){
        // Gets the timestamp of this poll, i.e. a millisecond timestamp. It's used to determine the position of the X-axis written to the chart.
        var nowTime = new Date().getTime()
        // Get the ticker data
        var ticker = _C(exchange.GetTicker)
        // Get buy one price from the return value of the ticker data
        var buy1Price = ticker.Buy    
        // To obtain the final transaction price, we add 1 in order not to overlap the 2 lines
        var lastPrice = ticker.Last + 1
        // Data sequence with timestamp as X-value and buy one price as Y-value passed into index 0
        ObjChart.add(0, [nowTime, buy1Price])
        // ditto
        ObjChart.add(1, [nowTime, lastPrice])
        Sleep(2000)
    }
}```
```python
import time
chart = {
    "__isStock" : True,
    "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},  
    "title" : {"text" : "spread analysis chart"}, 
    "rangeSelector" : {
        "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], 
        "selected": 0,
        "inputEnabled": False 
    }, 
    "xAxis": {"type": "datetime"}, 
    "yAxis": {
        "title": {"text": "spread"},
        "opposite": False
    },
    "series": [{
        "name": "line1", "id": "line1,buy1Price", "data": []
    }, {
        "name": "line2", "id": "line2,lastPrice", "dashStyle": "shortdash", "data": []
    }]
}
def main():
    ObjChart = Chart(chart)
    ObjChart.reset()
    while True:
        nowTime = time.time() * 1000
        ticker = exchange.GetTicker()
        buy1Price = ticker["Buy"]
        lastPrice = ticker["Last"] + 1
        ObjChart.add(0, [nowTime, buy1Price])
        ObjChart.add(1, [nowTime, lastPrice])
        Sleep(2000)
void main() {
    // When writing strategies in C++, try not to declare global variables that are not of the base type, so the chart configuration object is declared inside the main function.
    json chart = R"({
        "__isStock" : true,
        "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},  
        "title" : {"text" : "spread analysis chart"}, 
        "rangeSelector" : {
            "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], 
            "selected": 0,
            "inputEnabled": false 
        }, 
        "xAxis": {"type": "datetime"}, 
        "yAxis": {
            "title": {"text": "spread"},
            "opposite": false
        },
        "series": [{
            "name": "line1", "id": "line1,buy1Price", "data": []
        }, {
            "name": "line2", "id": "line2,lastPrice", "dashStyle": "shortdash", "data": []
        }]
    })"_json;
    auto ObjChart = Chart(chart);
    ObjChart.reset();
    while(true) {
        auto nowTime = Unix() * 1000;
        auto ticker = exchange.GetTicker();
        auto buy1Price = ticker.Buy;
        auto lastPrice = ticker.Last + 1.0;
        ObjChart.add(0, {nowTime, buy1Price});
        ObjChart.add(1, {nowTime, lastPrice});
        Sleep(2000);
    }
}

Exemplo de um desenho simples:

// Objects used to initialize the chart
var chart = {                                   
    // Chart title
    title: {text: "line value triggers the plotLines value"},   
    // Y-axis related settings
    yAxis: {                                    
        // A horizontal line perpendicular to the Y-axis, used as a trigger line, is a structural array that can set multiple trigger lines
        plotLines: [{                           
            // The value of the trigger line, how much it set, this line will be displayed in the corresponding value position
            value: 0,                           
            // Set the color of the trigger line
            color: 'red',                       
            // Width
            width: 2,                           
            // Displaying labels
            label: {                            
                // Label text
                text: 'Trigger value',                  
                // Centered label position
                align: 'center'                 
            }
        }]
    },
    // X-axis related settings, here the setting type is time axis
    xAxis: {type: "datetime"},                  
    series: [
        {name: "sin", type: "spline", data: []},
        // This is an important data series, you can set multiple data series, according to the array index control
        {name: "cos", type: "spline", data: []}
    ]  
}
function main(){
    // Circumference
    var pi = 3.1415926535897
    // Variables for recording timestamps
    var time = 0                   
    // Angle
    var angle = 0                        
    // Coordinate y values for receiving sine and cosine values
    var y = 0          
    // Call the API interface to initialize the chart with the chart object
    var objChart = Chart(chart)        
    // Initially, clear the chart
    objChart.reset()
    // Set the value of the trigger line to 1
    chart.yAxis.plotLines[0].value = 1
    // Loop
    while(true){                          
        // Get the timestamp of the current moment
        time = new Date().getTime() 
        // Angle increases by 5 degrees every 500ms and calculates the sine value
        y = Math.sin(angle * 2 * pi / 360)
        // Write the calculated y value to the data series of the corresponding index of the chart, the first parameter of the add function is the specified data series index
        objChart.add(0, [time, y])
        // Calculate the cosine value
        y = Math.cos(angle * 2 * pi / 360)
        objChart.add(1, [time, y])
        // Increase by 5 degrees
        angle += 5
        // Pause for 5 seconds to avoid drawing too often and growing data too fast
        Sleep(5000)     
    }
}
import math
import time
chart = {
    "title": {"text": "line value triggers the plotLines value"}, 
    "yAxis": {
        "plotLines": [{
            "value": 0,
            "color": "red",
            "width": 2,
            "label": {
                "text": "trigger value", 
                "align": "center"
            }
        }]
    },
    "xAxis": {"type": "datetime"},
    "series": [{"name": "sin", "type": "spline", "data": []},
               {"name": "cos", "type": "spline", "data": []}]
}
def main():
    pi = 3.1415926535897
    ts = 0
    angle = 0
    y = 0
    objChart = Chart(chart)
    objChart.reset()
    chart["yAxis"]["plotLines"][0]["value"] = 1
    while True:
        ts = time.time() * 1000
        y = math.sin(angle * 2 * pi / 360)
        objChart.add(0, [ts, y])
        y = math.cos(angle * 2 * pi / 360)
        objChart.add(1, [ts, y])
        angle += 5
        Sleep(5000)
void main() {
    json chart = R"({
        "title": {"text": "line value triggers the plotLines value"}, 
        "yAxis": {
            "plotLines": [{
                "value": 0,
                "color": "red",
                "width": 2,
                "label": {
                    "text": "trigger value", 
                    "align": "center"
                }
            }]
        },
        "xAxis": {"type": "datetime"},
        "series": [{"name": "sin", "type": "spline", "data": []},
                   {"name": "cos", "type": "spline", "data": []}]     
    })"_json;            

    auto pi = 3.1415926535897;
    auto ts = 0;
    auto angle = 0.0;
    auto y = 0.0;
    auto objChart = Chart(chart);
    objChart.reset();
    chart["yAxis"]["plotLines"][0]["value"] = 1;
    while(true) {
        ts = Unix() * 1000;
        y = sin(angle * 2 * pi / 360);
        objChart.add(0, {ts, y});
        y = cos(angle * 2 * pi / 360);
        objChart.add(1, {ts, y});
        angle += 5;
        Sleep(5000);
    }
}

Exemplo de desenho de curva trigonométrica:

/*backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/            

var chartCfg = {
    subtitle: {
        text: "subtitle",
    },
    yAxis: [{
        height: "40%",
        lineWidth: 2,
        title: {
            text: 'PnL',
        },
        tickPixelInterval: 20,
        minorGridLineWidth: 1,
        minorTickWidth: 0,
        opposite: true,
        labels: {
            align: "right",
            x: -3,
        }
    }, {
        title: {
            text: 'Profit',
        },
        top: "42%",
        height: "18%",
        offset: 0,
        lineWidth: 2
    }, {
        title: {
            text: 'Vol',
        },
        top: '62%',
        height: '18%',
        offset: 0,
        lineWidth: 2
    }, {
        title: {
            text: 'Asset',
        },
        top: '82%',
        height: '18%',
        offset: 0,
        lineWidth: 2
    }],
    series: [{
        name: 'PnL',
        data: [],
        id: 'primary',
        tooltip: {
            xDateFormat: '%Y-%m-%d %H:%M:%S'
        },
        yAxis: 0
    }, {
        type: 'column',
        lineWidth: 2,
        name: 'Profit',
        data: [],
        yAxis: 1,
    }, {
        type: 'column',
        name: 'Trade',
        data: [],
        yAxis: 2
    }, {
        type: 'area',
        step: true,
        lineWidth: 0,
        name: 'Long',
        data: [],
        yAxis: 2
    }, {
        type: 'area',
        step: true,
        lineWidth: 0,
        name: 'Short',
        data: [],
        yAxis: 2
    }, {
        type: 'line',
        step: true,
        color: '#5b4b00',
        name: 'Asset',
        data: [],
        yAxis: 3
    }, {
        type: 'pie',
        innerSize: '70%',
        name: 'Random',
        data: [],
        center: ['3%', '6%'],
        size: '15%',
        dataLabels: {
            enabled: false
        },
        startAngle: -90,
        endAngle: 90,
    }],
};            

function main() {
    let c = Chart(chartCfg);
    let preTicker = null;
    while (true) {
        let t = exchange.GetTicker();
        
        c.add(0, [t.Time, t.Last]); // PnL
        c.add(1, [t.Time, preTicker ? t.Last - preTicker.Last : 0]); // profit
        let r = Math.random();
        var pos = parseInt(t.Time/86400);
        c.add(2, [t.Time, pos/2]); // Vol
        c.add(3, [t.Time, r > 0.8 ? pos : null]); // Long
        c.add(4, [t.Time, r < 0.8 ? -pos : null]); // Short
        c.add(5, [t.Time, Math.random() * 100]); // Asset
        // update pie
        chartCfg.series[chartCfg.series.length-1].data = [
            ["A", Math.random()*100],
            ["B", Math.random()*100],
         ];
        c.update(chartCfg)
        preTicker = t;
    }
}
'''backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''            

import random            

chartCfg = {
    "subtitle": {
        "text": "subtitle"
    },
    "yAxis": [{
        "height": "40%",
        "lineWidth": 2,
        "title": {
            "text": 'PnL'
        },
        "tickPixelInterval": 20,
        "minorGridLineWidth": 1,
        "minorTickWidth": 0,
        "opposite": True,
        "labels": {
            "align": "right",
            "x": -3
        }
    }, {
        "title": {
            "text": 'Profit'
        },
        "top": "42%",
        "height": "18%",
        "offset": 0,
        "lineWidth": 2
    }, {
        "title": {
            "text": 'Vol'
        },
        "top": '62%',
        "height": '18%',
        "offset": 0,
        "lineWidth": 2
    }, {
        "title": {
            "text": 'Asset'
        },
        "top": '82%',
        "height": '18%',
        "offset": 0,
        "lineWidth": 2
    }],
    "series": [{
        "name": 'PnL',
        "data": [],
        "id": 'primary',
        "tooltip": {
            "xDateFormat": '%Y-%m-%d %H:%M:%S'
        },
        "yAxis": 0
    }, {
        "type": 'column',
        "lineWidth": 2,
        "name": 'Profit',
        "data": [],
        "yAxis": 1
    }, {
        "type": 'column',
        "name": 'Trade',
        "data": [],
        "yAxis": 2
    }, {
        "type": 'area',
        "step": True,
        "lineWidth": 0,
        "name": 'Long',
        "data": [],
        "yAxis": 2
    }, {
        "type": 'area',
        "step": True,
        "lineWidth": 0,
        "name": 'Short',
        "data": [],
        "yAxis": 2
    }, {
        "type": 'line',
        "step": True,
        "color": '#5b4b00',
        "name": 'Asset',
        "data": [],
        "yAxis": 3
    }, {
        "type": 'pie',
        "innerSize": '70%',
        "name": 'Random',
        "data": [],
        "center": ['3%', '6%'],
        "size": '15%',
        "dataLabels": {
            "enabled": False
        },
        "startAngle": -90,
        "endAngle": 90
    }]
}            

def main():
    c = Chart(chartCfg)
    preTicker = None
    while True:
        t = exchange.GetTicker()
        c.add(0, [t["Time"], t["Last"]])
        profit = t["Last"] - preTicker["Last"] if preTicker else 0
        c.add(1, [t["Time"], profit])
        r = random.random()
        pos = t["Time"] / 86400
        c.add(2, [t["Time"], pos / 2])
        long = pos if r > 0.8 else None
        c.add(3, [t["Time"], long])
        short = -pos if r < 0.8 else None
        c.add(4, [t["Time"], short])
        c.add(5, [t["Time"], random.random() * 100])            

        # update pie
        chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
            ["A", random.random() * 100], 
            ["B", random.random() * 100]
        ]
        c.update(chartCfg)
        preTicker = t
/*backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/            

void main() {
    json chartCfg = R"({
        "subtitle": {
            "text": "subtitle"
        },
        "yAxis": [{
            "height": "40%",
            "lineWidth": 2,
            "title": {
                "text": "PnL"
            },
            "tickPixelInterval": 20,
            "minorGridLineWidth": 1,
            "minorTickWidth": 0,
            "opposite": true,
            "labels": {
                "align": "right",
                "x": -3
            }
        }, {
            "title": {
                "text": "Profit"
            },
            "top": "42%",
            "height": "18%",
            "offset": 0,
            "lineWidth": 2
        }, {
            "title": {
                "text": "Vol"
            },
            "top": "62%",
            "height": "18%",
            "offset": 0,
            "lineWidth": 2
        }, {
            "title": {
                "text": "Asset"
            },
            "top": "82%",
            "height": "18%",
            "offset": 0,
            "lineWidth": 2
        }],
        "series": [{
            "name": "PnL",
            "data": [],
            "id": "primary",
            "tooltip": {
                "xDateFormat": "%Y-%m-%d %H:%M:%S"
            },
            "yAxis": 0
        }, {
            "type": "column",
            "lineWidth": 2,
            "name": "Profit",
            "data": [],
            "yAxis": 1
        }, {
            "type": "column",
            "name": "Trade",
            "data": [],
            "yAxis": 2
        }, {
            "type": "area",
            "step": true,
            "lineWidth": 0,
            "name": "Long",
            "data": [],
            "yAxis": 2
        }, {
            "type": "area",
            "step": true,
            "lineWidth": 0,
            "name": "Short",
            "data": [],
            "yAxis": 2
        }, {
            "type": "line",
            "step": true,
            "color": "#5b4b00",
            "name": "Asset",
            "data": [],
            "yAxis": 3
        }, {
            "type": "pie",
            "innerSize": "70%",
            "name": "Random",
            "data": [],
            "center": ["3%", "6%"],
            "size": "15%",
            "dataLabels": {
                "enabled": false
            },
            "startAngle": -90,
            "endAngle": 90
        }]
    })"_json;
    
    Chart c = Chart(chartCfg);
    Ticker preTicker;
    while(true) {
        auto t = exchange.GetTicker();
        c.add(0, {t.Time, t.Last});
        auto profit = preTicker.Valid ? t.Last - preTicker.Last : 0;
        c.add(1, {t.Time, profit});    
        auto r = rand() % 100;
        auto pos = t.Time / 86400.0;
        c.add(2, {t.Time, pos / 2.0});
        auto longPos = r > 0.8 ? pos : NULL;
        c.add(3, {t.Time, longPos});
        auto shortPos = r < 0.8 ? -pos : NULL;
        c.add(4, {t.Time, shortPos});
        c.add(5, {t.Time, rand() % 100});
        
        // update pie 
        json pie = R"([["A", 0], ["B", 0]])"_json;
        pie[0][1] = rand() % 100;
        pie[1][1] = rand() % 100;
        chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie;
        
        c.update(chartCfg);
        preTicker = t;
    }
}            

Exemplos complexos de utilização de gráficos híbridos:

// update pie
chartCfg.series[chartCfg.series.length-1].data = [
    ["A", Math.random()*100],
    ["B", Math.random()*100],
];
c.update(chartCfg)
# update pie
chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
    ["A", random.random() * 100], 
    ["B", random.random() * 100]
]
c.update(chartCfg)
// update pie 
json pie = R"([["A", 0], ["B", 0]])"_json;
pie[0][1] = rand() % 100;
pie[1][1] = rand() % 100;
chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie;
c.update(chartCfg);

Cartões de tipopiesão gráficos sem uma linha do tempo, e você precisa atualizar a configuração do gráfico diretamente ao atualizar os dados.c.update(chartCfg)Após a atualização dos dados, do seguinte modo:

OChart()função retorna um objeto gráfico que tem 4 métodos:add(), reset(), update(), del().

    1. Oupdate()método: Oupdate()O parâmetro deste método é o objeto de configuração do gráfico (JSON).
    1. Odel()método: Odel()O método pode excluir a série de dados do índice especificado com base no parâmetro de série passado.
    1. Oadd()método: Oadd()O método pode escrever dados para o gráfico, com os seguintes parâmetros em ordem:
    • series: utilizado para definir o índice da série de dados, que é um número inteiro.
    • data: usado para definir os dados específicos a serem escritos, é uma matriz.
    • index(opcional): utilizado para definir o índice de dados, é um número inteiro.-1refere-se aos últimos dados do conjunto de dados. Por exemplo, ao desenhar uma linha, modificar os dados no último ponto da linha:chart.add(0, [1574993606000, 13.5], -1), isto é, alterar os dados no penúltimo primeiro ponto do gráficoseries[0].data- Não. OindexO parâmetro não é definido, o que significa que os dados são adicionados ao último ponto da série de dados corrente.
    1. Oreset()método: Oreset()O método é utilizado para esvaziar os dados do gráfico.reset()método pode tomar um parâmetroremainPara especificar o número de entradas a manter.remainé passado para limpar todos os dados.

Não, não, não, não.

KLineChart

A função é usada para desenho personalizado no tempo de execução da estratégia usando um método de desenho similar aoPine language.

O objeto gráfico.KLineChart()função retorna um objeto gráfico com vários métodos, entre os quais você precisa prestar atenção abegin()eclose(). A operação de desenho deve começar por umbegin()Função chamada e termina com aclose()chamada de função ao atravessar os dados KLine para executar a operação de desenho. Objeto

KLineChart (opções)

OoptionsO parâmetro é a configuração do gráfico. opções verdade Objeto, matriz de objetos

function main() {
    // Call the KLineChart function to create a chart control object c
    let c = KLineChart({
        overlay: true
    })            

    // Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up the contract first.
    let bars = exchange.GetRecords()
    if (!bars) {
        return
    }            
    
    // Execute the drawing operation by traversing over the K-line data. The drawing operation must start with the ```c.begin(bar)``` function call and end with the ```c.close()``` function call.
    bars.forEach(function(bar, index) {
        c.begin(bar)
        c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)')
        if (bar.Close > bar.Open) {
            c.bgcolor('rgba(0, 255, 0, 0.5)')
        }
        let h = c.plot(bar.High, 'high')
        let l = c.plot(bar.Low, 'low')            

        c.fill(h, l, {
            color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'
        })
        c.hline(bar.High)
        c.plotarrow(bar.Close - bar.Open)
        c.plotshape(bar.Low, {
            style: 'diamond'
        })
        c.plotchar(bar.Close, {
            char: 'X'
        })
        c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
        if (bar.Close > bar.Open) {
            // long/short/closelong/closeshort
            c.signal("long", bar.High, 1.5)
        } else if (bar.Close < bar.Open) {
            c.signal("closelong", bar.Low, 1.5)
        }
        c.close()
    })
}
def main():
    # Call the KLineChart function to create a chart control object c
    c = KLineChart({
        "overlay": True
    })            

    # Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up the contract first.
    bars = exchange.GetRecords()
    if not bars:
        return            

    for bar in bars:
        c.begin(bar)
        c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
        if bar.Close > bar.Open:
            c.bgcolor('rgba(0, 255, 0, 0.5)')            

        h = c.plot(bar.High, 'high')
        l = c.plot(bar.Low, 'low')            

        c.fill(h, l, 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)')
        c.hline(bar.High)
        c.plotarrow(bar.Close - bar.Open)        
        c.plotshape(bar.Low, style = 'diamond')
        c.plotchar(bar.Close, char = 'X')
        c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
        if bar.Close > bar.Open:
            # long/short/closelong/closeshort
            c.signal("long", bar.High, 1.5)
        elif bar.Close < bar.Open:
            c.signal("closelong", bar.Low, 1.5)            

        c.close()
// Not supported for now

Se um objeto de controlo de gráfico for necessário para desenhar na área de desenho personalizado da estratégia, use oKLineChart()A função para criar o objeto.KLineChart()A função é uma estrutura de configuração de gráfico, a usada no código de referência é simples:{overlay: true}Esta estrutura de configuração de gráfico define apenas o conteúdo do desenho a ser emitido no gráfico principal.overlayé definido em um valor falso, por exemplo:false, o conteúdo do gráfico é saída no gráfico secundário. Se você precisa especificar uma função de desenho para desenhar no gráfico principal, você também pode especificar o parâmetrooverlaycomo um valor verdadeiro na chamada de função específica, por exemplo:true.

c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)')   // Use the example illustrated in the reference code in this example, without further ado
c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
//  Not supported for now

As funções da interface de desenho doPineAs línguas suportadas na operação de desenho são:barcolor, que define a cor da linha K.

barcolor ((color, offset, editável, show_last, title, display) Parâmetros de exibição são opcionais: none, all

c.bgcolor('rgba(0, 255, 0, 0.5)')
c.bgcolor('rgba(0, 255, 0, 0.5)')
// Not supported for now

bgcolor, preenche o fundo da linha K com a cor especificada.

bgcolor ((color, offset, editável, show_last, título, exibição, sobreposição) Parâmetros de exibição são opcionais: none, all

c.plot(bar.High, 'high')
c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"})  // Support for drawing discontinuous data lines
h = c.plot(bar.High, 'high')
h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr")  # Support for drawing discontinuous data lines
// Not supported for now

plot, traçar uma série de dados num gráfico.

plot ((série, título, cor, largura de linha, estilo, trackprice, histbase, offset, join, editável, show_last, display) Os parâmetros de estilo são opcionais: stepline_diamond, stepline, cross, areabr, area, circles, columns, histogram, linebr, line Parâmetros de exibição opcionais: none, all

let h = c.plot(bar.High, 'high')
let l = c.plot(bar.Low, 'low')

c.fill(h, l, {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'})
h = c.plot(bar.High, 'high')
l = c.plot(bar.Low, 'low')

c.fill(h, l, color = 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)'})
// Not supported for now

fill, preencher o fundo entre dois gráficos ouhlinecom as cores fornecidas.

preencher ((linha1, linha2, cor, título, editável, preencher espaços, exibição) Parâmetros de exibição são opcionais: none, all

Desde oJavaScriptlinguagem não pode especificar parâmetros de entrada com base nos nomes das funções parâmetros formais, para resolver este problema, você pode usar um{key: value}estrutura para especificar os parâmetros a passar a um determinado nome de parâmetro formal. Por exemplo, o código de referência utiliza{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)'}Especifica ocolorParâmetro dofillfunção. Se você precisa especificar vários parâmetros com nomes de parâmetros de forma consecutiva, você pode usar{key1: value1, key2: value2, key3: value3}- Não. Por exemplo, neste exemplo, um extratitleÉ especificado o parâmetro:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)', title: 'fill'}- Não. Para o valor da cor, você pode definir com'rgba(255, 0, 0, 0, 0.2)'ou com'#FF0000'.

c.hline(bar.High)
c.hline(bar.High)
// Not supported for now

hline, a linha horizontal é apresentada a um determinado nível de preço fixo.

linha ((preço, título, cor, estilo de linha, largura de linha, editável, exibição) Os parâmetros do estilo de linha são opcionais: dashed, dotted, solid Parâmetros de exibição são opcionais: none, all

c.plotarrow(bar.Close - bar.Open)
c.plotarrow(bar.Close - bar.Open)
// Not supported for now

plotarrow, traçar setas para cima e para baixo no gráfico.

Plotarrow ((série, título, colorup, colorordown, offset, minheight, maxheight, editável, show_last, display) Parâmetros de exibição são opcionais: none, all

c.plotshape(bar.Low, {style: 'diamond'})
c.plotshape(bar.Low, style = 'diamond')
// Not supported for now

plotshape, desenhar formas visuais no gráfico.

plotshape (série, título, estilo, localização, cor, offset, texto, textcolor, editável, tamanho, show_last, display) Os parâmetros de estilo são opcionais: diamond, square, label_down, label_up, arrow_down, arrow_up, circle, flag, triangle_down, triangle_up, cross, xcross Os parâmetros de localização são opcionais: bar superior, bar inferior, top, bottom, absolute Os parâmetros de tamanho são opcionais: 10px, 14px, 20px, 40px, 80px, comparando size.tiny, size.small, size.normal, size.large, size.huge na língua Pine.size.autoÉ pequeno. Parâmetros de exibição são opcionais: none, all

c.plotchar(bar.Close, {char: 'X'})
c.plotchar(bar.Close, char = 'X')
// Not supported for now

plotchar, desenhe formas visuais no gráfico usando qualquer caracter Unicode dado.

plotchar ((série, título, char, localização, cor, offset, texto, textcolor, editável, tamanho, show_last, display) Os parâmetros de localização são opcionais: bar superior, bar inferior, top, bottom, absolute Os parâmetros de tamanho são opcionais: 10px, 14px, 20px, 40px, 80px, comparando size.tiny, size.small, size.normal, size.large, size.huge na língua Pine.size.autoÉ pequeno. Parâmetros de exibição são opcionais: none, all

c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
// Not supported for now

plotcandle, traçar um gráfico de linha K em um gráfico.

plotcandle ((aberto, alto, baixo, fechado, título, cor, wickcolor, editável, show_last, bordercolor, display) Parâmetros de exibição são opcionais: none, all

c.signal("long", bar.High, 1.5)
c.signal("long", bar.High, 1.5)
// Not supported for now

signal, uma função não disponível na linguagem Pine, é usada para desenhar sinais de compra e venda aqui.

sinal ((direção, preço, qty, id) O parâmetro long é passado para indicar a direção da transação, você pode escolher long, closelong, short, closeshort.bar.Highé a posição do eixo Y do sinal de marcação. O parâmetro transmitido 1.5 indica o número de transações do sinal. O quarto parâmetro pode ser transmitido para substituir o conteúdo de texto padrão desenhado, e o texto padrão do marcador de sinal desenhado é a direção da transação, por exemplo closelong.

c.reset()
c.reset()
// Not supported for now

reset, uma função não disponível na linguagem Pine, é usada para esvaziar os dados do gráfico.

Reiniciar (permanecer) Oreset()O método pode assumir um parâmetro,remain, para especificar o número de dados a conservar.remainsignifica limpar todos os dados.

Estratégia desenho personalizado só pode usar uma das formas deKLineChart()função ouChart()Para algumas configurações de cor e estilo utilizadas noKLineChart()chamada de função, por favor, consulte oUse a função KLineChart para facilitar o desenho de estratégias.

Não, não, não, não.

LogReset

Limpa o tronco.

LogReset (permanecer)

OremainO parâmetro é utilizado para definir o número de entradas de registo recentes a manter. permanecer Falso Número

function main() {
    // Keep the last 10 logs and clear the rest
    LogReset(10)     
}
def main():
    LogReset(10)
void main() {
    LogReset(10);
}

O log de inicialização para cada início da estratégia conta como um, por isso, se nenhum parâmetro for passado e não houver saída de log no início da estratégia, nenhum log será exibido, esperando que o log docker seja devolvido (não é uma exceção).

Não, não, não, não.

LogVacuum

Utilizado para recuperar o espaço de armazenamento ocupado porSQLiteQuando se excluem dados após a chamada doLogReset()Função para limpar o registro.

LogVacuum ((()

function main() {
    LogReset()
    LogVacuum()
}
def main():
    LogReset()
    LogVacuum()
void main() {
    LogReset()
    LogVacuum()
}

A razão é queSQLitenão recupera o espaço ocupado ao excluir dados, e precisa executarVACUUMA operação de transferência de arquivos ocorre quando esta função é chamada, e o atraso é grande, por isso é recomendado chamar em um intervalo de tempo adequado.

Não, não, não, não.

console.log

Ele é usado para a saída de informações de depuração na coluna de informação de depuração na página de negociação ao vivo.123456, oconsole.logfunção de saída de depuração de informações na página de negociação ao vivo, e, ao mesmo tempo, criar um arquivo de log com a extensão.loge escrever informações de depuração no/logs/storage/123456/no diretório do docker ao qual pertence a negociação ao vivo, com o prefixo nome do arquivostdout_.

console.log (...msgs)

O parâmetromsgé o conteúdo da saída e o parâmetromsgpodem ser passadas mais de uma. msg Falso string, number, bool, object, array, null e outros tipos suportados pelo sistema.

function main() {
    console.log("test console.log")
}
# Not supported
// Not supported
  • Apenas oJavaScriptA linguagem suporta esta função.
  • Esta função só é suportada pela negociação ao vivo, mas não por Debugging Tools ou Backtesting System.
  • A saída de um objeto é convertida para a cadeia[object Object], por isso tente produzir o maior número possível de informações legíveis.

Não, não, não, não.

console.error

Usado para saída de erro no campo Debug message na página de negociação ao vivo.123456, oconsole.errorfunção cria um arquivo de log com a extensão.logem/logs/storage/123456/diretório do docker onde o comércio ao vivo pertence, e escreve a saída de erro com o prefixostderr_.

Console.error ((...msgs)

O parâmetromsgé o conteúdo da saída e o parâmetromsgpodem ser passadas mais de uma. msg Falso string, number, bool, object, array, null e outros tipos suportados pelo sistema.

function main() {
    console.error("test console.error")
}
# Not supported
// Not supported
  • Apenas oJavaScriptA linguagem suporta esta função.
  • Esta função só é suportada pela negociação ao vivo, mas não por Debugging Tools ou Backtesting System.
  • A saída de um objeto é convertida para a cadeia[object Object], por isso tente produzir o maior número possível de informações legíveis.

Não, não, não, não.

Em termos globais Mercado