Type/to search
Built-in Functions
Structures
Ticker
Depth
OrderBook
Trade
Record
Market
Order
Condition
Account
Asset
Position
Funding
Other Structures
HttpQuery-options
HttpQuery-return
LogStatus-table
LogStatus-btnTypeOne
LogStatus-btnTypeTwo
Status Bar Components
Chart-options
Chart-return
KLineChart-options
KLineChart-return
SetData-data
EventLoop-return
exchange.Go-return
DBExec-return
Dial-return
Thread.join-return
Built-in Variables and Constants
Conventions
Exchanges

Status bar table output with LogStatus: columns can set number formats, up/down colors and units; cells can be merged or hold buttons; several tables can be shown as tabs.

Examples

  • Outputs a table with 3 rows and 3 columns.

    javascript
    function main() { var tbl = { type: "table", title: "Title", cols: ["Column 1", "Column 2", "Column 3"], rows: [ ["Row 1 Column 1", "Row 1 Column 2", "Row 1 Column 3"], ["Row 2 Column 1", "Row 2 Column 2", "Row 2 Column 3"], ["Row 3 Column 1", "Row 3 Column 2", "Row 3 Column 3"] ] } // A lone table object gets backticks automatically LogStatus(tbl) }
    python
    def main(): tbl = { "type": "table", "title": "Title", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [ ["Row 1 Column 1", "Row 1 Column 2", "Row 1 Column 3"], ["Row 2 Column 1", "Row 2 Column 2", "Row 2 Column 3"], ["Row 3 Column 1", "Row 3 Column 2", "Row 3 Column 3"] ] } # A lone table dict gets backticks automatically LogStatus(tbl)
    rust
    fn main() { let tbl = r#"{"type": "table", "title": "Title", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [["Row 1 Column 1", "Row 1 Column 2", "Row 1 Column 3"], ["Row 2 Column 1", "Row 2 Column 2", "Row 2 Column 3"], ["Row 3 Column 1", "Row 3 Column 2", "Row 3 Column 3"]]}"#; // Rust strings get no automatic backticks; the JSON inside must be one line LogStatus!(format!("`{}`", tbl.replace('\n', ""))); }
  • The last 10 daily K-lines: column formats and up/down colors, plus a cell object with its own color.

    javascript
    function main() { var r = exchange.GetRecords(PERIOD_D1) if (!r || r.length < 11) return var rows = [] for (var i = r.length - 1; i >= r.length - 10; i--) { var chg = r[i].Close / r[i - 1].Close - 1 var note = Math.abs(chg) > 0.05 ? {value: "Big move", color: "warning"} : "" rows.push([_D(r[i].Time, "yyyy-MM-dd"), r[i].Close, chg, r[i].Volume, note]) } LogStatus({type: "table", title: "Last 10 days", rows: rows, cols: [ "Date", {title: "Close", format: {precision: 2}, align: "right"}, {title: "Change", format: {percent: true, precision: 2}, color: "sign", align: "right"}, {title: "Volume", format: {compact: true}, align: "right"}, "Note" ]}) }
    python
    def main(): r = exchange.GetRecords(PERIOD_D1) if not r or len(r) < 11: return rows = [] for i in range(len(r) - 1, len(r) - 11, -1): chg = r[i]["Close"] / r[i - 1]["Close"] - 1 note = {"value": "Big move", "color": "warning"} if abs(chg) > 0.05 else "" rows.append([_D(r[i]["Time"] / 1000, "%Y-%m-%d"), r[i]["Close"], chg, r[i]["Volume"], note]) pct = {"percent": True, "precision": 2} LogStatus({"type": "table", "title": "Last 10 days", "rows": rows, "cols": [ "Date", {"title": "Close", "format": {"precision": 2}, "align": "right"}, {"title": "Change", "format": pct, "color": "sign", "align": "right"}, {"title": "Volume", "format": {"compact": True}, "align": "right"}, "Note" ]})
    rust
    fn main() { let Ok(r) = exchange.GetRecords(None, PERIOD_D1, None) else { return }; if r.len() < 11 { return; } let rows: Vec<String> = (r.len() - 10..r.len()).rev().map(|i| { let chg = r[i].Close / r[i - 1].Close - 1.0; let big = r#"{"value": "Big move", "color": "warning"}"#; let note = if chg.abs() > 0.05 { big } else { r#""""# }; let date = &_D(r[i].Time)[..10]; format!(r#"["{}", {}, {}, {}, {}]"#, date, r[i].Close, chg, r[i].Volume, note) }).collect(); let table = format!(r#"{{"type": "table", "title": "Last 10 days", "rows": [{}], "cols": [ "Date", {{"title": "Close", "format": {{"precision": 2}}, "align": "right"}}, {{"title": "Change", "format": {{"percent": true, "precision": 2}}, "color": "sign", "align": "right"}}, {{"title": "Volume", "format": {{"compact": true}}, "align": "right"}}, "Note"]}}"#, rows.join(",")); // The JSON inside backticks must be one line LogStatus!(format!("`{}`", table.replace('\n', ""))); }
  • Horizontally merge cells in the table drawn by the LogStatus() function.

    javascript
    function main() { var table = { type: 'table', title: 'Position Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close'}] ] } var ticker = exchange.GetTicker() // Add a row of data, merge the first and second cells, and output the ticker variable in the merged cell table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}] ] } ticker = exchange.GetTicker() table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"]) LogStatus("`" + json.dumps(table) + "`")
    rust
    fn main() { let table_tpl = String::from(r#"{"type": "table", "title": "Position Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}],"# + r#"__ROW2__"# + r#"]}"#; let ticker = exchange.GetTicker(None).unwrap(); let json_ticker = format!( r#"{{"Buy": {}, "Sell": {}, "High": {}, "Low": {}, "Volume": {}, "Last": {}, "Time": {}}}"#, ticker.Buy, ticker.Sell, ticker.High, ticker.Low, ticker.Volume, ticker.Last, ticker.Time ); // Add a row of data, merge the first and second cells, and output the ticker data in the merged cell // body is a string (corresponding to JS's JSON.stringify(ticker)); its internal quotes must be escaped before being embedded into the JSON let row2 = format!(r#"[{{"body": "{}", "colspan": 2}}, "abc"]"#, json_ticker.replace('"', "\\\"")); let table = table_tpl.replace("__ROW2__", &row2); LogStatus!(format!("`{}`", table)); }
  • Vertically merge cells in a table drawn by the LogStatus() function.

    javascript
    function main() { var table = { type: 'table', title: 'Table Demo', cols: ['Column A', 'Column B', 'Column 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"]) // A4 is merged into the first cell of the previous row table.rows.push(["B4", "C4"]) // A5 is merged into the first cell of the previous row table.rows.push(["B5", "C5"]) table.rows.push(["A6", "B6", "C6"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "Table Demo", "cols" : ["Column A", "Column B", "Column 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) + "`")
    rust
    fn main() { // For ease of testing, constructed data is used here to keep the code short and readable let json_ticker = r#"{"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0}"#; let name = exchange.GetName(); let mut rows: Vec<String> = Vec::new(); rows.push(String::from(r#"["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]"#)); // body is a string, and the quotes inside it must be escaped before they can be embedded in JSON let body = format!("A2 + B2:{}", json_ticker).replace('"', "\\\""); rows.push(format!(r#"[{{"body": "{}", "colspan": 2}}, "C2"]"#, body)); rows.push(format!(r#"[{{"body": "A3 + A4 + A5:{}", "rowspan": 3}}, "B3", "C3"]"#, name)); // A4 is merged into the first cell of the previous row rows.push(String::from(r#"["B4", "C4"]"#)); // A5 is merged into the first cell of the previous row rows.push(String::from(r#"["B5", "C5"]"#)); rows.push(String::from(r#"["A6", "B6", "C6"]"#)); let table = format!(r#"{{"type": "table", "title": "Table Demo", "cols": ["Column A", "Column B", "Column C"], "rows": [{}]}}"#, rows.join(",")); LogStatus!(format!("`{}`", table)); }
  • Display tables with pagination in the status bar.

    javascript
    function main() { var table1 = {type: 'table', title: 'table1', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} var table2 = {type: 'table', title: 'table2', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} LogStatus('`' + JSON.stringify([table1, table2]) + '`') }
    python
    import json def main(): table1 = {"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} table2 = {"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} LogStatus("`" + json.dumps([table1, table2]) + "`")
    rust
    fn main() { let table1 = r#"{"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; let table2 = r#"{"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; LogStatus!(format!("`[{},{}]`", table1, table2)); }
  • In addition to displaying tables with pagination, you can also arrange multiple tables from top to bottom.

    javascript
    function main(){ var tab1 = { type : "table", title : "Table 1", cols : ["1", "2"], rows : [] } var tab2 = { type : "table", title : "Table 2", cols : ["1", "2", "3"], rows : [] } var tab3 = { type : "table", title : "Table 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": "Table 1", "cols": ["1", "2"], "rows": [] } tab2 = { "type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [] } tab3 = { "type": "table", "title": "Table 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) + "`")
    rust
    fn main() { // In Rust, write the row data directly into the JSON string let tab1 = r#"{"type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [["jack", "lucy"]]}"#; let tab2 = r#"{"type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [["A", "B", "C"]]}"#; let tab3 = r#"{"type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [["A", "B", "C"]]}"#; LogStatus!(format!("`{}`\n`{}`\n`{}`", tab1, tab2, tab3)); Log!("exit"); }
  • Supports setting horizontal and vertical scroll modes for the status bar table. After setting the scroll attribute to auto, when the number of vertical rows in the status bar table exceeds 20, the content will scroll automatically; when the number of horizontal columns exceeds the visible range of the page, horizontal scrolling will be applied. Using the scroll attribute can help mitigate the lag caused by writing large amounts of data to the status bar during live trading.

    Refer to the following test example:

    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) + "`")
    rust
    fn main() { let tbl_tpl = String::from(r#"{"type": "table", "title": "test scroll", "scroll": "auto", "cols": ["#) + r#""col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10","# + r#""col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20""# + r#"], "rows": [__ROWS__]}"#; let mut rows: Vec<String> = Vec::new(); for index in 1..100 { let i = index.to_string(); rows.push(format!( r#"[{}, "1,{}", "2,{}", "3,{}", "4,{}", "5,{}", "6,{}", "7,{}", "8,{}", "9,{}", "10,{}", "11,{}", "12,{}", "13,{}", "14,{}", "15,{}", "16,{}", "17,{}", "18,{}", "19,{}", "20,{}"]"#, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i )); } let tbl = tbl_tpl.replace("__ROWS__", &rows.join(",")); LogStatus!(format!("`{}`", tbl)); }

Attributes

NameTypeDescription

type

string

Required. Always table.

title

string

Table title.

cols

array

Required. Column headers: each item is a string or a column definition object with title.

rows

array

Required. 2D array, one array per row with one item per column. A cell can be text (a trailing #ff0000 sets the color), a number, a button object (an array for several buttons), a merged cell {body, colspan, rowspan}, or a formatted cell {value, format, color, unit}.

scroll

string

auto scrolls vertically beyond 20 rows and horizontally when the columns overflow, which helps with large data.

cols[].title

string

Column header.

cols[].format

object

Number format of the column {precision, compact, percent}; see Status Bar Components.

cols[].color

string

Color of the column's numbers: sign picks the up or down color by sign (0 stays uncolored), or up, down, primary, warning, muted.

cols[].unit

string

Unit after the column's numbers.

cols[].align

string

Alignment: left, center or right.

rows[][].value

number / string

Value of a formatted cell.

rows[][].format

object

Number format of the cell, taking precedence over the column.

rows[][].color

string

Color of the cell, same values as cols[].color.

rows[][].unit

string

Unit of the cell.

See Also

Remarks

Column definitions apply only to the column's numbers; strings are shown as is, and cell objects take precedence over the column. Formatted text still sorts by the raw numbers; search and CSV export in the table use the formatted text.

To output a table on its own, JavaScript and Python pass the table object directly (backticks are added automatically) or write LogStatus("`" + JSON.stringify(tbl) + "`"); Rust writes format!("`{}`", table). Inside grid, tabs or an array with components no backticks are needed.

An array of tables wrapped in backticks is shown as tabs; tables on separate lines are stacked top to bottom. For buttons in cells see LogStatus-btnTypeTwo.