Output log.
Catatan ((...msgs)
Parametermsg
adalah isi output, dan parametermsg
bisa dilewati lebih dari satu.
msg
palsu
string, number, bool, object, array, jenis apapun yang didukung oleh sistem seperti null.
function main() {
Log("msg1", "msg2", "msg3")
}
def main():
Log("msg1", "msg2", "msg3")
void main() {
Log("msg1", "msg2", "msg3");
}
Berbagaimsg
parameter dapat dilewati:
function main() {
Log("Hello, FMZ Quant!@")
Sleep(1000 * 5)
// Add #ff0000 to the string to print the log in red and push the message
Log("Hello, #ff0000@")
}
def main():
Log("Hello, FMZ Quant!@")
Sleep(1000 * 5)
Log("Hello, #ff0000@")
void main() {
Log("Hello, FMZ Quant!@");
Sleep(1000 * 5);
Log("Hello, #ff0000@");
}
Ini mendukung pengaturan warna pesan output, jika kita menggunakan pengaturan warna dan push pada saat yang sama, kita perlu untuk mengatur warna pertama dan menggunakan@
karakter untuk mengatur dorongan terakhir.
function main() {
Log("`data:image/png;base64,AAAA`")
}
def main():
Log("`data:image/png;base64,AAAA`")
void main() {
Log("`data:image/png;base64,AAAA`");
}
PeraturanLog()
Fungsi mendukung pencetakanbase64
gambar yang dikodekan, dimulai dengan`
dan berakhir dengan`
, misalnya:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
PeraturanLog()
Fungsi mendukung pencetakan langsungPython
Itu adalahmatplotlib.pyplot
objek. Selama objek berisisavefig
metode, dapat dicetak langsung dengan menggunakanLog
fungsi, misalnya:
function main() {
Log("[trans]中文|abc[/trans]")
}
def main():
Log("[trans]中文|abc[/trans]")
void main() {
Log("[trans]中文|abc[/trans]");
}
PeraturanLog()
Fungsi ini mendukung pertukaran bahasa.Log()
fungsi output teks yang akan beralih ke bahasa yang sesuai secara otomatis berdasarkan pengaturan bahasa pada halaman platform, misalnya:
PeraturanLog()
fungsi output pesan log di area log dari live trading atau backtesting sistem, dan log disimpan di database live trading ketika live trading sedang berjalan.Log()
fungsi output pesan log yang berakhir dengan@
Push ke alamat email, alamat WebHook, dll yang dikonfigurasi diTekan PengaturanPushing pesan tidak didukung olehAlat debug, sistem backtesting. Ada batas frekuensi untuk push pesan. Aturan pembatasan spesifik adalah sebagai berikut: dalam siklus 20 detik perdagangan langsung, hanya pesan push terakhir yang akan dipertahankan dan didorong, dan pesan lain akan disaring dan tidak didorong (output log push oleh fungsi Log akan dicetak dan ditampilkan secara normal di area log).
UntukWebHook
push, Anda dapat menggunakan program layanan yang ditulis olehGolang
:
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)
}
SetWebHook
dalamTekan Pengaturan: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ
Aku tidak tahu.
Setelah menjalankan tertulisGolang
program layanan, kita mulai menjalankan strategi live trading, berikut adalah strategi yang ditulis dalamJavaScript
bahasa, strategi berjalan dengan melaksanakanLog()
fungsi dan mendorong pesan:
function main() {
Log("msg", "@")
}
Sebuah program layanan yang ditulis dalamGolang
bahasa menerima dorongan dan program layanan mencetak pesan:
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
{@fun/Log/LogReset LogReset}, {@fun/Log/LogVacuum LogVacuum}
Catat nilai P&L, cetak nilai P&L dan gambarkan kurva pengembalian berdasarkan nilai P&L.
LogProfit (keuntungan) LogProfit (keuntungan,... args)
Parameterprofit
adalah data pendapatan, yang diberikan oleh algoritma desain dan perhitungan dalam strategi.
keuntungan
benar
nomor
Parameter diperluas untuk output informasi kebetulan ke log pendapatan,arg
parameter dapat dilewati lebih dari satu.
arg
palsu
string, number, bool, object, array, jenis apapun yang didukung oleh sistem seperti null.
function main() {
// Print 30 points on the earnings chart
for(var i = 0; i < 30; i++) {
LogProfit(i, '&')
Sleep(500)
}
}
def main():
for i in range(30):
LogProfit(i, '&')
Sleep(500)
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i, '&');
Sleep(500);
}
}
PeraturanLogProfit
fungsi, jika berakhir dengan karakter&
, hanya membuat grafik pendapatan dan tidak mencetak log pendapatan.
{@fun/Log/LogProfitReset LogProfitReset}
Hapus semua log pendapatan, grafik pendapatan.
LogProfitReset (() LogProfitReset (tetap)
Peraturanremain
Parameter digunakan untuk menentukan jumlah entri log (nilai bilangan bulat) yang harus disimpan.
tetap
palsu
nomor
function main() {
// Print 30 points on the revenue chart, then reset and keep only the last 10 points
for(var i = 0; i < 30; i++) {
LogProfit(i)
Sleep(500)
}
LogProfitReset(10)
}
def main():
for i in range(30):
LogProfit(i)
Sleep(500)
LogProfitReset(10)
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i);
Sleep(500);
}
LogProfitReset(10);
}
{@fun/Log/LogProfit LogProfit}
Informasi output di bilah status sistem backtesting atau halaman perdagangan langsung.
LogStatus ((...msgs)
Parametermsg
adalah isi output, dan parametermsg
bisa dilewati lebih dari satu.
msg
palsu
string, number, bool, object, array, jenis apapun yang didukung oleh sistem seperti null.
function main() {
LogStatus('This is a general status alert')
LogStatus('This is a status alert in red font #ff0000')
LogStatus('This is a multi-line status message \n I am the second line')
}
def main():
LogStatus('This is a general status alert')
LogStatus('This is a status alert in red font #ff0000')
LogStatus('This is a multi-line status message \n I am the second line')
void main() {
LogStatus("This is a general status alert");
LogStatus("This is a status alert in red font #ff0000");
LogStatus("This is a multi-line status message \n I am the second line");
}
Ini mendukung pengaturan warna konten output:
function main() {
var table = {type: 'table', title: 'Position information', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
// JSON serialization with the ` character on both sides, as a complex message format (support tables currently)
LogStatus('`' + JSON.stringify(table) + '`')
// Table information can also appear in multiple rows
LogStatus('First line of message\n`' + JSON.stringify(table) + '`\n third line of message')
// It supports multiple tables at the same time, will be displayed in a group with TAB
LogStatus('`' + JSON.stringify([table, table]) + '`')
// You can also construct a button in the form, and use the GetCommand strategy to receive the contents of the cmd attribute
var table = {
type: 'table',
title: 'Position operations',
cols: ['Column 1', 'Column 2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}]
]
}
LogStatus('`' + JSON.stringify(table) + '`')
// Or construct a separate button
LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`')
// Customizable button style (bootstrap's button attribute)
LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`')
}
import json
def main():
table = {"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('First line of message\n`' + json.dumps(table) + '`\n third line of message')
LogStatus('`' + json.dumps([table, table]) + '`')
table = {
"type" : "table",
"title" : "Position operations",
"cols" : ["Column 1", "Column 2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
]
}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "Close out positions"}) + '`')
LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"}) + '`')
void main() {
json table = R"({"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("First line of message\n`" + table.dump() + "`\n third line of message");
json arr = R"([])"_json;
arr.push_back(table);
arr.push_back(table);
LogStatus("`" + arr.dump() + "`");
table = R"({
"type" : "table",
"title" : "Position operations",
"cols" : ["Column 1", "Column 2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
]
})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
}
Contoh output data di bilah status:
function main() {
var table = {
type: "table",
title: "status bar button style",
cols: ["default", "original", "success", "info", "warning", "danger"],
rows: [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
}
LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "status bar button style",
"cols": ["default", "original", "success", "info", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
}
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type": "table",
"title": "status bar button style",
"cols": ["default", "original", "success", "info", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"type":"button", "class": "btn btn-xs btn-success", "name": "success"},
{"type":"button", "class": "btn btn-xs btn-info", "name": "info"},
{"type":"button", "class": "btn btn-xs btn-warning", "name": "warning"},
{"type":"button", "class": "btn btn-xs btn-danger", "name": "danger"}
]
]
})"_json;
LogStatus("`" + table.dump() + "`");
}
Ini mendukung untuk merancang kontrol tombol di bilah status (struktur tombol lama):
function main() {
var table = {
type: "table",
title: "Status bar button disable, description function test",
cols: ["Column 1", "Column 2", "Column 3"],
rows: []
}
var button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
var button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true}
var button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "disabled": false}
table.rows.push([button1, button2, button3])
LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "Status bar button disable, description function test",
"cols": ["Column 1", "Column 2", "Column 3"],
"rows": []
}
button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": True}
button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "disabled": False}
table["rows"].append([button1, button2, button3])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type": "table",
"title": "Status bar button disable, description function test",
"cols": ["Column 1", "Column 2", "Column 3"],
"rows": []
})"_json;
json button1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"})"_json;
json button2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true})"_json;
json button3 = R"({"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "disabled": false})"_json;
json arr = R"([])"_json;
arr.push_back(button1);
arr.push_back(button2);
arr.push_back(button3);
table["rows"].push_back(arr);
LogStatus("`" + table.dump() + "`");
}
Atur fungsi deskripsi dari tombol status bar (struktur tombol lama):
function test1() {
Log("Calling custom functions")
}
function main() {
while (true) {
var table = {
type: 'table',
title: 'operation',
cols: ['column1', 'column2', 'Action'],
rows: [
['a', '1', {
'type': 'button',
'cmd': "CoverAll",
'name': 'Close out positions'
}],
['b', '1', {
'type': 'button',
'cmd': 10,
'name': 'Send values'
}],
['c', '1', {
'type': 'button',
'cmd': _D(),
'name': 'Calling functions'
}],
['d', '1', {
'type': 'button',
'cmd': 'test1',
'name': 'Calling custom functions'
}]
]
}
LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')
var str_cmd = GetCommand()
if (str_cmd) {
Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd)
if(str_cmd == "test1") {
test1()
}
}
Sleep(500)
}
}
import json
def test1():
Log("Calling custom functions")
def main():
while True:
table = {
"type": "table",
"title": "operation",
"cols": ["column1", "column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "Close out positions"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send values"
}],
["c", "1", {
"type": "button",
"cmd": _D(),
"name": "Calling functions"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Calling custom functions"
}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
str_cmd = GetCommand()
if str_cmd:
Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd)
if str_cmd == "test1":
test1()
Sleep(500)
void test1() {
Log("Calling custom functions");
}
void main() {
while(true) {
json table = R"({
"type": "table",
"title": "operation",
"cols": ["column1", "column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "Close out positions"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send values"
}],
["c", "1", {
"type": "button",
"cmd": "",
"name": "Calling functions"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Calling custom functions"
}]
]
})"_json;
table["rows"][2][2]["cmd"] = _D();
LogStatus(_D(), "\n", "`" + table.dump() + "`");
auto str_cmd = GetCommand();
if(str_cmd != "") {
Log("Received interaction data str_cmd:", "type:", typeof(str_cmd), "value:", str_cmd);
if(str_cmd == "test1") {
test1();
}
}
Sleep(500);
}
}
Dalam kombinasi denganGetCommand()
fungsi, membangun fungsi interaksi tombol bilah status (struktur tombol lama):
function main() {
var tbl = {
type: "table",
title: "operation",
cols: ["column1", "column2"],
rows: [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
while (true) {
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
}
Sleep(1000)
}
}
import json
def main():
tbl = {
"type": "table",
"title": "operation",
"cols": ["column1", "column2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
while True:
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
Sleep(1000)
void main() {
json tbl = R"({
"type": "table",
"title": "operation",
"cols": ["column1", "column2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
})"_json;
LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
while(true) {
auto cmd = GetCommand();
if(cmd != "") {
Log("cmd:", cmd);
}
Sleep(1000);
}
}
Data masukan juga didukung ketika membangun tombol bar status untuk interaksi, dan perintah interaksi ditangkap olehGetCommand()
fungsi akhirnya.input
item (struktur tombol lama) untuk struktur data kontrol tombol di bilah status, misalnya menambahkan"input": {"name": "number of open positions", "type": "number", "defValue": 1}
untuk{"type": "button", "cmd": "open", "name": "open position"}
akan menyebabkan popup dengan kontrol kotak input muncul ketika tombol diklik (nilai default dalam kotak input adalah 1, yang merupakan data yang ditetapkan olehdefValue
Anda dapat memasukkan data yang akan dikirim bersama dengan perintah tombol. Sebagai contoh, ketika kode tes berikut berjalan, setelah mengklik tombol "open positionGetCommand()
fungsi kemudian akan menangkap pesan:open:111
.
function main() {
var tbl = {
type: "table",
title: "Demonstrate grouping button control",
cols: ["operation"],
rows: []
}
// Creating a grouping button control structure
var groupBtn = {
type: "button",
cmd: "open",
name: "open positions",
group: [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
]
}
// test button 1
var testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
var testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}
// Add groupBtn to tbl
tbl.rows.push([groupBtn])
// It supports multiple buttons in a cell of a status bar table, i.e. the data in a cell is an array of button structures: [testBtn1, testBtn2].
tbl.rows.push([[testBtn1, testBtn2]])
while (true) {
LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + JSON.stringify(groupBtn) + "`")
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
}
Sleep(5000)
}
}
import json
def main():
tbl = {
"type": "table",
"title": "Demonstrate grouping button control",
"cols": ["operation"],
"rows": []
}
groupBtn = {
"type": "button",
"cmd": "open",
"name": "open positions",
"group": [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": True}
]
}
testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}
tbl["rows"].append([groupBtn])
tbl["rows"].append([[testBtn1, testBtn2]])
while True:
LogStatus("`" + json.dumps(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + json.dumps(groupBtn) + "`")
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
Sleep(5000)
void main() {
json tbl = R"({
"type": "table",
"title": "Demonstrate grouping button control",
"cols": ["operation"],
"rows": []
})"_json;
json groupBtn = R"({
"type": "button",
"name": "open positions",
"cmd": "open",
"group": [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
]})"_json;
json testBtn1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."})"_json;
json testBtn2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}})"_json;
tbl["rows"].push_back({groupBtn});
tbl["rows"].push_back({{testBtn1, testBtn2}});
while(true) {
LogStatus("`" + tbl.dump() + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + groupBtn.dump() + "`");
auto cmd = GetCommand();
if(cmd != "") {
Log("cmd:", cmd);
}
Sleep(5000);
}
}
Ini mendukung untuk kontrol tombol dikelompokkan (struktur tombol lama), secara fungsional konsisten dengantombol bar status yang mendukung entri dataPerintah interaktif pada akhirnya ditangkap olehGetCommand()
Perbedaannya adalah bahwa dengan"group"
pengaturan bidang, ketika tombol diklik untuk memicu interaksi, dialog yang muncul di halaman berisi satu setkelompokdari kontrol input yang diatur untuk memasukkan sekelompok data sekaligus.
Beberapa hal yang perlu diperhatikan tentang"group"
bidang dalam struktur kontrol tombol bilah status dan kontrol tombol kelompok:
type
properti dalam kelompok hanya mendukung empat jenis berikut, dandefValue
property adalah nilai default.
|
simbol untuk memisahkan setiap opsi di kotak dropdown saat ditetapkan.
"name": "tradePrice@orderType==1"
pengaturan, yang membuatperdaganganHargakontrol input hanya tersedia ketikaorderJeniskontrol drop-down dipilih sebagaiPerintah yang sedang menunggu.|
simbol untuk memisahkan isi deskripsi dalam bahasa Cina dan Inggris.name
, description
dalam kelompok danname
, description
dalam struktur tombol tidak memiliki definisi yang sama meskipun mereka memiliki nama bidang yang sama.
Definisi dariname
dalam kelompok juga berbeda dari definisiname
dalam input.Log("cmd:", cmd)
pernyataan dalam contoh uji berikut:cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
, yaitu, apa yang dikembalikan olehGetCommand()
fungsi ketika terjadi interaksi:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
.type
properti kontrol tombol hanya mendukung:"button"
Aku tidak tahu.
Kontrol tombol yang mendukung input data, yaitu kontrol denganinput
set properti,type
properti dalam informasi konfigurasi dariinput
bidang mendukung beberapa jenis kontrol.
Perhatikan contoh-contoh berikut:function main() {
// Status bar button control (set input field to implement) testBtn1 button triggered by the page in the drop-down box control using the options field to set options, using the defValue field to set the default options. This is different from the other examples in this chapter, which use defValue to set the options directly.
var testBtn1 = {
type: "button",
name: "testBtn1",
cmd: "cmdTestBtn1",
input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1}
}
/*
Status bar button control (set input field implementation) testBtn2 button triggered by the page in the drop-down box control using the options field to set the options, options field in the options field not only supports the string,
the use of the ```{text: "description", value: "value"}``` structure is also supported. Use the defValue field to set the default option, which can be multiple choice (multiple choice via array structure). Multiple choice requires setting the additional field multiple to a true value.
*/
var testBtn2 = {
type: "button",
name: "testBtn2",
cmd: "cmdTestBtn2",
input: {
name: "testBtn2MultiComboBox",
type: "selected",
description: "Implementing dropdown box multi-selection",
options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}],
defValue: ["A", "C"],
multiple: true
}
}
// Status bar grouping button control (set group field implementation) testBtn3 button triggered by the page in the drop-down box control using the options field to set options, also supports the direct use of defValue set options.
var testBtn3 = {
type: "button",
name: "testBtn3",
cmd: "cmdTestBtn3",
group: [
{name: "comboBox1", label: "labelComboBox1", description: "Dropdown box 1", type: "selected", defValue: 1, options: ["A", "B"]},
{name: "comboBox2", label: "labelComboBox2", description: "Dropdown box 2", type: "selected", defValue: "A|B"},
{name: "comboBox3", label: "labelComboBox3", description: "Dropdown box 3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]},
{
name: "comboBox4",
label: "labelComboBox4",
description: "Dropdown box 4",
type: "selected",
defValue: ["A", "C"],
multiple: true,
options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}, {text: "Option D", value: "D"}]
}
]
}
while (true) {
LogStatus("`" + JSON.stringify(testBtn1) + "`\n", "`" + JSON.stringify(testBtn2) + "`\n", "`" + JSON.stringify(testBtn3) + "`\n")
var cmd = GetCommand()
if (cmd) {
Log(cmd)
}
Sleep(5000)
}
}
import json
def main():
testBtn1 = {
"type": "button",
"name": "testBtn1",
"cmd": "cmdTestBtn1",
"input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}
}
testBtn2 = {
"type": "button",
"name": "testBtn2",
"cmd": "cmdTestBtn2",
"input": {
"name": "testBtn2MultiComboBox",
"type": "selected",
"description": "Implementing dropdown box multi-selection",
"options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],
"defValue": ["A", "C"],
"multiple": True
}
}
testBtn3 = {
"type": "button",
"name": "testBtn3",
"cmd": "cmdTestBtn3",
"group": [
{"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},
{"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"},
{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]},
{
"name": "comboBox4",
"label": "labelComboBox4",
"description": "Dropdown box 4",
"type": "selected",
"defValue": ["A", "C"],
"multiple": True,
"options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}]
}
]
}
while True:
LogStatus("`" + json.dumps(testBtn1) + "`\n", "`" + json.dumps(testBtn2) + "`\n", "`" + json.dumps(testBtn3) + "`\n")
cmd = GetCommand()
if cmd:
Log(cmd)
Sleep(5000)
void main() {
json testBtn1 = R"({
"type": "button",
"name": "testBtn1",
"cmd": "cmdTestBtn1",
"input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}
})"_json;
json testBtn2 = R"({
"type": "button",
"name": "testBtn2",
"cmd": "cmdTestBtn2",
"input": {
"name": "testBtn2MultiComboBox",
"type": "selected",
"description": "Implementing dropdown box multi-selection",
"options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],
"defValue": ["A", "C"],
"multiple": true
}
})"_json;
json testBtn3 = R"({
"type": "button",
"name": "testBtn3",
"cmd": "cmdTestBtn3",
"group": [
{"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},
{"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"},
{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]},
{
"name": "comboBox4",
"label": "labelComboBox4",
"description": "Dropdown box 4",
"type": "selected",
"defValue": ["A", "C"],
"multiple": true,
"options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}]
}
]
})"_json;
while (true) {
LogStatus("`" + testBtn1.dump() + "`\n", "`" + testBtn2.dump() + "`\n", "`" + testBtn3.dump() + "`\n");
auto cmd = GetCommand();
if (cmd != "") {
Log(cmd);
}
Sleep(5000);
}
}
Ketika tombol status bar kelompok kontrol (diimplementasikan dengan mengaturgroup
(diimplementasikan dengan mengaturinput
field) diklik untuk memicu interaksi (struktur tombol lama), kontrol kotak drop-down di kotak dialog yang muncul di halaman juga mendukung beberapa pilihan. Contoh berikut menunjukkan cara merancang kontrol kotak drop-down dengan beberapa pilihan pemilihan:
var symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]
function createBtn(tmp, group) {
var btn = JSON.parse(JSON.stringify(tmp))
_.each(group, function(eleByGroup) {
btn["group"].unshift(eleByGroup)
})
return btn
}
function main() {
var arrManager = []
_.each(symbols, function(symbol) {
arrManager.push({
"symbol": symbol,
})
})
// Btn
var tmpBtnOpen = {
"type": "button",
"cmd": "open",
"name": "Open a position and place an order",
"group": [{
"type": "selected",
"name": "tradeType",
"label": "Order type",
"description": "Market order, limit order",
"default": 0,
"group": "Trading setup",
"settings": {
"options": ["Market order", "Limit order"],
"required": true,
}
}, {
"type": "selected",
"name": "direction",
"label": "Trading direction",
"description": "Buy, sell",
"default": "buy",
"group": "Trading setup",
"settings": {
"render": "segment",
"required": true,
"options": [{"name": "buy", "value": "buy"}, {"name": "sell", "value": "sell"}],
}
}, {
"type": "number",
"name": "price",
"label": "price",
"description": "The price of the order",
"group": "Trading setup",
"filter": "tradeType==1",
"settings": {
"required": true,
}
}, {
"type": "number",
"name": "amount",
"label": "Order quantity",
"description": "Order quantity",
"group": "Trading setup",
"settings": {
"required": true,
}
}],
}
while (true) {
var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}
_.each(arrManager, function(m) {
var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Trading instruments", "default": m["symbol"], "settings": {"required": true}}])
tbl["rows"].push([m["symbol"], btnOpen])
})
var cmd = GetCommand()
if (cmd) {
Log("Receive interaction:", cmd)
// Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
// According to the first colon: the previous instruction determines which button template triggers the message
var arrCmd = cmd.split(":", 2)
if (arrCmd[0] == "open") {
var msg = JSON.parse(cmd.slice(5))
Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", msg["tradeType"] == 0 ? "Market order" : "Limit order", msg["tradeType"] == 0 ? ", Order price: current market price" : ", Order price:" + msg["price"], ", Order quantity:", msg["amount"])
}
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
import json
symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]
def createBtn(tmp, group):
btn = json.loads(json.dumps(tmp))
for eleByGroup in group:
btn["group"].insert(0, eleByGroup)
return btn
def main():
arrManager = []
for symbol in symbols:
arrManager.append({"symbol": symbol})
# Btn
tmpBtnOpen = {
"type": "button",
"cmd": "open",
"name": "Open a position and place an order",
"group": [{
"type": "selected",
"name": "tradeType",
"label": "Order type",
"description": "Market order, limit order",
"default": 0,
"group": "Trading setup",
"settings": {
"options": ["Market order", "Limit order"],
"required": True,
}
}, {
"type": "selected",
"name": "direction",
"label": "Trading direction",
"description": "Buy, sell",
"default": "buy",
"group": "Trading Setup",
"settings": {
"render": "segment",
"required": True,
"options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
}
}, {
"type": "number",
"name": "price",
"label": "price",
"description": "The price of the order",
"group": "Trading Setup",
"filter": "tradeType==1",
"settings": {
"required": True,
}
}, {
"type": "number",
"name": "amount",
"label": "Order quantity",
"description": "Order quantity",
"group": "Trading Setup",
"settings": {
"required": True,
}
}],
}
while True:
tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}
for m in arrManager:
btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": True}}])
tbl["rows"].append([m["symbol"], btnOpen])
cmd = GetCommand()
if cmd != "" and cmd != None:
Log("Receive interaction:", cmd)
# Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
# According to the first colon: the previous instruction determines which button template triggers the message
arrCmd = cmd.split(":")
if arrCmd[0] == "open":
msg = json.loads(cmd[5:])
Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", "Market order" if msg["tradeType"] == 0 else "Limit order", ", Order price: current market price" if msg["tradeType"] == 0 else ", Order price:" + str(msg["price"]), ", Order quantity:", msg["amount"])
# Output status bar information
LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
Sleep(1000)
// Omit...
Gunakan struktur tombol terbaru untuk membangun tombol dalam tabel bilah status. Saat mengklik tombol untuk memicu interaksi, jendela pop-up multi-kontrol akan muncul. Untuk rincian lebih lanjut, silakan lihat:Panduan Pengguna - Kontrol Interaktif di Bar Status.
function main() {
var table = {
type: 'table',
title: 'position operation',
cols: ['column1', 'column2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'close positions'}]
]
}
var ticker = exchange.GetTicker()
// Add a row of data, merge the first and second cells, and output the ticker variable in the merged cell
table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"])
LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
table = {
"type" : "table",
"title" : "position operation",
"cols" : ["column1", "column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close positions"}]
]
}
ticker = exchange.GetTicker()
table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "position operation",
"cols" : ["column1", "column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close positions"}]
]
})"_json;
auto ticker = exchange.GetTicker();
json jsonTicker = R"({"Buy": 0, "Sell": 0, "High": 0, "Low": 0, "Volume": 0, "Last": 0, "Time": 0})"_json;
jsonTicker["Buy"] = ticker.Buy;
jsonTicker["Sell"] = ticker.Sell;
jsonTicker["Last"] = ticker.Last;
jsonTicker["Volume"] = ticker.Volume;
jsonTicker["Time"] = ticker.Time;
jsonTicker["High"] = ticker.High;
jsonTicker["Low"] = ticker.Low;
json arr = R"([{"body": {}, "colspan": 2}, "abc"])"_json;
arr[0]["body"] = jsonTicker;
table["rows"].push_back(arr);
LogStatus("`" + table.dump() + "`");
}
Merger horizontal sel dalam tabel yang dibuat olehLogStatus()
Fungsi:
function main() {
var table = {
type: 'table',
title: 'table demo',
cols: ['columnA', 'columnB', 'columnC'],
rows: [
['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}]
]
}
var ticker = exchange.GetTicker()
var name = exchange.GetName()
table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"])
table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"])
// A3 is merged by the first cell in the previous row
table.rows.push(["B4", "C4"])
// A2 is merged by the first cell of the previous row
table.rows.push(["B5", "C5"])
table.rows.push(["A6", "B6", "C6"])
LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
table = {
"type" : "table",
"title" : "table demo",
"cols" : ["columnA", "columnB", "columnC"],
"rows" : [
["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
]
}
ticker = exchange.GetTicker()
name = exchange.GetName()
table["rows"].append([{"body": "A2 + B2:" + json.dumps(ticker), "colspan": 2}, "C2"])
table["rows"].append([{"body": "A3 + A4 + A5:" + name, "rowspan": 3}, "B3", "C3"])
table["rows"].append(["B4", "C4"])
table["rows"].append(["B5", "C5"])
table["rows"].append(["A6", "B6", "C6"])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "table demo",
"cols" : ["columnA", "columnB", "columnC"],
"rows" : [
["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
]
})"_json;
// For testing purposes, the code is short and easy to read, and the constructed data is used here
json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json;
auto name = exchange.GetName();
json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json;
arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump();
json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json;
arr2[0]["body"] = "A3 + A4 + A5:" + name;
table["rows"].push_back(arr1);
table["rows"].push_back(arr2);
table["rows"].push_back(R"(["B4", "C4"])"_json);
table["rows"].push_back(R"(["B5", "C5"])"_json);
table["rows"].push_back(R"(["A6", "B6", "C6"])"_json);
LogStatus("`" + table.dump() + "`");
}
Secara vertikal menggabungkan sel-sel dalam tabel yang digambar olehLogStatus()
Fungsi:
function main() {
var table1 = {type: 'table', title: 'table1', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
var table2 = {type: 'table', title: 'table2', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
LogStatus('`' + JSON.stringify([table1, table2]) + '`')
}
import json
def main():
table1 = {"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
table2 = {"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
LogStatus("`" + json.dumps([table1, table2]) + "`")
void main() {
json table1 = R"({"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
json table2 = R"({"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
json arr = R"([])"_json;
arr.push_back(table1);
arr.push_back(table2);
LogStatus("`" + arr.dump() + "`");
}
Tampilan paginasi tabel bilah status:
function main(){
var tab1 = {
type : "table",
title : "table1",
cols : ["1", "2"],
rows : []
}
var tab2 = {
type : "table",
title : "table2",
cols : ["1", "2", "3"],
rows : []
}
var tab3 = {
type : "table",
title : "table3",
cols : ["A", "B", "C"],
rows : []
}
tab1.rows.push(["jack", "lucy"])
tab2.rows.push(["A", "B", "C"])
tab3.rows.push(["A", "B", "C"])
LogStatus('`' + JSON.stringify(tab1) + '`\n' +
'`' + JSON.stringify(tab2) + '`\n' +
'`' + JSON.stringify(tab3) + '`')
Log("exit")
}
import json
def main():
tab1 = {
"type": "table",
"title": "table1",
"cols": ["1", "2"],
"rows": []
}
tab2 = {
"type": "table",
"title": "table2",
"cols": ["1", "2", "3"],
"rows": []
}
tab3 = {
"type": "table",
"title": "table3",
"cols": ["A", "B", "C"],
"rows": []
}
tab1["rows"].append(["jack", "lucy"])
tab2["rows"].append(["A", "B", "C"])
tab3["rows"].append(["A", "B", "C"])
LogStatus("`" + json.dumps(tab1) + "`\n" +
"`" + json.dumps(tab2) + "`\n" +
"`" + json.dumps(tab3) + "`")
void main() {
json tab1 = R"({
"type": "table",
"title": "table1",
"cols": ["1", "2"],
"rows": []
})"_json;
json tab2 = R"({
"type": "table",
"title": "table2",
"cols": ["1", "2", "3"],
"rows": []
})"_json;
json tab3 = R"({
"type": "table",
"title": "table3",
"cols": ["A", "B", "C"],
"rows": []
})"_json;
tab1["rows"].push_back(R"(["jack", "lucy"])"_json);
tab2["rows"].push_back(R"(["A", "B", "C"])"_json);
tab3["rows"].push_back(R"(["A", "B", "C"])"_json);
LogStatus("`" + tab1.dump() + "`\n" +
"`" + tab2.dump() + "`\n" +
"`" + tab3.dump() + "`");
}
Selain menampilkan tabel dalam halaman, beberapa tabel juga dapat ditampilkan dalam urutan dari atas ke bawah:
function main() {
var tbl = {
type : "table",
title : "test scroll",
scroll : "auto",
cols : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10",
"col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
rows : []
}
for (var i = 1 ; i < 100 ; i++) {
tbl.rows.push([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i,
"11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i])
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
import json
def main():
tbl = {
"type" : "table",
"title" : "test scroll",
"scroll" : "auto",
"cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10",
"col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
"rows" : []
}
for index in range(1, 100):
i = str(index)
tbl["rows"].append([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i,
"11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i])
LogStatus("`" + json.dumps(tbl) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "test scroll",
"scroll" : "auto",
"cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10",
"col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"],
"rows" : []
})"_json;
for (int index = 1; index < 100; ++index) {
std::string i = std::to_string(index);
table["rows"].push_back({i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i,
"11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i});
}
LogStatus("`" + table.dump() + "`");
}
Dukungan untuk mengatur mode gulung horizontal dan vertikal dari tabel bilah status.scroll
atribut untuk"auto"
, ketika jumlah baris vertikal dari tabel bar status melebihi 20 baris, isi akan di geser.scroll
atribut dapat digunakan untuk meringankan masalah keterlambatan menulis sejumlah besar data di bilah status selama perdagangan langsung.
Hasil informasi dariLogStatus()
fungsi ketika perdagangan langsung berjalan tidak disimpan ke basis data perdagangan langsung, tetapi hanya memperbarui konten bilah status perdagangan langsung saat ini.
PeraturanLogStatus()
Fungsi mendukung pencetakanbase64
gambar yang dikodekan, dimulai dengan`
dan berakhir dengan`
Misalnya:LogStatus("`data:image/png;base64,AAAA`")
Aku tidak tahu.
PeraturanLogStatus()
Fungsi mendukung melewatimatplotlib.pyplot
objek langsung kePython
, selama objek berisisavefig
metode, itu dapat dilewati sebagai parameter untukLogStatus()
fungsi, misalnya:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
Ketika strategi berjalan perdagangan langsung, jika Anda pergi melalui sejarah di halaman perdagangan langsung, bilah status akan tidur dan berhenti memperbarui. hanya data bilah status akan diperbarui ketika log berada di halaman pertama.base64
gambar terenkode di bilah status, dan juga mendukung outputbase64
Gambar yang dienkode dalam tabel yang ditampilkan di bilah status. Karena data string gambar yang dienkode umumnya sangat panjang, contoh kode tidak ditampilkan.
{@fun/Global/GetCommand GetCommand}
Aktifkan atau matikan pencatatan informasi pesanan.
EnableLog (diaktifkan)
Jikaenable
Parameter diatur ke nilai palsu, misalnyafalse
, order log (yaitu log yang dihasilkan oleh fungsi sepertiexchange.Buy()
) tidak dicetak dan tidak ditulis ke database perdagangan langsung.
Memungkinkan
benar
bool
function main() {
EnableLog(false)
}
def main():
EnableLog(False)
void main() {
EnableLog(false);
}
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.CancelOrder exchange.CancelOrder}
Sesuaikan fungsi gambar grafik.
Objek grafik. objek
Grafik (pilihan)
Peraturanoptions
parameter adalah konfigurasi grafik.Chart()
parameter fungsioptions
adalahJSON
dapat diserialisasikanHighStocks
parameter untukHighcharts.StockChart
. Sebuah tambahan__isStock
atribut ditambahkan di atas parameter asli, dan jika__isStock:false
Jika data yang ditampilkan di atas adalah data yang ditampilkan di atas, maka data tersebut akan ditampilkan sebagai grafik normal.__isStock
atribut ditetapkan ke nilai palsu misalnyafalse
, yaitu grafik yang digunakan adalahHighcharts
Jika__isStock
atribut ditetapkan ke nilai benar misalnyatrue
, yaitu grafik yang digunakan adalahHighstocks
grafik (secara default)__isStock
adalah benar misalnyatrue
) Anda dapat menanyakanPerpustakaan grafik HighStocksAku tidak tahu.
pilihan
benar
objek, array objek
function main() {
var cfgA = {
extension: {
layout: 'single', // No grouping, display separately, default to group 'group'
height: 300, // Specify the height
},
title: {
text: 'handicap chart'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'buy one',
data: [],
}, {
name: 'sell one',
data: [],
}]
}
var cfgB = {
title: {
text: 'spread chart'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'spread',
type: 'column',
data: [],
}]
}
var cfgC = {
__isStock: false,
title: {
text: 'pie chart'
},
series: [{
type: 'pie',
name: 'one',
data: [
["A", 25],
["B", 25],
["C", 25],
["D", 25],
] // Instead of updating the initial data with the add function, the sequence can be updated by changing the chart configuration directly.
}]
};
var cfgD = {
extension: {
layout: 'single',
col: 8, // Specify the cell value for the width, the total value is 12
height: '300px',
},
title: {
text: 'handicap chart'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'buy one',
data: [],
}, {
name: 'sell one',
data: [],
}]
}
var cfgE = {
__isStock: false,
extension: {
layout: 'single',
col: 4,
height: '300px',
},
title: {
text: 'pie chart2'
},
series: [{
type: 'pie',
name: 'one',
data: [
["A", 25],
["B", 25],
["C", 25],
["D", 25],
]
}]
};
var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]);
chart.reset()
// Add a number of points to the pie chart, add can only update the data points added by add, built-in data points cannot be updated later.
chart.add(3, {
name: "ZZ",
y: Math.random() * 100
});
while (true) {
Sleep(1000)
var ticker = exchange.GetTicker()
if (!ticker) {
continue;
}
var diff = ticker.Sell - ticker.Buy
cfgA.subtitle = {
text: 'buy one ' + ticker.Buy + ', sell one ' + ticker.Sell,
};
cfgB.subtitle = {
text: 'spread ' + diff,
};
chart.add([0, [new Date().getTime(), ticker.Buy]]);
chart.add([1, [new Date().getTime(), ticker.Sell]]);
// Equivalent to updating the first data series of the second chart
chart.add([2, [new Date().getTime(), diff]]);
chart.add(4, [new Date().getTime(), ticker.Buy]);
chart.add(5, [new Date().getTime(), ticker.Buy]);
cfgC.series[0].data[0][1] = Math.random() * 100;
cfgE.series[0].data[0][1] = Math.random() * 100;
// update is actually the same as resetting the chart's configuration
chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]);
}
}
import random
import time
def main():
cfgA = {
"extension" : {
"layout" : "single",
"height" : 300,
"col" : 8
},
"title" : {
"text" : "handicap chart"
},
"xAxis" : {
"type" : "datetime"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
}
cfgB = {
"title" : {
"text" : "spread chart"
},
"xAxis" : {
"type" : "datetime",
},
"series" : [{
"name" : "spread",
"type" : "column",
"data" : []
}]
}
cfgC = {
"__isStock" : False,
"title" : {
"text" : "pie chart"
},
"series" : [{
"type" : "pie",
"name" : "one",
"data" : [
["A", 25],
["B", 25],
["C", 25],
["D", 25],
]
}]
}
cfgD = {
"extension" : {
"layout" : "single",
"col" : 8,
"height" : "300px"
},
"title" : {
"text" : "handicap chart"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
}
cfgE = {
"__isStock" : False,
"extension" : {
"layout" : "single",
"col" : 4,
"height" : "300px"
},
"title" : {
"text" : "pie chart2"
},
"series" : [{
"type" : "pie",
"name" : "one",
"data" : [
["A", 25],
["B", 25],
["C", 25],
["D", 25]
]
}]
}
chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE])
chart.reset()
chart.add(3, {
"name" : "ZZ",
"y" : random.random() * 100
})
while True:
Sleep(1000)
ticker = exchange.GetTicker()
if not ticker :
continue
diff = ticker["Sell"] - ticker["Buy"]
cfgA["subtitle"] = {
"text" : "buy one" + str(ticker["Buy"]) + "sell one" + str(ticker["Sell"])
}
cfgB["subtitle"] = {
"text" : "spread " + str(diff)
}
chart.add(0, [time.time() * 1000, ticker["Buy"]])
chart.add(1, [time.time() * 1000, ticker["Sell"]])
chart.add(2, [time.time() * 1000, diff])
chart.add(4, [time.time() * 1000, ticker["Buy"]])
chart.add(5, [time.time() * 1000, ticker["Buy"]])
cfgC["series"][0]["data"][0][1] = random.random() * 100
cfgE["series"][0]["data"][0][1] = random.random() * 100
void main() {
json cfgA = R"({
"extension" : {
"layout" : "single",
"height" : 300,
"col" : 8
},
"title" : {
"text" : "handicap chart"
},
"xAxis" : {
"type" : "datetime"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
})"_json;
json cfgB = R"({
"title" : {
"text" : "spread chart"
},
"xAxis" : {
"type" : "datetime"
},
"series" : [{
"name" : "spread",
"type" : "column",
"data" : []
}]
})"_json;
json cfgC = R"({
"__isStock" : false,
"title" : {
"text" : "pie chart"
},
"series" : [{
"type" : "pie",
"name" : "one",
"data" : [
["A", 25],
["B", 25],
["C", 25],
["D", 25]
]
}]
})"_json;
json cfgD = R"({
"extension" : {
"layout" : "single",
"col" : 8,
"height" : "300px"
},
"title" : {
"text" : "handicap chart"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
})"_json;
json cfgE = R"({
"__isStock" : false,
"extension" : {
"layout" : "single",
"col" : 4,
"height" : "300px"
},
"title" : {
"text" : "pie chart2"
},
"series" : [{
"type" : "pie",
"name" : "one",
"data" : [
["A", 25],
["B", 25],
["C", 25],
["D", 25]
]
}]
})"_json;
auto chart = Chart({cfgA, cfgB, cfgC, cfgD, cfgE});
chart.reset();
json zz = R"({
"name" : "ZZ",
"y" : 0
})"_json;
zz["y"] = rand() % 100;
chart.add(3, zz);
while(true) {
Sleep(1000);
auto ticker = exchange.GetTicker();
if(!ticker.Valid) {
continue;
}
auto diff = ticker.Sell - ticker.Buy;
json cfgASubTitle = R"({"text" : ""})"_json;
cfgASubTitle["text"] = format("buy one %f , sell one %f", ticker.Buy, ticker.Sell);
cfgA["subtitle"] = cfgASubTitle;
json cfgBSubTitle = R"({"text" : ""})"_json;
cfgBSubTitle["text"] = format("spread %f", diff);
cfgB["subtitle"] = cfgBSubTitle;
chart.add(0, {Unix() * 1000, ticker.Buy});
chart.add(1, {Unix() * 1000, ticker.Sell});
chart.add(2, {Unix() * 1000, diff});
chart.add(4, {Unix() * 1000, ticker.Buy});
chart.add(5, {Unix() * 1000, ticker.Buy});
cfgC["series"][0]["data"][0][1] = rand() % 100;
cfgE["series"][0]["data"][0][1] = rand() % 100;
chart.update({cfgA, cfgB, cfgC, cfgD, cfgE});
}
}
Konfigurasi gambar multi-chart:
extension.layout
atribut
Jika atribut ditetapkan dengan nilai extension.height
atribut
Atribut ini digunakan untuk mengatur tinggi grafik, baik sebagai nilai numerik, atau sebagai extension.col
atribut
Atribut ini digunakan untuk mengatur lebar grafik, lebar halaman dibagi menjadi 12 sel, set 8, yaitu, grafik menempati lebar 8 sel.// This chart is an object in the JavaScript language, and before using the Chart function, we need to declare an object variable chart to configure the chart. var chart = {
// This field marks whether the chart is a general chart or not, if you are interested, you can change it to false and run it.
__isStock: true,
// Scaling tool
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
// title
title : { text : 'spread analysis chart'},
// selection range
rangeSelector: {
buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
selected: 0,
inputEnabled: false
},
// Coordinate axis horizontal axis that is: x-axis, the current setting type is: time
xAxis: { type: 'datetime'},
// Coordinate axis vertical axis that is: y-axis, default value adjusted with the size of the data
yAxis : {
// title
title: {text: 'spread'},
// Whether to enable the right vertical axis
opposite: false
},
// Data series, this sttribute holds the individual data series (lines, K-charts, labels, etc...)
series : [
// The index is 0, and the data array holds the data of the index series
{name : "line1", id : "line1,buy1Price", data : []},
// Index is 1, set dashStyle:'shortdash' i.e.: set the dashed line
{name : "line2", id : "line2,lastPrice", dashStyle : 'shortdash', data : []}
]
} function main(){
// Call the Chart function to initialize the chart
var ObjChart = Chart(chart)
// Clear out
ObjChart.reset()
while(true){
// Gets the timestamp of this poll, i.e. a millisecond timestamp. It's used to determine the position of the X-axis written to the chart.
var nowTime = new Date().getTime()
// Get the ticker data
var ticker = _C(exchange.GetTicker)
// Get buy one price from the return value of the ticker data
var buy1Price = ticker.Buy
// To obtain the final transaction price, we add 1 in order not to overlap the 2 lines
var lastPrice = ticker.Last + 1
// Data sequence with timestamp as X-value and buy one price as Y-value passed into index 0
ObjChart.add(0, [nowTime, buy1Price])
// ditto
ObjChart.add(1, [nowTime, lastPrice])
Sleep(2000)
}
}```
```python
import time
chart = {
"__isStock" : True,
"tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},
"title" : {"text" : "spread analysis chart"},
"rangeSelector" : {
"buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}],
"selected": 0,
"inputEnabled": False
},
"xAxis": {"type": "datetime"},
"yAxis": {
"title": {"text": "spread"},
"opposite": False
},
"series": [{
"name": "line1", "id": "line1,buy1Price", "data": []
}, {
"name": "line2", "id": "line2,lastPrice", "dashStyle": "shortdash", "data": []
}]
}
def main():
ObjChart = Chart(chart)
ObjChart.reset()
while True:
nowTime = time.time() * 1000
ticker = exchange.GetTicker()
buy1Price = ticker["Buy"]
lastPrice = ticker["Last"] + 1
ObjChart.add(0, [nowTime, buy1Price])
ObjChart.add(1, [nowTime, lastPrice])
Sleep(2000)
void main() {
// When writing strategies in C++, try not to declare global variables that are not of the base type, so the chart configuration object is declared inside the main function.
json chart = R"({
"__isStock" : true,
"tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},
"title" : {"text" : "spread analysis chart"},
"rangeSelector" : {
"buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}],
"selected": 0,
"inputEnabled": false
},
"xAxis": {"type": "datetime"},
"yAxis": {
"title": {"text": "spread"},
"opposite": false
},
"series": [{
"name": "line1", "id": "line1,buy1Price", "data": []
}, {
"name": "line2", "id": "line2,lastPrice", "dashStyle": "shortdash", "data": []
}]
})"_json;
auto ObjChart = Chart(chart);
ObjChart.reset();
while(true) {
auto nowTime = Unix() * 1000;
auto ticker = exchange.GetTicker();
auto buy1Price = ticker.Buy;
auto lastPrice = ticker.Last + 1.0;
ObjChart.add(0, {nowTime, buy1Price});
ObjChart.add(1, {nowTime, lastPrice});
Sleep(2000);
}
}
Contoh gambar sederhana:
// Objects used to initialize the chart
var chart = {
// Chart title
title: {text: "line value triggers the plotLines value"},
// Y-axis related settings
yAxis: {
// A horizontal line perpendicular to the Y-axis, used as a trigger line, is a structural array that can set multiple trigger lines
plotLines: [{
// The value of the trigger line, how much it set, this line will be displayed in the corresponding value position
value: 0,
// Set the color of the trigger line
color: 'red',
// Width
width: 2,
// Displaying labels
label: {
// Label text
text: 'Trigger value',
// Centered label position
align: 'center'
}
}]
},
// X-axis related settings, here the setting type is time axis
xAxis: {type: "datetime"},
series: [
{name: "sin", type: "spline", data: []},
// This is an important data series, you can set multiple data series, according to the array index control
{name: "cos", type: "spline", data: []}
]
}
function main(){
// Circumference
var pi = 3.1415926535897
// Variables for recording timestamps
var time = 0
// Angle
var angle = 0
// Coordinate y values for receiving sine and cosine values
var y = 0
// Call the API interface to initialize the chart with the chart object
var objChart = Chart(chart)
// Initially, clear the chart
objChart.reset()
// Set the value of the trigger line to 1
chart.yAxis.plotLines[0].value = 1
// Loop
while(true){
// Get the timestamp of the current moment
time = new Date().getTime()
// Angle increases by 5 degrees every 500ms and calculates the sine value
y = Math.sin(angle * 2 * pi / 360)
// Write the calculated y value to the data series of the corresponding index of the chart, the first parameter of the add function is the specified data series index
objChart.add(0, [time, y])
// Calculate the cosine value
y = Math.cos(angle * 2 * pi / 360)
objChart.add(1, [time, y])
// Increase by 5 degrees
angle += 5
// Pause for 5 seconds to avoid drawing too often and growing data too fast
Sleep(5000)
}
}
import math
import time
chart = {
"title": {"text": "line value triggers the plotLines value"},
"yAxis": {
"plotLines": [{
"value": 0,
"color": "red",
"width": 2,
"label": {
"text": "trigger value",
"align": "center"
}
}]
},
"xAxis": {"type": "datetime"},
"series": [{"name": "sin", "type": "spline", "data": []},
{"name": "cos", "type": "spline", "data": []}]
}
def main():
pi = 3.1415926535897
ts = 0
angle = 0
y = 0
objChart = Chart(chart)
objChart.reset()
chart["yAxis"]["plotLines"][0]["value"] = 1
while True:
ts = time.time() * 1000
y = math.sin(angle * 2 * pi / 360)
objChart.add(0, [ts, y])
y = math.cos(angle * 2 * pi / 360)
objChart.add(1, [ts, y])
angle += 5
Sleep(5000)
void main() {
json chart = R"({
"title": {"text": "line value triggers the plotLines value"},
"yAxis": {
"plotLines": [{
"value": 0,
"color": "red",
"width": 2,
"label": {
"text": "trigger value",
"align": "center"
}
}]
},
"xAxis": {"type": "datetime"},
"series": [{"name": "sin", "type": "spline", "data": []},
{"name": "cos", "type": "spline", "data": []}]
})"_json;
auto pi = 3.1415926535897;
auto ts = 0;
auto angle = 0.0;
auto y = 0.0;
auto objChart = Chart(chart);
objChart.reset();
chart["yAxis"]["plotLines"][0]["value"] = 1;
while(true) {
ts = Unix() * 1000;
y = sin(angle * 2 * pi / 360);
objChart.add(0, {ts, y});
y = cos(angle * 2 * pi / 360);
objChart.add(1, {ts, y});
angle += 5;
Sleep(5000);
}
}
Contoh gambar kurva trigonometri:
/*backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
var chartCfg = {
subtitle: {
text: "subtitle",
},
yAxis: [{
height: "40%",
lineWidth: 2,
title: {
text: 'PnL',
},
tickPixelInterval: 20,
minorGridLineWidth: 1,
minorTickWidth: 0,
opposite: true,
labels: {
align: "right",
x: -3,
}
}, {
title: {
text: 'Profit',
},
top: "42%",
height: "18%",
offset: 0,
lineWidth: 2
}, {
title: {
text: 'Vol',
},
top: '62%',
height: '18%',
offset: 0,
lineWidth: 2
}, {
title: {
text: 'Asset',
},
top: '82%',
height: '18%',
offset: 0,
lineWidth: 2
}],
series: [{
name: 'PnL',
data: [],
id: 'primary',
tooltip: {
xDateFormat: '%Y-%m-%d %H:%M:%S'
},
yAxis: 0
}, {
type: 'column',
lineWidth: 2,
name: 'Profit',
data: [],
yAxis: 1,
}, {
type: 'column',
name: 'Trade',
data: [],
yAxis: 2
}, {
type: 'area',
step: true,
lineWidth: 0,
name: 'Long',
data: [],
yAxis: 2
}, {
type: 'area',
step: true,
lineWidth: 0,
name: 'Short',
data: [],
yAxis: 2
}, {
type: 'line',
step: true,
color: '#5b4b00',
name: 'Asset',
data: [],
yAxis: 3
}, {
type: 'pie',
innerSize: '70%',
name: 'Random',
data: [],
center: ['3%', '6%'],
size: '15%',
dataLabels: {
enabled: false
},
startAngle: -90,
endAngle: 90,
}],
};
function main() {
let c = Chart(chartCfg);
let preTicker = null;
while (true) {
let t = exchange.GetTicker();
c.add(0, [t.Time, t.Last]); // PnL
c.add(1, [t.Time, preTicker ? t.Last - preTicker.Last : 0]); // profit
let r = Math.random();
var pos = parseInt(t.Time/86400);
c.add(2, [t.Time, pos/2]); // Vol
c.add(3, [t.Time, r > 0.8 ? pos : null]); // Long
c.add(4, [t.Time, r < 0.8 ? -pos : null]); // Short
c.add(5, [t.Time, Math.random() * 100]); // Asset
// update pie
chartCfg.series[chartCfg.series.length-1].data = [
["A", Math.random()*100],
["B", Math.random()*100],
];
c.update(chartCfg)
preTicker = t;
}
}
'''backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
import random
chartCfg = {
"subtitle": {
"text": "subtitle"
},
"yAxis": [{
"height": "40%",
"lineWidth": 2,
"title": {
"text": 'PnL'
},
"tickPixelInterval": 20,
"minorGridLineWidth": 1,
"minorTickWidth": 0,
"opposite": True,
"labels": {
"align": "right",
"x": -3
}
}, {
"title": {
"text": 'Profit'
},
"top": "42%",
"height": "18%",
"offset": 0,
"lineWidth": 2
}, {
"title": {
"text": 'Vol'
},
"top": '62%',
"height": '18%',
"offset": 0,
"lineWidth": 2
}, {
"title": {
"text": 'Asset'
},
"top": '82%',
"height": '18%',
"offset": 0,
"lineWidth": 2
}],
"series": [{
"name": 'PnL',
"data": [],
"id": 'primary',
"tooltip": {
"xDateFormat": '%Y-%m-%d %H:%M:%S'
},
"yAxis": 0
}, {
"type": 'column',
"lineWidth": 2,
"name": 'Profit',
"data": [],
"yAxis": 1
}, {
"type": 'column',
"name": 'Trade',
"data": [],
"yAxis": 2
}, {
"type": 'area',
"step": True,
"lineWidth": 0,
"name": 'Long',
"data": [],
"yAxis": 2
}, {
"type": 'area',
"step": True,
"lineWidth": 0,
"name": 'Short',
"data": [],
"yAxis": 2
}, {
"type": 'line',
"step": True,
"color": '#5b4b00',
"name": 'Asset',
"data": [],
"yAxis": 3
}, {
"type": 'pie',
"innerSize": '70%',
"name": 'Random',
"data": [],
"center": ['3%', '6%'],
"size": '15%',
"dataLabels": {
"enabled": False
},
"startAngle": -90,
"endAngle": 90
}]
}
def main():
c = Chart(chartCfg)
preTicker = None
while True:
t = exchange.GetTicker()
c.add(0, [t["Time"], t["Last"]])
profit = t["Last"] - preTicker["Last"] if preTicker else 0
c.add(1, [t["Time"], profit])
r = random.random()
pos = t["Time"] / 86400
c.add(2, [t["Time"], pos / 2])
long = pos if r > 0.8 else None
c.add(3, [t["Time"], long])
short = -pos if r < 0.8 else None
c.add(4, [t["Time"], short])
c.add(5, [t["Time"], random.random() * 100])
# update pie
chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
["A", random.random() * 100],
["B", random.random() * 100]
]
c.update(chartCfg)
preTicker = t
/*backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json chartCfg = R"({
"subtitle": {
"text": "subtitle"
},
"yAxis": [{
"height": "40%",
"lineWidth": 2,
"title": {
"text": "PnL"
},
"tickPixelInterval": 20,
"minorGridLineWidth": 1,
"minorTickWidth": 0,
"opposite": true,
"labels": {
"align": "right",
"x": -3
}
}, {
"title": {
"text": "Profit"
},
"top": "42%",
"height": "18%",
"offset": 0,
"lineWidth": 2
}, {
"title": {
"text": "Vol"
},
"top": "62%",
"height": "18%",
"offset": 0,
"lineWidth": 2
}, {
"title": {
"text": "Asset"
},
"top": "82%",
"height": "18%",
"offset": 0,
"lineWidth": 2
}],
"series": [{
"name": "PnL",
"data": [],
"id": "primary",
"tooltip": {
"xDateFormat": "%Y-%m-%d %H:%M:%S"
},
"yAxis": 0
}, {
"type": "column",
"lineWidth": 2,
"name": "Profit",
"data": [],
"yAxis": 1
}, {
"type": "column",
"name": "Trade",
"data": [],
"yAxis": 2
}, {
"type": "area",
"step": true,
"lineWidth": 0,
"name": "Long",
"data": [],
"yAxis": 2
}, {
"type": "area",
"step": true,
"lineWidth": 0,
"name": "Short",
"data": [],
"yAxis": 2
}, {
"type": "line",
"step": true,
"color": "#5b4b00",
"name": "Asset",
"data": [],
"yAxis": 3
}, {
"type": "pie",
"innerSize": "70%",
"name": "Random",
"data": [],
"center": ["3%", "6%"],
"size": "15%",
"dataLabels": {
"enabled": false
},
"startAngle": -90,
"endAngle": 90
}]
})"_json;
Chart c = Chart(chartCfg);
Ticker preTicker;
while(true) {
auto t = exchange.GetTicker();
c.add(0, {t.Time, t.Last});
auto profit = preTicker.Valid ? t.Last - preTicker.Last : 0;
c.add(1, {t.Time, profit});
auto r = rand() % 100;
auto pos = t.Time / 86400.0;
c.add(2, {t.Time, pos / 2.0});
auto longPos = r > 0.8 ? pos : NULL;
c.add(3, {t.Time, longPos});
auto shortPos = r < 0.8 ? -pos : NULL;
c.add(4, {t.Time, shortPos});
c.add(5, {t.Time, rand() % 100});
// update pie
json pie = R"([["A", 0], ["B", 0]])"_json;
pie[0][1] = rand() % 100;
pie[1][1] = rand() % 100;
chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie;
c.update(chartCfg);
preTicker = t;
}
}
Contoh kompleks penggunaan grafik hibrida:
// update pie
chartCfg.series[chartCfg.series.length-1].data = [
["A", Math.random()*100],
["B", Math.random()*100],
];
c.update(chartCfg)
# update pie
chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
["A", random.random() * 100],
["B", random.random() * 100]
]
c.update(chartCfg)
// update pie
json pie = R"([["A", 0], ["B", 0]])"_json;
pie[0][1] = rand() % 100;
pie[1][1] = rand() % 100;
chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie;
c.update(chartCfg);
Bagan tipepie
adalah grafik tanpa garis waktu, dan Anda perlu memperbarui konfigurasi grafik langsung saat memperbarui data.c.update(chartCfg)
setelah memperbarui data, sebagai berikut:
PeraturanChart()
fungsi mengembalikan objek grafik yang memiliki 4 metode:add()
, reset()
, update()
, del()
.
update()
metode:
Peraturanupdate()
Metode ini dapat memperbarui informasi konfigurasi grafik. Parameter dari metode ini adalah objek konfigurasi grafik (JSON).del()
metode:
Peraturandel()
Metode ini dapat menghapus seri data dari indeks yang ditentukan berdasarkan parameter seri yang dilewati.add()
metode:
Peraturanadd()
metode dapat menulis data ke grafik, dengan parameter berikut dalam urutan:series
: digunakan untuk mengatur indeks seri data, yang merupakan bilangan bulat.data
: digunakan untuk mengatur data tertentu yang akan ditulis, itu adalah array.index
(opsional): digunakan untuk mengatur indeks data, ini adalah bilangan bulat.-1
mengacu pada data terakhir dalam set data.
Misalnya, ketika menggambar garis, mengubah data pada titik terakhir garis:chart.add(0, [1574993606000, 13.5], -1)
, yaitu, mengubah data pada titik pertama penultimate grafikseries[0].data
Aku tidak tahu.
Peraturanindex
parameter tidak ditetapkan, yang berarti bahwa data ditambahkan ke titik terakhir dari seri data saat ini.reset()
metode:
Peraturanreset()
metode digunakan untuk mengosongkan data grafik.reset()
Metode dapat mengambil parameterremain
untuk menentukan jumlah entri untuk menyimpan.remain
Dioperasikan untuk menghapus semua data.{@fun/Log/KLineChart KLineChart}
Fungsi ini digunakan untuk menggambar kustom pada strategi runtime menggunakan metode menggambar mirip denganPine
language.
Objek grafik.KLineChart()
fungsi mengembalikan objek grafik dengan beberapa metode, di antaranya Anda perlu memperhatikanbegin()
danclose()
Operasi menggambar harus dimulai denganbegin()
panggilan fungsi dan berakhir denganclose()
panggilan fungsi saat melintasi data KLine untuk melakukan operasi gambar.
objek
KLineChart (opsi)
Peraturanoptions
Parameter adalah konfigurasi grafik.
pilihan
benar
objek, array objek
function main() {
// Call the KLineChart function to create a chart control object c
let c = KLineChart({
overlay: true
})
// Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up the contract first.
let bars = exchange.GetRecords()
if (!bars) {
return
}
// Execute the drawing operation by traversing over the K-line data. The drawing operation must start with the ```c.begin(bar)``` function call and end with the ```c.close()``` function call.
bars.forEach(function(bar, index) {
c.begin(bar)
c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)')
if (bar.Close > bar.Open) {
c.bgcolor('rgba(0, 255, 0, 0.5)')
}
let h = c.plot(bar.High, 'high')
let l = c.plot(bar.Low, 'low')
c.fill(h, l, {
color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'
})
c.hline(bar.High)
c.plotarrow(bar.Close - bar.Open)
c.plotshape(bar.Low, {
style: 'diamond'
})
c.plotchar(bar.Close, {
char: 'X'
})
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
if (bar.Close > bar.Open) {
// long/short/closelong/closeshort
c.signal("long", bar.High, 1.5)
} else if (bar.Close < bar.Open) {
c.signal("closelong", bar.Low, 1.5)
}
c.close()
})
}
def main():
# Call the KLineChart function to create a chart control object c
c = KLineChart({
"overlay": True
})
# Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up the contract first.
bars = exchange.GetRecords()
if not bars:
return
for bar in bars:
c.begin(bar)
c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
if bar.Close > bar.Open:
c.bgcolor('rgba(0, 255, 0, 0.5)')
h = c.plot(bar.High, 'high')
l = c.plot(bar.Low, 'low')
c.fill(h, l, 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)')
c.hline(bar.High)
c.plotarrow(bar.Close - bar.Open)
c.plotshape(bar.Low, style = 'diamond')
c.plotchar(bar.Close, char = 'X')
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
if bar.Close > bar.Open:
# long/short/closelong/closeshort
c.signal("long", bar.High, 1.5)
elif bar.Close < bar.Open:
c.signal("closelong", bar.Low, 1.5)
c.close()
// Not supported for now
Jika objek kontrol grafik diperlukan untuk menggambar di area gambar khusus strategi, gunakanKLineChart()
fungsi untuk membuat objek.KLineChart()
fungsi adalah struktur konfigurasi grafik, yang digunakan dalam kode referensi sederhana:{overlay: true}
. Struktur konfigurasi grafik ini hanya menetapkan konten gambar yang akan di output pada grafik utama.overlay
ditetapkan pada nilai false, misalnyafalse
Jika Anda perlu menentukan fungsi gambar untuk menggambar pada bagan utama, Anda juga dapat menentukan parameteroverlay
sebagai nilai benar dalam panggilan fungsi tertentu, misalnya:true
.
c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') // Use the example illustrated in the reference code in this example, without further ado
c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
// Not supported for now
Fungsi antarmuka gambar dariPine
bahasa yang didukung dalam operasi gambar adalah:barcolor
, yang mengatur warna garis K.
barcolor ((warna, offset, dapat diedit, show_last, judul, tampilan) parameter tampilan opsional:
tidak ada , semua
c.bgcolor('rgba(0, 255, 0, 0.5)')
c.bgcolor('rgba(0, 255, 0, 0.5)')
// Not supported for now
bgcolor
, mengisi latar belakang garis K dengan warna yang ditentukan.
bgcolor ((warna, offset, dapat diedit, show_last, judul, tampilan, overlay) parameter tampilan opsional:
tidak ada , semua
c.plot(bar.High, 'high')
c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"}) // Support for drawing discontinuous data lines
h = c.plot(bar.High, 'high')
h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr") # Support for drawing discontinuous data lines
// Not supported for now
plot
, memetakan serangkaian data pada grafik.
plot ((seri, judul, warna, lebar baris, gaya, trackprice, histbase, offset, join, editable, show_last, display) parameter gaya opsional:
stepline_diamond , stepline , cross , areabr , area , circles , columns , histogram , linebr , line parameter tampilan opsional: tidak ada , semua
let h = c.plot(bar.High, 'high')
let l = c.plot(bar.Low, 'low')
c.fill(h, l, {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'})
h = c.plot(bar.High, 'high')
l = c.plot(bar.Low, 'low')
c.fill(h, l, color = 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)'})
// Not supported for now
fill
, mengisi latar belakang antara dua plot atauhline
dengan warna yang disediakan.
mengisi (line1, line2, warna, judul, dapat diedit, mengisi celah, menampilkan) parameter tampilan opsional:
tidak ada , semua
SejakJavaScript
bahasa tidak dapat menentukan parameter masuk berdasarkan nama parameter fungsi formal, untuk memecahkan masalah ini, Anda dapat menggunakan{key: value}
struktur untuk menentukan parameter yang akan dilewatkan ke nama parameter formal tertentu.
Misalnya, kode referensi menggunakan{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)'}
menentukancolor
parameter darifill
fungsi.
Jika Anda perlu menentukan beberapa parameter dengan nama parameter bentuk berturut-turut, Anda dapat menggunakan{key1: value1, key2: value2, key3: value3}
Aku tidak tahu.
Misalnya, dalam contoh ini, tambahantitle
parameter ditentukan:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)', title: 'fill'}
Aku tidak tahu.
Untuk nilai warna, Anda dapat mengaturnya dengan'rgba(255, 0, 0, 0, 0.2)'
atau dengan'#FF0000'
.
c.hline(bar.High)
c.hline(bar.High)
// Not supported for now
hline
, garis horizontal disajikan pada tingkat harga tetap tertentu.
hline ((harga, judul, warna, gaya baris, lebar baris, dapat diedit, tampilan) Parameter gaya garis bersifat opsional:
bergaris-garis , bertitik , padat parameter tampilan opsional: tidak ada , semua
c.plotarrow(bar.Close - bar.Open)
c.plotarrow(bar.Close - bar.Open)
// Not supported for now
plotarrow
, menggambar panah ke atas dan ke bawah pada grafik.
Plotarrow ((seri, judul, colorup, colorordown, offset, minheight, maxheight, editable, show_last, display) parameter tampilan opsional:
tidak ada , semua
c.plotshape(bar.Low, {style: 'diamond'})
c.plotshape(bar.Low, style = 'diamond')
// Not supported for now
plotshape
, menggambar bentuk visual pada grafik.
plotshape ((seri, judul, gaya, lokasi, warna, offset, teks, textcolor, dapat diedit, ukuran, show_last, display) parameter gaya opsional:
diamond size.autoadalah ukuran kecil. parameter tampilan opsional:, square , label_down , label_up , arrow_down , arrow_up , circle , flag , triangle_down , triangle_up , cross , xcross parameter lokasi bersifat opsional: bar atas , bar bawah , top , bottom , absolute parameter ukuran adalah opsional: 10px , 14px , 20px , 40px , 80px , membandingkan size.tiny, size.small, size.normal, size.large, size.huge dalam bahasa Pine. tidak ada , semua
c.plotchar(bar.Close, {char: 'X'})
c.plotchar(bar.Close, char = 'X')
// Not supported for now
plotchar
, menggambar bentuk visual pada grafik menggunakan karakter Unicode tertentu.
plotchar ((seri, judul, char, lokasi, warna, offset, teks, textcolor, editable, size, show_last, display) parameter lokasi bersifat opsional:
abovebar size.autoadalah ukuran kecil. parameter tampilan opsional:, belowbar , top , bottom , absolute parameter ukuran adalah opsional: 10px , 14px , 20px , 40px , 80px , membandingkan size.tiny, size.small, size.normal, size.large, size.huge dalam bahasa Pine. tidak ada , semua
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
// Not supported for now
plotcandle
, menggambar grafik garis K pada grafik.
plotcandle ((buka, tinggi, rendah, dekat, judul, warna, wickcolor, editable, show_last, bordercolor, display) parameter tampilan opsional:
tidak ada , semua
c.signal("long", bar.High, 1.5)
c.signal("long", bar.High, 1.5)
// Not supported for now
signal
, fungsi yang tidak tersedia pada bahasa Pine, digunakan untuk menarik sinyal beli dan jual di sini.
sinyal ((arah, harga, qty, id) Parameter
long diteruskan untuk menunjukkan arah transaksi, Anda dapat memilih long , closelong , short , closeshort . bar.High
adalah posisi sumbu Y dari sinyal penanda. Parameter 1.5 yang dilewati menunjukkan jumlah transaksi sinyal. Parameter keempat dapat dilewati untuk menggantikan konten teks default yang ditarik, dan teks default dari penanda sinyal yang ditarik adalah arah transaksi, misalnyacloselong .
c.reset()
c.reset()
// Not supported for now
reset
, fungsi yang tidak tersedia pada bahasa Pine, digunakan untuk mengosongkan data grafik.
Reset (tetap) Peraturan
reset()
metode dapat mengambil satu parameter,remain
, untuk menentukan jumlah data yang harus disimpan.remain
berarti menghapus semua data.
Strategi gambar kustom hanya dapat menggunakan salah satu caraKLineChart()
fungsi atauChart()
Untuk beberapa pengaturan warna dan gaya yang digunakan dalamKLineChart()
panggilan fungsi, silakan lihatGunakan fungsi KLineChart untuk membuat desain strategi gambar lebih mudah.
{@fun/Log/Chart Chart}
Bersihkan lognya.
LogReset (tetap)
Peraturanremain
Parameter digunakan untuk mengatur jumlah entri log terbaru yang harus disimpan.
tetap
palsu
nomor
function main() {
// Keep the last 10 logs and clear the rest
LogReset(10)
}
def main():
LogReset(10)
void main() {
LogReset(10);
}
Log startup untuk setiap awal strategi perdagangan langsung dihitung sebagai satu, jadi jika tidak ada parameter yang diteruskan dan tidak ada output log pada awal strategi, tidak ada log yang akan ditampilkan sama sekali, menunggu log docker untuk dikembalikan (bukan pengecualian).
{@fun/Log Log}, {@fun/Log/LogVacuum LogVacuum}
Digunakan untuk merebut kembali ruang penyimpanan yang diduduki olehSQLiteketika menghapus data setelah memanggilLogReset()
Fungsi untuk menghapus log.
LogVacuum ((()
function main() {
LogReset()
LogVacuum()
}
def main():
LogReset()
LogVacuum()
void main() {
LogReset()
LogVacuum()
}
Alasannya adalah bahwaSQLite
tidak merebut kembali ruang yang diduduki saat menghapus data, dan perlu dijalankanVACUUM
Untuk membersihkan tabel dan membebaskan ruang. file move operasi terjadi ketika fungsi ini dipanggil, dan keterlambatan yang besar, sehingga disarankan untuk memanggil pada interval waktu yang tepat.
{@fun/Log/LogReset LogReset}
Ini digunakan untuk output informasi debugging di kolom 123456
, yangconsole.log
fungsi output debugging informasi pada halaman perdagangan hidup, dan pada saat yang sama, membuat file log dengan ekstensi.log
dan menulis informasi debugging di/logs/storage/123456/
dalam direktori docker yang termasuk perdagangan langsung, dengan awalan nama filestdout_
.
konsol.log ((...msgs)
Parametermsg
adalah isi output, dan parametermsg
bisa dilewati lebih dari satu.
msg
palsu
string, number, bool, object, array, null dan tipe lain yang didukung oleh sistem.
function main() {
console.log("test console.log")
}
# Not supported
// Not supported
JavaScript
bahasa mendukung fungsi ini.[object Object]
, jadi cobalah untuk output sebanyak mungkin informasi yang dapat dibaca.{@fun/Log/console.errorconsole.error}
Digunakan untuk output kesalahan di kolom 123456
, yangconsole.error
fungsi membuat file log dengan ekstensi.log
dalam/logs/storage/123456/
direktori dari docker di mana perdagangan hidup milik, dan menulis output kesalahan dengan awalanstderr_
.
konsol.kesalahan(...msgs)
Parametermsg
adalah isi output, dan parametermsg
bisa dilewati lebih dari satu.
msg
palsu
string, number, bool, object, array, null dan tipe lain yang didukung oleh sistem.
function main() {
console.error("test console.error")
}
# Not supported
// Not supported
JavaScript
bahasa mendukung fungsi ini.[object Object]
, jadi cobalah untuk output sebanyak mungkin informasi yang dapat dibaca.{@fun/Log/console.log konsol.log}
Global Pasar