输入/搜索内容
内置函数
Global
Version
Sleep
IsVirtual
Mail
Mail_Go
SetErrorFilter
GetPid
GetLastError
GetCommand
GetMeta
Dial
HttpQuery
HttpQuery_Go
Encode
UnixNano
Unix
GetOS
MD5
DBExec
UUID
EventLoop
__Serve
_G
_D
_N
_C
_Cross
JSON.parse
JSON.stringify
SetChannelData
GetChannelData
Log
Market
Trade
Account
Futures
Threads
threading
Thread
getThread
mainThread
currentThread
Lock
Condition
Event
Dict
pending
Thread
ThreadLock
ThreadEvent
ThreadCondition
ThreadDict
TA
Talib
talib.CDL2CROWS
talib.CDL3BLACKCROWS
talib.CDL3INSIDE
talib.CDL3LINESTRIKE
talib.CDL3OUTSIDE
talib.CDL3STARSINSOUTH
talib.CDL3WHITESOLDIERS
talib.CDLABANDONEDBABY
talib.CDLADVANCEBLOCK
talib.CDLBELTHOLD
talib.CDLBREAKAWAY
talib.CDLCLOSINGMARUBOZU
talib.CDLCONCEALBABYSWALL
talib.CDLCOUNTERATTACK
talib.CDLDARKCLOUDCOVER
talib.CDLDOJI
talib.CDLDOJISTAR
talib.CDLDRAGONFLYDOJI
talib.CDLENGULFING
talib.CDLEVENINGDOJISTAR
talib.CDLEVENINGSTAR
talib.CDLGAPSIDESIDEWHITE
talib.CDLGRAVESTONEDOJI
talib.CDLHAMMER
talib.CDLHANGINGMAN
talib.CDLHARAMI
talib.CDLHARAMICROSS
talib.CDLHIGHWAVE
talib.CDLHIKKAKE
talib.CDLHIKKAKEMOD
talib.CDLHOMINGPIGEON
talib.CDLIDENTICAL3CROWS
talib.CDLINNECK
talib.CDLINVERTEDHAMMER
talib.CDLKICKING
talib.CDLKICKINGBYLENGTH
talib.CDLLADDERBOTTOM
talib.CDLLONGLEGGEDDOJI
talib.CDLLONGLINE
talib.CDLMARUBOZU
talib.CDLMATCHINGLOW
talib.CDLMATHOLD
talib.CDLMORNINGDOJISTAR
talib.CDLMORNINGSTAR
talib.CDLONNECK
talib.CDLPIERCING
talib.CDLRICKSHAWMAN
talib.CDLRISEFALL3METHODS
talib.CDLSEPARATINGLINES
talib.CDLSHOOTINGSTAR
talib.CDLSHORTLINE
talib.CDLSPINNINGTOP
talib.CDLSTALLEDPATTERN
talib.CDLSTICKSANDWICH
talib.CDLTAKURI
talib.CDLTASUKIGAP
talib.CDLTHRUSTING
talib.CDLTRISTAR
talib.CDLUNIQUE3RIVER
talib.CDLUPSIDEGAP2CROWS
talib.CDLXSIDEGAP3METHODS
talib.AD
talib.ADOSC
talib.OBV
talib.ACOS
talib.ASIN
talib.ATAN
talib.CEIL
talib.COS
talib.COSH
talib.EXP
talib.FLOOR
talib.LN
talib.LOG10
talib.SIN
talib.SINH
talib.SQRT
talib.TAN
talib.TANH
talib.MAX
talib.MAXINDEX
talib.MIN
talib.MININDEX
talib.MINMAX
talib.MINMAXINDEX
talib.SUM
talib.HT_DCPERIOD
talib.HT_DCPHASE
talib.HT_PHASOR
talib.HT_SINE
talib.HT_TRENDMODE
talib.ATR
talib.NATR
talib.TRANGE
talib.BBANDS
talib.DEMA
talib.EMA
talib.HT_TRENDLINE
talib.KAMA
talib.MA
talib.MAMA
talib.MIDPOINT
talib.MIDPRICE
talib.SAR
talib.SAREXT
talib.SMA
talib.T3
talib.TEMA
talib.TRIMA
talib.WMA
talib.LINEARREG
talib.LINEARREG_ANGLE
talib.LINEARREG_INTERCEPT
talib.LINEARREG_SLOPE
talib.STDDEV
talib.TSF
talib.VAR
talib.ADX
talib.ADXR
talib.APO
talib.AROON
talib.AROONOSC
talib.BOP
talib.CCI
talib.CMO
talib.DX
talib.MACD
talib.MACDEXT
talib.MACDFIX
talib.MFI
talib.MINUS_DI
talib.MINUS_DM
talib.MOM
talib.PLUS_DI
talib.PLUS_DM
talib.PPO
talib.ROC
talib.ROCP
talib.ROCR
talib.ROCR100
talib.RSI
talib.STOCH
talib.STOCHF
talib.STOCHRSI
talib.TRIX
talib.ULTOSC
talib.WILLR
talib.AVGPRICE
talib.MEDPRICE
talib.TYPPRICE
talib.WCLPRICE
OS
结构体
内置变量

