Inventor de documentação de API de quantificação

Autora:Sonhos pequenos, Criado: 2017-11-27 09:05:08, Atualizado: 2023-07-12 16:47:31

O que é mais importante, é que o sistema de vigilância do EventLoop não foi lançado antes de os dados terem sido recebidos, e os incidentes foram perdidos. // A menos que a primeira linha de código inicie a chamada do EventLoop ((-1) e inicie primeiro o mecanismo de escuta do EventLoop, esses eventos não serão perdidos

// Log("GetDepth:", routine_getDepth.wait()) 如果这里提前调用wait函数取出GetDepth函数并发调用的结果,此次GetDepth函数收到请求结果的事件便不会在EventLoop函数返回
var ts1 = new Date().getTime()
var ret1 = EventLoop(0)

var ts2 = new Date().getTime()
var ret2 = EventLoop(0)

var ts3 = new Date().getTime()
var ret3 = EventLoop(0)

Log("第1个并发任务完成的为:", _D(ts1), ret1)
Log("第2个并发任务完成的为:", _D(ts2), ret2)
Log("第3个并发任务完成的为:", _D(ts3), ret3)

Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())

}


```python
import time
def main():
    routine_getTicker = exchange.Go("GetTicker")
    routine_getDepth = exchange.Go("GetDepth")
    routine_getTrades = exchange.Go("GetTrades")
    
    ts1 = time.time()
    ret1 = EventLoop(0)
    
    ts2 = time.time()
    ret2 = EventLoop(0)
    
    ts3 = time.time()
    ret3 = EventLoop(0)
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1)
    Log("第2个并发任务完成的为:", _D(ts2), ret2)
    Log("第3个并发任务完成的为:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
void main() {
    auto routine_getTicker = exchange.Go("GetTicker");
    auto routine_getDepth = exchange.Go("GetDepth");
    auto routine_getTrades = exchange.Go("GetTrades");
    
    auto ts1 = Unix() * 1000;
    auto ret1 = EventLoop(0);
    
    auto ts2 = Unix() * 1000;
    auto ret2 = EventLoop(0);
    
    auto ts3 = Unix() * 1000;
    auto ret3 = EventLoop(0);
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1);
    Log("第2个并发任务完成的为:", _D(ts2), ret2);
    Log("第3个并发任务完成的为:", _D(ts3), ret3);
    
    Ticker ticker;
    Depth depth;
    Trades trades;
    routine_getTicker.wait(ticker);
    routine_getDepth.wait(depth);
    routine_getTrades.wait(trades);
    
    Log("GetTicker:", ticker);
    Log("GetDepth:", depth);
    Log("GetTrades:", trades);
}

Funções embutidas

_G(K, V)

_G(K, V)A função permite um dicionário global salvável, com suporte para rastreamento e disco físico. Após o rastreamento, os dados salvos são eliminados. A estrutura de dados éKVA tabela é um arquivo local permanentemente mantido, com um banco de dados separado para cada disco, que permanece após o reinicio ou o desligamento do administrador.KA maioria dos usuários não tem acesso ao site, mas a maioria não tem acesso ao site.VPode ser para qualquer coisa.JSONConteúdo serializado._G()Quando a função não transmite nenhum parâmetro, a função não é executada._G()A função retorna o disco real atual.ID

function main(){
    // 设置一个全局变量num,值为1
    _G("num", 1)     
    // 更改一个全局变量num,值为字符串ok
    _G("num", "ok")    
    // 删除全局变量num
    _G("num", null)
    // 返回全局变量num的值
    Log(_G("num"))
    // 删除所有全局变量
    _G(null)
    // 返回实盘ID
    var robotId = _G()
}
def main():
    _G("num", 1)     
    _G("num", "ok")    
    _G("num", None)
    Log(_G("num"))
    _G(None)
    robotId = _G()
void main() {
    _G("num", 1);
    _G("num", "ok");
    _G("num", NULL);
    Log(_G("num"));
    _G(NULL);
    // 不支持 auto robotId = _G();
}

Atenção: Utilização_GQuando os dados são armazenados com duração funcional, devem ser usados de forma razoável, de acordo com a memória e o espaço no disco rígido do dispositivo de hardware, e não devem ser abusados.Desgaste de memóriaA questão é:

_D ((Tempestamp, Fmt)

_D(Timestamp, Fmt), Retorna a cadeia de tempo correspondente a um botão de tempo especificado.TimestampPara o tipo de valor numérico, o valor é milissegundos.FmtPara o tipo de strings,FmtO que você acha?yyyy-MM-dd hh:mm:ss, retorna o valor: tipo de string. Devolve a string correspondente a um fuso de tempo especificado (millisecondes), sem passar nenhum parâmetro, devolvendo o tempo atual; por exemplo:_D()Ou_D(1478570053241)O formato padrão é:yyyy-MM-dd hh:mm:ss

function main(){
    var time = _D()
    Log(time)
}
def main():
    strTime = _D()
    Log(strTime)
void main() {
    auto strTime = _D();
    Log(strTime);
}

Atenção:PythonUtilização estratégica_D()Quando o tempo de entrada é igual a um segundo, é necessário ter em mente que o parâmetro de entrada é o ponto de tempo de nível de segundo.JavaScriptC++A estratégia é de tempo de milissegundos, 1 segundo é igual a 1000 milissegundos). Usado em disco real_D()Quando a função analisa uma barra de tempo como uma string de tempo legível, é necessário prestar atenção ao fuso horário do sistema operacional onde o programa administrador está localizado._D()A função analisa um cronograma como uma cadeia de tempo legível definida em função do tempo do sistema administrador.

Por exemplo, um fuso horário é1574993606000Com o código de análise:

function main() {
    Log(_D(1574993606000))
}
def main():
    # 北京时间的服务器上运行:2019-11-29 10:13:26 ,另一台其它地区的服务器上的托管者运行此代码结果则为:2019-11-29 02:13:26
    Log(_D(1574993606))
void main() {
    Log(_D(1574993606000));
}

_N ((Num, Precisão)

_N(Num, Precision), formatear um ponto flutuante.NumPara o tipo de valor,PrecisionPara inteiro. Retorna valor: tipo numérico.

Por exemplo:_N(3.1415, 2)Será removido3.1415O valor de dois dígitos após o decimal é devolvido.3.14

function main(){
    var i = 3.1415
    Log(i)
    var ii = _N(i, 2)
    Log(ii)
}
def main():
    i = 3.1415
    Log(i)
    ii = _N(i, 2)
    Log(ii)
void main() {
    auto i = 3.1415;
    Log(i);
    auto ii = _N(i, 2);
    Log(ii);
}

Se quisermos transformar todos os n dígitos à esquerda do decimal em 0, podemos escrever:

function main(){
    var i = 1300
    Log(i)
    var ii = _N(i, -3)
    // 查看日志得知为1000
    Log(ii)
}
def main():
    i = 1300
    Log(i)
    ii = _N(i, -3)
    Log(ii)
void main() {
    auto i = 1300;
    Log(i);
    auto ii = _N(i, -3);
    Log(ii);
}

- O quê?

_C(function, args...)A função é chamada de função de reinicialização e é usada para obter transações, obter pedidos não concluídos e outros erros de interface.

A interface continua a chamar a função especificada até que retorne com sucesso o parâmetro (().functionQuando a função referida é chamada, ela retorna um valor em branco oufalseO usuário pode tentar ligar novamente) ^ por exemplo._C(exchange.GetTicker)A diferença é que, por defeito, o intervalo de repetição é de 3 segundos._CDelay(...)Funções para definir intervalos de retest, como_CDelay(1000)A mudança_CO intervalo de reexame da função é de 1 segundo.

Para as seguintes funções:

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPosition()

Todos podem ser aprovados_C(...)A função é chamada para permitir erros._C(function, args...)Funções não limitadas a funções erroneas listadas acima, parametrosfunctionÉ uma referência de função e não uma chamada de função._C(exchange.GetTicker)Não é_C(exchange.GetTicker())

function main(){
    var ticker = _C(exchange.GetTicker)
    // 调整_C()函数重试时间间隔为2秒
    _CDelay(2000)
    var depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
}
def main():
    ticker = _C(exchange.GetTicker)
    _CDelay(2000)
    depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
void main() {
    auto ticker = _C(exchange.GetTicker);
    _CDelay(2000);
    auto depth = _C(exchange.GetDepth);
    Log(ticker);
    Log(depth);
}

Funções com parâmetros_C(...)Quando se erra:

function main(){
    var records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
}
def main():
    records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
void main() {
    auto records = _C(exchange.GetRecords, PERIOD_D1);
    Log(records);
}

Também pode ser usado para lidar com erros de funções personalizadas:

var test = function(a, b){
    var time = new Date().getTime() / 1000
    if(time % b == 3){
        Log("符合条件!", "#FF0000")
        return true
    }
    Log("重试!", "#FF0000")
    return false
}

function main(){
    var ret = _C(test, 1, 5)
    Log(ret)
}
import time
def test(a, b):
    ts = time.time()
    if ts % b == 3:
        Log("符合条件!", "#FF0000")
        return True
    Log("重试!", "#FF0000")
    return False

def main():
    ret = _C(test, 1, 5)
    Log(ret)
// C++ 不支持这种方式对于自定义函数容错

_Cross ((Arr1, Arr2)

_Cross(Arr1, Arr2)Retorna a matrizarr1earr2O número de períodos de cruzamento de um conjunto de valores. Os números positivos são os períodos de cruzamento, os números negativos são os períodos de cruzamento, 0 é o mesmo preço atual.

Podemos simular um conjunto de testes de dados_Cross(Arr1, Arr2)Função:

// 快线指标
var arr1 = [1,2,3,4,5,6,8,8,9]
// 慢线指标
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]     
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
    vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
    vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}

img

Visualizar os dados simulados para observação

img

Informações específicas sobre o uso:Função embutida_Cross Análise e instruções de uso

JSONParse ((strJson)

JSONParse(strJson)Esta função é usada para paralisar as strings JSON. Pode ser usada para paralisar corretamente as strings JSON que contêm valores maiores.

function main() {
    let s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("JSON.parse:", JSON.parse(s1))    // JSON.parse: {"num":8.754613216564988e+39}
    Log("JSONParse:", JSONParse(s1))      // JSONParse:  {"num":"8754613216564987646512354656874651651358"}
    
    let s2 = '{"num": 123}'
    Log("JSON.parse:", JSON.parse(s2))    // JSON.parse: {"num":123}
    Log("JSONParse:", JSONParse(s2))      // JSONParse:  {"num":123}
}
import json

def main():
    s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("json.loads:", json.loads(s1))    # json.loads: map[num:8.754613216564987e+39]
    Log("JSONParse:", JSONParse(s1))      # JSONParse:  map[num:8754613216564987646512354656874651651358]
    
    s2 = '{"num": 123}'
    Log("json.loads:", json.loads(s2))    # json.loads: map[num:123]
    Log("JSONParse:", JSONParse(s2))      # JSONParse:  map[num:123]
void main() {
    auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
    Log("json::parse:", json::parse(s1));
    // Log("JSONParse:", JSONParse(s1));   // 不支持该函数
    
    auto s2 = "{\"num\":123}";
    Log("json::parse:", json::parse(s2));
    // Log("JSONParse:", JSONParse(s2));   // 不支持该函数
}

Cores personalizadas

Todas as strings de mensagens podem ser usadas#ff0000Este valor RGB é o final, representando a visão de frente que deve ser exibida.#ff0000112233O formato é o seguinte: os últimos seis números representam a cor do fundo.

function main() {
    Log("红色", "#FF0000")
}
def main():
    Log("红色", "#FF0000")
void main() {
    Log("红色", "#FF0000");
}

Informações do diário

As informações de logs são gravadas no banco de dados do disco real quando o disco real é executado.sqlite3Base de dados, arquivo de banco de dados em disco físico no dispositivo onde o programa administrador está, arquivo de banco de dados no programa administradorrobotPor exemplo: ID para130350O arquivo do banco de dados do disco real está em../logs/storage/130350Neste catálogo..Ou seja,robotO arquivo de banco de dados é chamado130350.db3Não, não. Os registros no sistema de retrospecção podem ser fechados após a retrospecção, clicando no canto inferior direito da página.Baixe o diárioO botão ] para fazer o download. Quando é necessário migrar o disco para outro servidor, o administrador pode mover o arquivo de banco de dados do disco (extenção chamada de arquivo de banco de dados db3) para o servidor de destino para a migração, definindo o nome do arquivo como o ID de disco correspondente na plataforma. Assim, todas as informações de registro do disco anterior não serão perdidas ao migrar para o novo dispositivo.

Registo ((...)

Log(message), salvar uma mensagem para a lista de diários.messagePode ser de qualquer tipo. Se você adicionar depois de uma linha@A mensagem é enviada para a fila de push e é enviada para o e-mail, Telegram, WebHook, etc. configurado na configuração de push da conta do inventor atual.Centro de ControlePágina, canto superior direitoConfiguração da contaA página do Facebook:Configuração de pushA página está ligada).

Atenção:

  • A ferramenta de depuração não oferece suporte ao push.
  • O "sistema de retrospecção" não suporta o "push".
function main() {
    Log("发明者量化你好 !@")
    Sleep(1000 * 5)
    // 字符串内加入#ff0000,打印日志显示为红色,并且推送消息
    Log("你好, #ff0000@")
}
def main():
    Log("发明者量化你好 !@")
    Sleep(1000 * 5)
    Log("你好, #ff0000@")
void main() {
    Log("发明者量化你好 !@");
    Sleep(1000 * 5);
    Log("你好, #ff0000@");
}

WebHookEmpurra:

UtilizaçãoGolangO serviço DEMO foi escrito por:

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

ConfiguraçãoWebHookhttp://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ

Após a execução do serviço, executar a estratégia, a estratégia empurra informações:

function main() {
    Log("msg", "@")
}
def main():
    Log("msg", "@")
void main() {
    Log("msg", "@");
}

O programa de serviço imprime a seguinte informação:

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}

Impressãobase64Imagens codificadas LogFunções de impressãobase64A imagem foi codificada para ser usada como um`Começou com:`A conclusão, por exemplo:

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

LogSuporte para impressão diretaPythonNão.matplotlib.pyplotObjeto, desde que o objeto contenhasavefigO método é direto.LogA imprensa, por exemplo:

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

O registro de impressão é automaticamente mudado para o idioma LogA função suporta a troca de idiomas.LogA função produz texto que é automaticamente trocado para o idioma correspondente com base no idioma definido na página da plataforma, por exemplo:

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

LogProfit ((Profit)

LogProfit(Profit), registar os lucros e prejuízos, imprimir os lucros e prejuízos e traçar uma curva de ganhos com base nos lucros e prejuízos; valor do parâmetro:LucroPara o tipo de valor numérico.

A função pode ser executada com caracteres.&No final, apenas desenhe um gráfico de receita e não imprima um diário de receita, por exemplo:LogProfit(10, '&')

LogProfitReset (em inglês)

LogProfitReset(), para limpar todos os registros de ganhos, pode usar um parâmetro inteiro para especificar o número de entradas reservadas.

function main() {
    // 在收益图表上打印30个点,然后重置,只保留最后10个点
    for(var i = 0; i < 30; i++) {
        LogProfit(i)
        Sleep(500)
    }
    LogProfitReset(10)
}
def main():
    for i in range(30):
        LogProfit(i)
        Sleep(500)
    LogProfitReset(10)
void main() {
    for(int i = 0; i < 30; i++) {
        LogProfit(i);
        Sleep(500);
    }
    LogProfitReset(10);
}

LogStatus ((Msg)

LogStatus(Msg)Esta informação não é guardada na lista de logs, apenas atualiza a informação de estado do disco real atual, que é exibida no bar de estado acima da área de logs da página do disco real.MsgPode ser de qualquer tipo.

function main() {
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
}
def main():
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
void main() {
    LogStatus("这是一个普通的状态提示");
    LogStatus("这是一个红色字体的状态提示#ff0000");
    LogStatus("这是一个多行的状态信息\n我是第二行");
}

LogStatus(Msg)Suporte para impressãobase64A imagem foi codificada para ser usada como um`Começou com:`A conclusão, por exemplo:LogStatus("`data:image/png;base64,AAAA`")LogStatus(Msg)Suporte para transmissão diretaPythonNão.matplotlib.pyplotObjeto, desde que o objeto contenhasavefigO método pode ser transmitido.LogStatus(Msg)Funções, por exemplo:

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

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

function main() {
    var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    // JSON序列化后两边加上`字符,视为一个复杂消息格式(当前支持表格)
    LogStatus('`' + JSON.stringify(table) + '`')                    
    // 表格信息也可以在多行中出现
    LogStatus('第一行消息\n`' + JSON.stringify(table) + '`\n第三行消息')
    // 支持多个表格同时显示,将以TAB显示到一组里
    LogStatus('`' + JSON.stringify([table, table]) + '`')
    
    // 也可以构造一个按钮在表格中,策略用GetCommand接收cmd属性的内容                                
    var table = { 
        type: 'table', 
        title: '持仓操作', 
        cols: ['列1', '列2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
        ]
    }
    LogStatus('`' + JSON.stringify(table) + '`') 
    // 或者构造一单独的按钮
    LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': '平仓'}) + '`') 
    // 可以自定义按钮风格(bootstrap的按钮属性)
    LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': '平仓'}) + '`')
}
import json
def main():
    table = {"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('第一行消息\n`' + json.dumps(table) + '`\n第三行消息')
    LogStatus('`' + json.dumps([table, table]) + '`')

    table = {
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    }
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "平仓"}) + '`')
    LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"}) + '`')