在回测系统或实盘页面状态栏输出信息。

LogStatus(...msgs)

示例

  • 支持设置输出内容的颜色:

    javascript
    function main() { LogStatus('这是一个普通的状态提示') LogStatus('这是一个红色字体的状态提示#ff0000') LogStatus('这是一个多行的状态信息\n我是第二行') }
    python
    def main(): LogStatus('这是一个普通的状态提示') LogStatus('这是一个红色字体的状态提示#ff0000') LogStatus('这是一个多行的状态信息\n我是第二行')
    c++
    void main() { LogStatus("这是一个普通的状态提示"); LogStatus("这是一个红色字体的状态提示#ff0000"); LogStatus("这是一个多行的状态信息\n我是第二行"); }
  • 状态栏中数据输出示例:

    javascript
    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': '平仓'}) + '`') }
    python
    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": "平仓"}) + '`')
    c++
    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() + "`"); }
  • 支持在状态栏中设计按钮控件(旧版按钮结构):

    javascript
    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) + "`") }
    python
    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) + "`")
    c++
    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() + "`"); }
  • 设置状态栏按钮的禁用、描述功能(旧版按钮结构):

    javascript
    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) + "`") }
    python
    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) + "`")
    c++
    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() + "`"); }
  • 结合GetCommand()函数,构造状态栏按钮交互功能(旧版按钮结构):

    javascript
    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) } }
    python
    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)
    c++
    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); } }
  • 在构造状态栏按钮进行交互时也支持输入数据,交互指令最终由GetCommand()函数捕获。

    给状态栏中的按钮控件的数据结构中增加input项(旧版按钮结构),例如给{"type": "button", "cmd": "open", "name": "开仓"}增加:"input": {"name": "开仓数量", "type": "number", "defValue": 1},即可使按钮在被点击时弹出一个带输入框控件的弹窗(输入框中默认值为1,即defValue设置的数据),可以输入数据并与按钮命令一起发送。例如以下测试代码运行时,点击「开仓」按钮后,会弹出一个带输入框的弹窗,在输入框中输入111后点击「确定」,GetCommand()函数将捕获消息:open:111

    javascript
    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) } }
    python
    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)
    c++
    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); } }
  • 支持分组按钮控件(旧版按钮结构),功能与支持输入数据的状态栏按钮(使用"input"字段设置)一致。交互指令最终由GetCommand()函数捕获。区别在于使用"group"字段设置,当点击按钮触发交互时,页面弹出的对话框中包含设置好的一组输入控件,可以一次性输入一组数据。

    关于状态栏按钮控件和分组按钮控件结构中"group"字段,需要注意以下几点:

    • group中type属性仅支持以下4种类型,defValue属性为默认值。
      "selected":下拉框控件,设置下拉框中每个选项时使用|符号分隔。
      "number":数值输入框控件。
      "string":字符串输入框控件。
      "boolean":勾选框控件,勾选为布尔值真,不勾选为布尔值假。
    • 交互输入时的控件支持依赖设置:
      例如以下示例中的:"name": "tradePrice@orderType==1"设置,该设置使交易价格tradePrice)输入控件仅当下单方式(orderType)下拉框控件选择为挂单时可用。
    • 交互输入时的控件名称支持双语设置:
      例如以下示例中的:"description": "下单方式|order type"设置,使用|符号分隔中英文描述内容。
    • group中的namedescription与按钮结构中的namedescription虽然字段名一致,但定义并不相同:
      group中的name与input中的name定义也不同。
    • 分组按钮控件触发后,发送交互内容的格式为:按钮的cmd字段值、group字段相关数据,例如以下示例测试时Log("cmd:", cmd)语句输出的内容:
      cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true},即发生交互操作时GetCommand()函数返回的内容:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
    • 按钮控件的type属性仅支持:"button"
      支持输入数据的按钮控件,即设置了input属性的控件,input字段的配置信息中的type属性支持多种控件类型。
      参考以下示例:
    javascript
    function main() { var tbl = { type: "table", title: "演示分组按钮控件", cols: ["操作"], rows: [] } // 创建分组按钮控件结构 var groupBtn = { type: "button", cmd: "open", name: "开仓", group: [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true} ] } // 测试按钮1 var testBtn1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"} var testBtn2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}} // 在tbl中添加groupBtn tbl.rows.push([groupBtn]) // 支持状态栏表格的一个单元格内设置多个按钮,即一个单元格内的数据为一个按钮结构数组:[testBtn1, testBtn2] tbl.rows.push([[testBtn1, testBtn2]]) while (true) { LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + JSON.stringify(groupBtn) + "`") var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) } Sleep(5000) } }
    python
    import json def main(): tbl = { "type": "table", "title": "演示分组按钮控件", "cols": ["操作"], "rows": [] } groupBtn = { "type": "button", "cmd": "open", "name": "开仓", "group": [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": True} ] } testBtn1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"} testBtn2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}} tbl["rows"].append([groupBtn]) tbl["rows"].append([[testBtn1, testBtn2]]) while True: LogStatus("`" + json.dumps(tbl) + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + json.dumps(groupBtn) + "`") cmd = GetCommand() if cmd: Log("cmd:", cmd) Sleep(5000)
    c++
    void main() { json tbl = R"({ "type": "table", "title": "演示分组按钮控件", "cols": ["操作"], "rows": [] })"_json; json groupBtn = R"({ "type": "button", "name": "开仓", "cmd": "open", "group": [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true} ]})"_json; json testBtn1 = R"({"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"})"_json; json testBtn2 = R"({"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}})"_json; tbl["rows"].push_back({groupBtn}); tbl["rows"].push_back({{testBtn1, testBtn2}}); while(true) { LogStatus("`" + tbl.dump() + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + groupBtn.dump() + "`"); auto cmd = GetCommand(); if(cmd != "") { Log("cmd:", cmd); } Sleep(5000); } }
  • 状态栏分组按钮控件(通过设置group字段实现)与状态栏按钮控件(通过设置input字段实现)被点击触发交互时(旧版按钮结构),页面弹出的对话框中的下拉框控件也支持多选。以下示例演示如何设计包含多选选项的下拉框控件:

    javascript
    function main() { // 状态栏按钮控件(设置input字段实现)testBtn1按钮触发的页面中的下拉框控件使用options字段设置选项,使用defValue字段设置默认选项。区别于本章其它例子中直接使用defValue设置选项。 var testBtn1 = { type: "button", name: "testBtn1", cmd: "cmdTestBtn1", input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1} } /* 状态栏按钮控件(设置input字段实现)testBtn2按钮触发的页面中的下拉框控件使用options字段设置选项,options字段中的选项不仅支持字符串, 也支持使用```{text: "描述", value: "值"}```结构。使用defValue字段设置默认选项,默认选项可以是多选(通过数组结构实现多选)。多选需要设置额外的字段multiple为真值(true)。 */ var testBtn2 = { type: "button", name: "testBtn2", cmd: "cmdTestBtn2", input: { name: "testBtn2MultiComboBox", type: "selected", description: "实现下拉框多选", options: [{text: "选项A", value: "A"}, {text: "选项B", value: "B"}, {text: "选项C", value: "C"}], defValue: ["A", "C"], multiple: true } } // 状态栏分组按钮控件(设置group字段实现)testBtn3按钮触发的页面中的下拉框控件使用options字段设置选项,也支持直接使用defValue设置选项。 var testBtn3 = { type: "button", name: "testBtn3", cmd: "cmdTestBtn3", group: [ {name: "comboBox1", label: "labelComboBox1", description: "下拉框1", type: "selected", defValue: 1, options: ["A", "B"]}, {name: "comboBox2", label: "labelComboBox2", description: "下拉框2", type: "selected", defValue: "A|B"}, {name: "comboBox3", label: "labelComboBox3", description: "下拉框3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]}, { name: "comboBox4", label: "labelComboBox4", description: "下拉框4", type: "selected", defValue: ["A", "C"], multiple: true, options: [{text: "选项A", value: "A"}, {text: "选项B", value: "B"}, {text: "选项C", value: "C"}, {text: "选项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) } }
    python
    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": "实现下拉框多选", "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}], "defValue": ["A", "C"], "multiple": True } } testBtn3 = { "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "下拉框1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "下拉框2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "下拉框3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "下拉框4", "type": "selected", "defValue": ["A", "C"], "multiple": True, "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}, {"text": "选项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)
    c++
    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": "实现下拉框多选", "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}], "defValue": ["A", "C"], "multiple": true } })"_json; json testBtn3 = R"({ "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "下拉框1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "下拉框2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "下拉框3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "下拉框4", "type": "selected", "defValue": ["A", "C"], "multiple": true, "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}, {"text": "选项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); } }
  • 使用当前最新的按钮结构,构造状态栏表格中的按钮,点击按钮触发交互时弹出一个多控件弹窗。

    详细内容可以参考:用户指南-状态栏中的交互控件

    javascript
    var symbols = ["rb2410", "MA501", "hc2501", "i2501", "TA888"] 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": "开仓下单", "group": [{ "type": "selected", "name": "tradeType", "label": "下单类型", "description": "市价单、限价单", "default": 0, "group": "交易设置", "settings": { "options": ["市价单", "限价单"], "required": true, } }, { "type": "selected", "name": "direction", "label": "交易方向", "description": "买入、卖出", "default": "buy", "group": "交易设置", "settings": { "render": "segment", "required": true, "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "价格", "description": "订单的价格", "group": "交易设置", "filter": "tradeType==1", "settings": { "required": true, } }, { "type": "number", "name": "amount", "label": "下单量", "description": "订单的下单量", "group": "交易设置", "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": "交易品种", "default": m["symbol"], "settings": {"required": true}}]) tbl["rows"].push([m["symbol"], btnOpen]) }) var cmd = GetCommand() if (cmd) { Log("收到交互:", cmd) // 解析交互消息: open:{"symbol":"TA888","tradeType":0,"direction":"buy","amount":111} // 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息 var arrCmd = cmd.split(":", 2) if (arrCmd[0] == "open") { var msg = JSON.parse(cmd.slice(5)) Log("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", msg["tradeType"] == 0 ? "市价单" : "限价单", msg["tradeType"] == 0 ? ",订单价格:当前市价" : ",订单价格:" + msg["price"], ",订单数量:", msg["amount"]) } } LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`") Sleep(1000) } }
    python
    import json symbols = ["rb2410", "MA501", "hc2501", "i2501", "TA888"] 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": "开仓下单", "group": [{ "type": "selected", "name": "tradeType", "label": "下单类型", "description": "市价单、限价单", "default": 0, "group": "交易设置", "settings": { "options": ["市价单", "限价单"], "required": True, } }, { "type": "selected", "name": "direction", "label": "交易方向", "description": "买入、卖出", "default": "buy", "group": "交易设置", "settings": { "render": "segment", "required": True, "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "价格", "description": "订单的价格", "group": "交易设置", "filter": "tradeType==1", "settings": { "required": True, } }, { "type": "number", "name": "amount", "label": "下单量", "description": "订单的下单量", "group": "交易设置", "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("收到交互:", cmd) # 解析交互消息: open:{"symbol":"TA888","tradeType":0,"direction":"buy","amount":111} # 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息 arrCmd = cmd.split(":") if arrCmd[0] == "open": msg = json.loads(cmd[5:]) Log("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", "市价单" if msg["tradeType"] == 0 else "限价单", ",订单价格:当前市价" if msg["tradeType"] == 0 else ",订单价格:" + str(msg["price"]), ",订单数量:", msg["amount"]) # 输出状态栏信息 LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`") Sleep(1000)
    c++
    // 略...
  • 横向合并 LogStatus() 函数绘制的表格中的单元格:

    javascript
    function main() { var table = { type: 'table', title: '持仓操作', cols: ['列1', '列2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}] ] } // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数 while(!exchange.IO("status")) { Sleep(1000) } exchange.SetContractType("rb888") var ticker = exchange.GetTicker() // 添加一行数据,第一个和第二个单元格合并,并且输出ticker变量在合并后的单元格内 table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "持仓操作", "cols" : ["列1", "列2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}] ] } while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") ticker = exchange.GetTicker() table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"]) LogStatus("`" + json.dumps(table) + "`")
    c++
    void main() { json table = R"({ "type" : "table", "title" : "持仓操作", "cols" : ["列1", "列2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}] ] })"_json; while(exchange.IO("status") == 0) { Sleep(1000); } exchange.SetContractType("rb888"); 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() + "`"); }
  • 纵向合并 LogStatus() 函数绘制的表格中的单元格:

    javascript
    function main() { var table = { type: 'table', title: '表格演示', cols: ['列A', '列B', '列C'], rows: [ ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}] ] } // 由于是测试代码,不使用商品期货策略的一般架构 while(!exchange.IO("status")) { Sleep(1000) } exchange.SetContractType("rb888") 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"]) // A4 被上一行第一个单元格合并 table.rows.push(["B5", "C5"]) table.rows.push(["A6", "B6", "C6"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "表格演示", "cols" : ["列A", "列B", "列C"], "rows" : [ ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}] ] } while not exchange.IO("status"): Sleep(1000) exchange.SetContractType("rb888") 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) + "`")
    c++
    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() + "`"); }
  • 状态栏表格分页显示:

    javascript
    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]) + '`') }
    python
    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]) + "`")
    c++
    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() + "`"); }
  • 除了可以分页显示表格,还可以将多个表格自上而下排列显示:

    javascript
    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") }
    python
    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) + "`")
    c++
    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() + "`"); }
  • 支持设置状态栏表格的横向和纵向滚动模式。将scroll属性设置为"auto"时,当状态栏表格纵向行数超过20行时,内容将自动滚动显示;当横向列数超出页面显示范围时,将进行横向滚动显示。使用scroll属性可以有效缓解实盘运行时状态栏中大量数据写入导致的卡顿问题。参考以下测试示例:

    javascript
    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) + "`") }
    python
    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) + "`")
    c++
    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() + "`"); }

参数

名称类型必填描述

msg

string / number / bool / object / array / any (系统支持的所有类型)

参数msg为输出的内容,参数msg可以传入多个。

参考

备注

实盘运行时,LogStatus()函数输出的信息不保存到实盘数据库,仅更新当前实盘的状态栏内容。

LogStatus()函数支持打印base64编码后的图片,以`开头,以`结尾。例如:LogStatus("`data:image/png;base64,AAAA`")

LogStatus()函数支持直接传入Pythonmatplotlib.pyplot对象,只要该对象包含savefig方法即可作为参数传入LogStatus()函数,例如:

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

策略实盘运行时,在实盘页面如果翻看历史记录,状态栏会进入休眠状态并停止更新。只有当日志处于第一页时,状态栏数据才会刷新。支持在状态栏输出base64编码后的图片,也支持在状态栏显示的表格中输出base64编码后的图片。由于编码后的图片字符串数据通常很长,因此不再展示示例代码。