void main() {
    json table = R"({"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("第一行消息\n`" + table.dump() + "`\n第三行消息");
    json arr = R"([])"_json;
    arr.push_back(table);
    arr.push_back(table);
    LogStatus("`" + arr.dump() + "`");

    table = R"({
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    })"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
    LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
}

Desativar o botão do botão de estado, descrever funções:

img

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮的禁用、描述功能测试",
        cols: ["列1", "列2", "列3"], 
        rows: []
    }
    var button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    var button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true}
    var button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": false}
    table.rows.push([button1, button2, button3])
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    }
    button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": True}
    button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": False}
    table["rows"].append([button1, button2, button3])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    })"_json;
    json button1 = R"({"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"})"_json;
    json button2 = R"({"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true})"_json;
    json button3 = R"({"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "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() + "`");
}

Configuração do estilo do botão de estado:

img

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮样式",
        cols: ["默认", "原始", "成功", "信息", "警告", "危险"], 
        rows: [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    })"_json;
    LogStatus("`" + table.dump() + "`");
}

CombinaçãoGetCommand()Funções, configuração e interação do botão de estado:

function test1() {
    Log("调用自定义函数")
}

function main() {
    while (true) {
        var table = {
            type: 'table',
            title: '操作',
            cols: ['列1', '列2', 'Action'],
            rows: [
                ['a', '1', {
                    'type': 'button',                       
                    'cmd': "CoverAll",                      
                    'name': '平仓'                           
                }],
                ['b', '1', {
                    'type': 'button',
                    'cmd': 10,                              
                    'name': '发送数值'
                }],
                ['c', '1', {
                    'type': 'button',
                    'cmd': _D(),                          
                    'name': '调用函数'
                }],
                ['d', '1', {
                    'type': 'button',
                    'cmd': 'test1',       
                    'name': '调用自定义函数'
                }]
            ]
        }
        LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')

        var str_cmd = GetCommand()
        if (str_cmd) {
            Log("接收到的交互数据 str_cmd:", "类型:", typeof(str_cmd), "值:", str_cmd)
            if(str_cmd == "test1") {
                test1()
            }
        }

        Sleep(500)
    }
}
import json
def test1():
    Log("调用自定义函数")

def main():
    while True:
        table = {
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": _D(),
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        }

        LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
        str_cmd = GetCommand()
        if str_cmd:
            Log("接收到的交互数据 str_cmd", "类型:", type(str_cmd), "值:", str_cmd)
            if str_cmd == "test1":
                test1()
        Sleep(500)
void test1() {
    Log("调用自定义函数");
}

void main() {
    while(true) {
        json table = R"({
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": "",
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        })"_json;
        table["rows"][2][2]["cmd"] = _D();
        LogStatus(_D(), "\n", "`" + table.dump() + "`");
        auto str_cmd = GetCommand();
        if(str_cmd != "") {
            Log("接收到的交互数据 str_cmd", "类型:", typeid(str_cmd).name(), "值:", str_cmd);
            if(str_cmd == "test1") {
                test1();
            }
        }
        Sleep(500);
    }
}

Os botões do botão de estado de construção também suportam a entrada de dados quando interagem, e os instruções de interação são finalmente executadas por um botão de estado de construção.GetCommand()Captura de funções. Aumentar a estrutura de dados do controle do botão no painel de statusinputExemplo:{"type": "button", "cmd": "open", "name": "开仓"}Aumentar"input": {"name": "开仓数量", "type": "number", "defValue": 1}O botão pode ser clicado para criar uma janela pop-up com um controle de caixa de entrada (o valor padrão da caixa de entrada é 1, ou seja, dados definidos como defValue), que pode ser enviado junto com um comando de botão. Por exemplo, quando o código de teste abaixo é executado, uma janela pop-up com um controle de caixa de entrada é exibida após clicar no botão "Open Stock" e é inserida na caixa de entrada.111A partir daí, clique em "Confirm".GetCommandA função captura a mensagem:open:111

function main() {
    var tbl = {
        type: "table",
        title: "操作",
        cols: ["列1", "列2"],
        rows: [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ] 
    }

    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": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    }

    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": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    })"_json;

    LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
    while(true) {
        auto cmd = GetCommand();
        if(cmd != "") {
            Log("cmd:", cmd);
        }
        Sleep(1000);
    }
}

FusãoLogStatus(Msg)Celas dentro de uma tabela desenhada pela função:

  • Fusão horizontal

    function main() {
        var table = { 
            type: 'table', 
            title: '持仓操作', 
            cols: ['列1', '列2', 'Action'], 
            rows: [ 
                ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
            ]
        } 
        var ticker = exchange.GetTicker()
        // 添加一行数据,第一个和第二个单元格合并,并且输出ticker变量在合并后的单元格内
        table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"])    
        LogStatus('`' + JSON.stringify(table) + '`')
    }
    
    import json
    def main():
        table = {
            "type" : "table",
            "title" : "持仓操作",
            "cols" : ["列1", "列2", "Action"],
            "rows" : [
                ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
            ]
        }
        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" : "持仓操作",
            "cols" : ["列1", "列2", "Action"],
            "rows" : [
                ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
            ]
        })"_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() + "`");
    }
    

  • Fusão vertical

    function main() {
        var table = { 
            type: 'table', 
            title: '表格演示', 
            cols: ['列A', '列B', '列C'], 
            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被上一行第一个单元格合并
        table.rows.push(["B4", "C4"])
        // A2被上一行第一个单元格合并
        table.rows.push(["B5", "C5"])                                            
        table.rows.push(["A6", "B6", "C6"])
        LogStatus('`' + JSON.stringify(table) + '`')
    }
    
    import json
    def main():
        table = {
            "type" : "table", 
            "title" : "表格演示", 
            "cols" : ["列A", "列B", "列C"], 
            "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" : "表格演示", 
            "cols" : ["列A", "列B", "列C"], 
            "rows" : [
                ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
            ]
        })"_json;
        // 为了测试,代码简短易读,这里使用构造的数据
        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() + "`");
    }
    

O compartilhamento de páginas do quadro de status mostra:

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

img

Além de ser possível exibir o formulário em páginas separadas, pode-se exibir vários formulários ordenados de cima para baixo.

function main(){
    var tab1 = {
        type : "table",
        title : "表格1",
        cols : ["1", "2"],
        rows : []
    }
    var tab2 = {
        type : "table",
        title : "表格2",
        cols : ["1", "2", "3"],
        rows : []
    }
    var tab3 = {
        type : "table",
        title : "表格3",
        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": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    }
    tab2 = {
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    }
    tab3 = {
        "type": "table", 
        "title": "表格3", 
        "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": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    })"_json;
    json tab2 = R"({
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    })"_json;
    json tab3 = R"({
        "type": "table", 
        "title": "表格3", 
        "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() + "`");
}

O efeito de execução:

Atenção: Quando a política é executada no disco real, se a página do disco real for revistada, a barra de estado irá para o estado de sono e parar de ser atualizada. Suporte para exportação em barras de estadobase64Imagens codificadas, que também suportam a exportação para a tabela exibida na barra de statusbase64Imagens codificadas. As imagens codificadas não exibem mais o código de exemplo, já que as strings de dados das imagens codificadas são geralmente longas.

AtivarLog()

EnableLog(IsEnable)Registro de logs de informações de encomendas abertas ou fechadas.isEnablePara o tipo Boole.IsEnableConfiguraçãofalseA partir de agora, o site não irá imprimir o registro de pedidos e não será gravado em um banco de dados real.

Gráfico ((...)

Chart(...), função de desenho gráfico personalizado.

Chart({...})O parâmetro é:JSONSequenciadoAumento dos estoquesNão.Highcharts.StockChartParâmetros.__isStockPropriedade, se for especificado__isStock:falseO gráfico é mostrado como um gráfico normal.

Atenção: Se for definido__isStockPropriedadefalseO gráfico usado é:Highcharts (Highcharts)A foto abaixo mostra:

Highcharts图表

Se for definido__isStockPropriedadetrueO gráfico usado é:Resíduos pesados(Default)__isStockParatrueO que é que ele está a fazer?

Highstocks图表

Voltar para o que você pode chamaradd(n, data)nParaseriesO índice (por exemplo 0),dataPara grafar dados) para o índice especificadoseriesAdicionar dados, fazer chamadasreset()O que é que isso significa para mim?resetPode-se usar um parâmetro numérico para especificar o número de itens reservados.

Pode ser chamadoadd(n, data, i)iOs dados estão emseriesPara alterar a correspondenteseriesOs dados do site também estão disponíveis.

Pode ser negativo, -1 é o último, -2 é o segundo decimal, por exemplo, quando se desenha uma linha, modificando os dados no último ponto da linha:

chart.add(0, [1574993606000, 13.5], -1)Mudançaseries[0].dataO primeiro ponto do decimal é o dado.

Suporte para exibir vários gráficos, basta inserir parâmetros de matriz para configurar:var chart = Chart([{...}, {...}, {...}])Por exemplo, um gráfico tem dois.seriesO gráfico 2 tem umaseriesO gráfico 3 tem umaseriesEntão,addQuando se especifica que o ID da sequência 0 e 1 representa os dados das duas sequências do gráfico 1 atualizado,addQuando o ID da seqüência é especificado como 2 indica o primeiro da tabela 2.seriesA sequência 3 é a primeira sequência do gráfico 3.seriesOs dados mostram que o número de pessoas que morrem é muito alto.

HighStockshttp://api.highcharts.com/highstock

Os gráficos mostram algumas configurações de propriedades relacionadas:Exemplos

Por exemplo, os objetos de configuração de gráficos:

var cfgA = {
    extension: {
        // 不参于分组,单独显示,默认为分组 'group'
        layout: 'single', 
        // 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
        height: 300,      
        // 指定宽度占的单元值,总值为12
        col: 8            
    },
    title: {
        text: '盘口图表'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '买一',
        data: []
    }, {
        name: '卖一',
        data: []
    }]
}

var cfgB = {
    title: {
        text: '差价图'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '差价',
        type: 'column',
        data: []
    }]
}

var cfgC = {
    __isStock: false,
    title: {
        text: '饼图'
    },
    series: [{
        type: 'pie',
        name: 'one',
        // 指定初始数据后不需要用add函数更新,直接更改图表配置就可以更新序列
        data: [                    
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]                
    }]
}

var cfgD = {
    extension: {
        layout: 'single',
        // 指定宽度占的单元值,总值为12
        col: 8,                    
        height: '300px'
    },
    title: {
        text: '盘口图表'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '买一',
        data: []
    }, {
        name: '卖一',
        data: []
    }]
}

var cfgE = {
    __isStock: false,
    extension: {
        layout: 'single',
        col: 4,
        height: '300px'
    },
    title: {
        text: '饼图2'
    },
    series: [{
        type: 'pie',
        name: 'one',
        data: [
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]
    }]
}
cfgA = {
    "extension" : {
        "layout" : "single", 
        "height" : 300,
        "col" : 8
    }, 
    "title" : {
        "text" : "盘口图表"
    },
    "xAxis" : {
        "type" : "datetime" 
    }, 
    "series" : [{
        "name" : "买一",
        "data" : []
    }, {
        "name" : "卖一", 
        "data" : []
    }]
}    

cfgB = {
    "title" : {
        "text" : "差价图"
    }, 
    "xAxis" : {
        "type" : "datetime"
    }, 
    "series" : [{
        "name" : "差价", 
        "type" : "column", 
        "data" : []
    }]
}    

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

cfgD = {
    "extension" : {
        "layout" : "single",
        "col" : 8,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "盘口图表"
    }, 
    "series" : [{
        "name" : "买一", 
        "data" : []
    }, {
        "name" : "卖一",
        "data" : []
    }]
}    

cfgE = {
    "__isStock" : False, 
    "extension" : {
        "layout" : "single", 
        "col" : 4,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "饼图2"
    },
    "series" : [{
        "type" : "pie",
        "name" : "one", 
        "data" : [
            ["A", 25], 
            ["B", 25], 
            ["C", 25], 
            ["D", 25]
        ]
    }]
}
json cfgA = R"({
    "extension" : {
        "layout" : "single", 
        "height" : 300,
        "col" : 8
    }, 
    "title" : {
        "text" : "盘口图表"
    },
    "xAxis" : {
        "type" : "datetime" 
    }, 
    "series" : [{
        "name" : "买一",
        "data" : []
    }, {
        "name" : "卖一", 
        "data" : []
    }]
})"_json;    

json cfgB = R"({
    "title" : {
        "text" : "差价图"
    }, 
    "xAxis" : {
        "type" : "datetime"
    }, 
    "series" : [{
        "name" : "差价", 
        "type" : "column", 
        "data" : []
    }]
})"_json;    

json cfgC = R"({
    "__isStock" : false,
    "title" : {
        "text" : "饼图"
    }, 
    "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" : "盘口图表"
    }, 
    "series" : [{
        "name" : "买一", 
        "data" : []
    }, {
        "name" : "卖一",
        "data" : []
    }]
})"_json;    

json cfgE = R"({
    "__isStock" : false, 
    "extension" : {
        "layout" : "single", 
        "col" : 4,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "饼图2"
    },
    "series" : [{
        "type" : "pie",
        "name" : "one", 
        "data" : [
            ["A", 25], 
            ["B", 25], 
            ["C", 25], 
            ["D", 25]
        ]
    }]
})"_json;
  • cfgA.extension.layoutAtribuições

    Se esta propriedade for definida como "single", os gráficos não serão sobrepostos (não serão exibidos em etiquetas separadas) e serão exibidos separadamente (exibidos em plano).

  • cfgA.extension.heightAtribuições

    Esta propriedade é usada para definir a altura do gráfico, que pode ser definida como um tipo de valor numérico ou como "300px".

  • cfgA.extension.colAtribuições

    Esta propriedade é usada para definir a largura do gráfico, dividindo a largura da página em 12 unidades, e definir 8 para que o gráfico tenha 8 unidades de largura.

    A estratégia do paradigma completo:

    Os objetos de configuração de gráficos no exemplo acima mostram o efeito:

  • Os dados nos objetos de configuração do gráfico são atualizados para atualizar os dados, alterando diretamente a configuração do gráfico e atualizando o gráfico:

    Por exemplo:JavaScriptParágrafo de código parcial do exemploExemplo completo):

    cfgC.series[0].data[0][1] = Math.random() * 100
    cfgE.series[0].data[0][1] = Math.random() * 100
    // update实际上等于重置了图表的配置
    chart.update([cfgA, cfgB, cfgC, cfgD, cfgE])
    

    AprovaçãoaddMétodos de atualização de dados, como adicionar um item a um gráfico de biscoitos.JavaScriptParágrafo de código parcial do exemploExemplo completo):

    // 为饼图增加一个数据点,add只能更新通过add方式添加的数据点,内置的数据点无法后期更新
    chart.add(3, {
        name: "ZZ",
        y: Math.random() * 100
    })
    
  • Utilização complementarChartExemplos de funções

    Um exemplo simples de gráfico:

    // 这个chart在JavaScript语言中是对象,在使用Chart函数之前我们需要声明一个配置图表的对象变量chart
    var chart = {                                           
        // 该字段标记图表是否为一般图表,有兴趣的可以改成false运行看看
        __isStock: true,                                    
        // 缩放工具
        tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},    
        // 标题
        title : { text : '差价分析图'},                       
        // 选择范围
        rangeSelector: {                                    
            buttons:  [{type: 'hour',count: 1, text: '1h'}, {typ

Mais.

QQ89520Um problema é se a função C vai tentar novamente ou apenas uma vez.

Ai, ai!_C ((function, args...) é o padrão de 3s? Modificar o padrão para colocar diretamente _CDelay ((1000) antes de _C ((function, args...)?

lanchaiyeCluster: se você criar 1000 robôs em simultâneo, sem qualquer pressão, você pode criar vários administradores para distribuir tarefas. Há exemplos de código para criar clusters? Como criar vários administradores para descentralizar tarefas?

- O que é?Log ((talib.help (('MACD')); só pode ser usado em js, Python não tem a propriedade talib.help...

Cjz140O que é que a diferença entre a função _C (função, args...) e a função Sleep?

3263243yComo limpar o ErrorFilter após o SetErrorFilter? sem filtrar mensagens de erro.

QQ47898077Se você quiser usar uma biblioteca de terceiros, há alguma maneira de fazer isso?

QQ47898077O que deve ser preenchido pela classe pai se quisermos herdar uma nova classe definida pelo objeto da bolsa?

ethanwuHá ferramentas de depuração locais?

PenglihengO que é exange.IO (status)?

PenglihengPor que a função sell está em cinza, ou a função de representação não está disponível?

PenglihengPor que a função sell está em cinza, ou a função de representação não está disponível?

PenglihengEu não sei inglês, haha, mas gostaria de saber se o es6 é compatível.

PenglihengEu não sei inglês, haha, mas gostaria de saber se o es6 é compatível.

Don.Como escrever a linha média do volume?

ZjuturtleSe você comprar no exchange.Buy (Buy) 1000 pelo preço de mercado, o que você receberá se não for bem sucedido?

Minha filhaEssa nova fonte é linda.

hipopótamoA rede de testes da Bitmex (testnet.bitmex.com) também possui uma interface API, mas atualmente as bolsas só podem selecionar o terminal Bitmex. O endereço do documento API é https://testnet.bitmex.com/app/apiOverview. Por favor, como apoiar?

- Não, não.Var ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); Log (('ok futures estimado preço de entrega', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png O que é que acontece quando um usuário faz uma chamada para uma interface de outras exchanges e escreve uma mensagem de erro?

allenfrostlineA diferença entre realTicker e Ticker é que o realTicker é um software que funciona como um conjunto de ferramentas, mas que não parece ser mencionado na primeira API.

visõesOlá, como desenvolvedor de Python, o que você acha que a sua documentação API está escrevendo?

allenfrostlineGetAccount: [EAPI: Rate limit exceeded] Gostaria de saber como resolver isso?

zhjx2314Não tem suporte para StochRSI, pode ser adicionado logo?

YhfggO script está em seu próprio servidor da nuvem Ali ou no botvs cluster?

YhfggQual é a versão do Python?

FkyslyA interpretação do GetFee deve ser que o getFee retorna uma estrutura de getFee, menos um composto.

ZkwapComo usar o jss para chamar o talib?

YhfggPeça documentação Python

Wmjbs123O fundo do código para a edição de estratégias pode ser preto? Olhos pontiagudos brancos, código escrito à noite, fácil de miopia

Don.Como é que se pode configurar o sumário no bot WeChat?

Número: loucoPode-se adicionar um campo de preço igual na estrutura da ordem?

PequenoGetOrders: Retorna todos os pedidos incompletos, retorna uma estrutura de ordem de arquivo, na China Bitcoin transação ETH, retorna apenas os últimos 10 itens, aqui há uma função que retorna todos os pedidos incompletos da China Bitcoin ETH, o que significa que outras plataformas podem retornar tudo com GetOrders, só que este fantasma da China Bitcoin retorna 10 itens, o que significa que você pode usar GetOrders para retornar todos os pedidos incompletos.

YhfggA função matemática que é necessária para a probabilidade estatística, onde é que ela é usada?

JiebangQual é o significado do valor que a função $.Cross ((x, y) retorna?

A minha tia chamava-meO LogReset limpa todos os registros e pode ter um parâmetro numérico para especificar o número de registros reservados. Como é que isso elimina os últimos registos?

Edward GywA função CORRE no talib parece não ter sido transplantada ou foi perdida?

A montanha pobre de LiuyangParece que não há função de referência de indicadores!

PequenoComo é que o tempo de leitura da linha k traduz para o tempo presente?

PequenoComo escrever o número de um arquivo para removê-lo, eu acho que isso não funciona com records.remove ((records[0])

SerpenteA linha K da hora é normalmente obtida, mas como chamar ATR da linha K do dia?

SerpenteA linha K da hora é normalmente obtida, mas como chamar ATR da linha K do dia?

57278863Aprenda como os futuros tradicionais recebem preços e compras, desculpe, a base é tênue.

KirinO exemplo de negociação de futuros tradicionais!

Pequenozero, pode escrever um exemplo de negociação de futuros tradicionais?

PequenoComo imprimir o estado de armazenamento de vários blocos vazios ao mesmo tempo, como imprimir meu objeto, como obter o estado de armazenamento de vários blocos e blocos vazios, e também GetTicker, como obter o preço da semana, da próxima semana e do trimestre.

- Não, não.As bolsas de futuros podem usar o GetTicker para obter transações?

Venda em massaO StochRSI é um indicador que pode ser adicionado?

MomoxCancelOrder ((orderId) cancelar um pedido com base no número da ordem, retornar true ou false, por favor, pergunte true= a célula foi cancelada com sucesso, certo?

Momox_G(K, V) Lista de dicionários globais que podem ser salvos Este método armazena variáveis globais que podem ser usadas para compartilhar dados entre diferentes políticas?

Fluffy3dA popularidade

Zero.O registro de ganhos pode ser reiniciado com o LogProfitReset. O histórico do gráfico de ganhos anterior desaparece.

xyPode-se copiar o EA diretamente?

SJIRONMANEu sinto que a plataforma é ótima, muito boa, muito mais interação em grupo.

PequenoO que é essa língua, há material para aprender?

jxhbtcData error: uma semana sem conectar o robô.

- O quê?O banco de dados TA é apenas para calcular o preço de fechamento?

btcrobotOlá, mundo.

Sonhos pequenosA função _C tentará novamente sem pensar até obter um resultado.

Sonhos pequenosA biblioteca talib do python precisa ser instalada. https://www.botvs.com/bbs-topic/669 pode ser consultado neste post.

Sonhos pequenosSleep é o número de milissegundos em que o programa não faz nada e espera que o parâmetro seja definido, _C é a função que re-chamou o parâmetro.

Sonhos pequenosSem herança, o JS é embalado diretamente no objeto {name: "novo objeto", old_exchange : exchange[0],...... }

Sonhos pequenosO editor local, o plugin de sincronização remota, basicamente, é o editor local, o decote remoto.

Sonhos pequenosPode vir ao grupo QQ, é fácil discutir.

Sonhos pequenosEm documentos da API, o significado de cinza é que a função não tem muita explicação de expansão e mostra representados em cinza e azul.

Sonhos pequenosO ES6 está fora de suporte, ^^

Sonhos pequenosEu, descreva o problema e eu vou responder ^^

Sonhos pequenosA primeira coisa que você pode fazer é fazer um pedido de compra, mas o resultado é um erro, e você não pode fazer o pedido (ou seja, comprar, não há dinheiro suficiente!).

ZjuturtlePor exemplo, OKCoin, se o volume de compras for superior ao de empréstimos, o que será o retorno?

Sonhos pequenosA questão é: em qual bolsa eu devolveria um número de ordem no OK Futures?

Zero.Já é suportado para trocar transações em tempo de execução, sendo necessário o download do mais recente host. Suporte Bter/Poloniex API detalhada documentação Descrição da função de transação abaixo (descreva se não for possível limpar o cache do navegador e atualizar se não for possível)

Sonhos pequenosQQ, eu ajudo-te a encontrar a pergunta.

Família profissionalA lista branca precisa ser definida, e eu defino o IP do host?

Sonhos pequenosEste é o link subterrâneo Não foi criado O servidor não respondeu; O endereço IP foi configurado quando o API KEY foi solicitado?

Família profissionalIsso é embaraçoso. A política que eu poderia executar foi interrompida na era do Bitcoin, e o GetAccount não conseguiu acessar o GetAccount: Post http://api.btc38.com/v1/getMyBalance.php: read tcp 192.168.0.227:58596->211.149.148.144:80: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 2017-05-23 21:08:24 Era BitEras Erro GetAccount: timeout 2017-05-23 21:08:02 Era do Bitcoin Erro GetAccount: timeout 2017-05-23 21:07:40 Bit Era Erro GetAccount: timeout 2017-05-23 21:07:20 Reiniciar É o problema da lista branca de IP???

Sonhos pequenosO servidor da bolsa não respondeu e o protocolo TCP não foi estabelecido em três apertos de mão.

Família profissionalUma tentativa de conexão falhou porque a parte conectada não respondeu adequadamente depois de um período de tempo.

Sonhos pequenosOlá! A função exchange.IO ((api, ApiName, Args) não é suportada, veja https://www.botvs.com/bbs-topic/812

Família profissionalUma tentativa de ligação falhou porque a parte ligada não respondeu adequadamente após um período de tempo,

Família profissionalA era dos bitcoins não é favorável?

Sonhos pequenoshttps://dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png O que você está fazendo é errado.

Minha filhaPor exemplo, eu queria fazer uma transação em todas as moedas do poloniex, mas apenas algumas moedas são suportadas pelo BOTvs, e o exchange.IO não parece suportar a P-Net.

Sonhos pequenosO exchange.IO pode ser chamado assim.

Minha filhaE a API que precisa de autenticação de contas?

Sonhos pequenosSe as APIs que não exigem a verificação de contas podem ser usadas com httpQuery (veja mais documentação sobre BotVS), as APIs de transações reais precisam ser acessadas.

Sonhos pequenosOs parâmetros da API podem ser transmitidos usando o HttpQuery: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd. O post: https://www.botvs.com/bbs-topic/850

visõesMuito obrigado, espero ter uma boa e perfeita documentação API.

Sonhos pequenosPor favor, onde é que a API do realTicker foi vista?

Sonhos pequenoshttps://dn-filebox.qbox.me/fe1a6f5563ed43a5357f858ecf8a50239619228e.png A documentação da API é a linguagem JavaScript. A descrição da versão em Python é publicada no topo da página de discussão da comunidade de chat chat. Se você tem alguma dúvida, é bem-vindo a escrever.

Zero.Olá, obrigado pela sugestão, a documentação da API está sendo reconstruída.

Sonhos pequenosOlá ~ mostra que a frequência de acesso ultrapassou o limite. https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png O objetivo é controlar a frequência de acesso à API, porque algumas exchanges definem um limite máximo de acesso, um certo tempo além de um certo número de visitas será recusado o acesso, bloqueando o endereço IP.

Sonhos pequenoshttps://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png O que eu escrevi pessoalmente é que os indicadores do STOCHRSI, que já foram comparados com o OK, concordam que a velocidade é um pouco lenta e precisa ser otimizada, por enquanto.

Zero.Pode escolher se o botvs fornecerá o seu servidor ou o seu servidor host, versão 2.7.5.

Sonhos pequenosAgora adicionado.

Sonhos pequenosAgora você pode configurar seu próprio estilo de fundo.

Sonhos pequenosA documentação python está sendo escrita.

Sonhos pequenosO talib é um livro que pode ser lido em português.

Hzzgood48 https://www.botvs.com/bbs-topic/276

Sonhos pequenosParece que há um exemplo na Praça da Estratégia: https://www.botvs.com/strategy/15098

Zero.Acesse a propriedade AvgPrice do Order, que é suportada pelas exchanges, e as que não são suportadas serão sempre 0

YhfggComo é que a terceira parte cita?

Zero.Se o mathjs não for capaz de satisfazer as necessidades, basta procurar políticas de importação e cópia de bibliotecas de terceiros. Para facilitar a compilação, o sistema tem apenas uma pequena quantidade de bibliotecas internas.

Sonhos pequenosNão é simpático, há um problema no grupo, pode-se M-me - eu estou basicamente online.

JiebangObrigado.

Sonhos pequenosVocê pode ver a análise de código do catálogo de transações de moeda digital na versão de notas.

Zero.Não é possível excluir o mais recente, só é possível manter alguns dos mais recentes... excluindo todos os antigos.

KirinPara obter cada posicionamento com a posição [i], a posição é um conjunto

Minha filhaexchange.GetRecords ((PERIODO_D1));

KirinO meu futuro tradicional é sempre o "GetAccount: not login", "password não errado, ou login impossível".

Zero.Por padrão, o SetContractType é necessário para obter o tipo de contrato especificado.

Zero.Como você pode ver, o verdadeiro é o valor de retorno da ação de cancelar a ordem que o exchange devolveu, mas o cancelamento real não foi cancelado, dependendo de como foi processado dentro do exchange.

Momox3q

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

XuanxuanClaro que não, isso é exclusivo do MT4.

Zero.O Javascript está em toda parte na internet.

Venda em massaO seu problema resolvido?

Zero.A maior parte do tempo, os dados podem ser transmitidos diretamente como registros ou como uma matriz de preço puro.