Журналы выводов.
Регистрация (...msgs)
Параметрmsg
является содержанием вывода, и параметрmsg
может пройти более одного.
СМС
ложное
строка, число, bool, объект, массив, любой тип, поддерживаемый системой, например null.
function main() {
Log("msg1", "msg2", "msg3")
}
def main():
Log("msg1", "msg2", "msg3")
void main() {
Log("msg1", "msg2", "msg3");
}
Многочисленныеmsg
параметры могут быть переданы:
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@");
}
Он поддерживает настройку цвета сообщения вывода, если мы используем настройки цвета и нажмите в то же время, мы должны установить цвет в первую очередь и использовать@
Персонаж, который будет толкать последним.
function main() {
Log("`data:image/png;base64,AAAA`")
}
def main():
Log("`data:image/png;base64,AAAA`")
void main() {
Log("`data:image/png;base64,AAAA`");
}
ВLog()
функция поддерживает печатьbase64
кодированные изображения, начиная с`
и заканчивается`
, например:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
ВLog()
Функция поддерживает прямую печатьPython
Это...matplotlib.pyplot
До тех пор, пока объект содержитsavefig
С помощью этого метода можно напечататьLog
функция, например:
function main() {
Log("[trans]中文|abc[/trans]")
}
def main():
Log("[trans]中文|abc[/trans]")
void main() {
Log("[trans]中文|abc[/trans]");
}
ВLog()
Функция поддерживает переключение языков.Log()
функция выводит текст, который автоматически переключается на соответствующий язык на основе настройки языка на странице платформы, например:
ВLog()
функция выводит сообщение о журнале в области журнала реального времени торгового процесса или системы обратного тестирования, и журнал сохраняется в базе данных реального времени торгового процесса при запуске реального времени торговли.Log()
функция выводит сообщение, заканчивающееся@
Нажмите на адрес электронной почты, адрес WebHook и т. д.Нажмите настройкиПодача сообщений не поддерживаетсяИнструменты отладки, система обратного тестирования. Существует ограничение частоты для push сообщения. Конкретные правила ограничения следующие: в течение 20-секундного цикла живой торговли будет сохранено и push только последнее push сообщение, а другие сообщения будут отфильтрованы и не push (вывод push log функцией Log будет распечатан и отображаться в регистре).
ДляWebHook
push, вы можете использовать сервисную программу, написаннуюGolang
:
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)
}
УстановленоWebHook
вНажмите настройки: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ
- Да.
После того, как я провел записьGolang
Программа обслуживания, мы начинаем запускать стратегию живой торговли, следующая стратегия написана вJavaScript
Изучение языка, стратегия выполняетLog()
Функция и подталкивание сообщения:
function main() {
Log("msg", "@")
}
Программа обслуживания, написанная вGolang
язык получает нажатие и сервисная программа печатает сообщение:
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}, {@fun/Log/LogReset LogReset}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogReset LogReset}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogVacuum}, {@fun/Log/LogVacuum}, {@fun/LogVacuum},
Запишите стоимость прибыли и убытков, напечатайте стоимость прибыли и убытков и набросьте кривую возврата на основе стоимости прибыли и убытков.
LogProfit (прибыль) LogProfit ((прибыль,... аргументы)
Параметрprofit
Это данные о доходах, которые даются алгоритмом проектирования и расчетов в стратегии.
прибыль
Истинно
Номер
Расширенный параметр для вывода дополнительной информации в журнале доходов,arg
Параметры могут быть переданы более чем одному.
арг
ложное
строка, число, bool, объект, массив, любой тип, поддерживаемый системой, например 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);
}
}
ВLogProfit
функция, если она заканчивается символом&
, составляет только график доходов и не печатает журнал доходов.
{@fun/Log/LogProfitReset LogProfitReset} - Я не знаю.
Уберите все журналы доходов, графики доходов.
LogProfitReset (() LogProfitReset ((остаться)
Вremain
Параметр используется для указания количества записей в журнале (значения целых чисел), которые необходимо хранить.
оставаться
ложное
Номер
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} Я не знаю.
Выходная информация в строке состояния системы обратного тестирования или страницы торговли в режиме реального времени.
LogStatus ((...msgs)
Параметрmsg
является содержанием вывода, и параметрmsg
может пройти более одного.
СМС
ложное
строка, число, bool, объект, массив, любой тип, поддерживаемый системой, например 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");
}
Поддерживает настройку цвета выходного содержимого:
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() + "`");
}
Пример вывода данных в строке состояния:
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() + "`");
}
Он поддерживает проектирование кнопок управления в строке состояния (старая структура кнопок):
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() + "`");
}
Установите отключенную функцию описания кнопки строки состояния (старая структура кнопки):
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);
}
}
В сочетании сGetCommand()
Функция, создать функцию взаимодействия кнопки строки состояния (старая структура кнопки):
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);
}
}
Вводные данные также поддерживаются при построении кнопок строки состояния для взаимодействия, и команды взаимодействия захватываютсяGetCommand()
В конце концов.input
элементы (старая структура кнопки) к структуре данных кнопки управления в строке состояния, например, добавление"input": {"name": "number of open positions", "type": "number", "defValue": 1}
до{"type": "button", "cmd": "open", "name": "open position"}
вызовет появление всплывающего окна с элементом управления окна ввода при нажатии кнопки (значение по умолчанию в окне ввода составляет 1, что является данными, установленнымиdefValue
Вы можете ввести данные, которые будут отправлены вместе с командой кнопки. Например, при запуске следующего тестового кода, после нажатия кнопки "открыть положениеGetCommand()
Функция затем захватит сообщение: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);
}
}
Он поддерживает группированные кнопки управления (старая структура кнопок), функционально совместимые скнопки строки состояния, поддерживающие ввод данных(установлено с помощью поля GetCommand()
Разница в том, что с"group"
Поле настройки, когда кнопка нажимается, чтобы запустить взаимодействие, диалог, который появляется на странице содержит наборгруппавводных элементов управления, установленных для одновременного ввода группы данных.
Некоторые моменты, которые следует отметить о"group"
поле в структуре кнопки управления строкой состояния и группы кнопок управления:
type
В группе, поддерживает только следующие четыре типа, иdefValue
property - это значение по умолчанию.
|
символ для разделения каждой опции в выпадающем окне, как она установлена.
"name": "tradePrice@orderType==1"
Установка, которая делаетtradeЦенаУправление вводом доступно только приПорядок Типвыпадающий элемент управления выбран какЗаказ в ожидании.|
символы для разделения содержания описания на китайском и английском языках.name
, description
в группе иname
, description
в структуре кнопок не имеют одинаковых определений, хотя имеют одинаковые имена полей.
Определениеname
в группе также отличается от определенияname
вход.Log("cmd:", cmd)
Заявление в следующем примере испытания:cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
, т.е. то, что возвращаетсяGetCommand()
функция, когда происходит взаимодействие:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
.type
свойство кнопки управления поддерживает только:"button"
- Да.
Кнопки управления, поддерживающие ввод данных, т.е.input
набор свойств,type
свойство в конфигурации информацииinput
поле поддерживает несколько типов элементов управления.
Обратите внимание на следующие примеры: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);
}
}
Когда кнопка управления группой в строке состояния (используется путем установкиgroup
поле) и кнопку управления строкой состояния (используется путем установкиinput
поле) нажимаются, чтобы запустить взаимодействие (старая структура кнопки), контрольный элемент выпадающего окна в диалоговом окне, который появляется на странице, также поддерживает несколько выборов.
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...
Используйте новейшую структуру кнопок для создания кнопок в таблице строки состояния. Дополнительная информация:Руководство пользователя - Интерактивные элементы управления в строке состояния.
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() + "`");
}
Горизонтальное объединение ячеек в таблице, составленнойLogStatus()
Функция:
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() + "`");
}
Вертикально слить ячейки в таблице, нарисованнойLogStatus()
Функция:
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() + "`");
}
Показать таблицу строки состояния:
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() + "`");
}
В дополнение к отображению таблиц на страницах, несколько таблиц также могут отображаться в порядке сверху вниз:
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() + "`");
}
Поддержка установки горизонтального и вертикального режима прокрутки таблицы строки состояния.scroll
атрибут к"auto"
, когда число вертикальных строк таблицы полосы состояния превышает 20 строк, содержимое будет прокручиваться.scroll
атрибут может быть использован для устранения проблемы задержки записи большого количества данных в строку состояния во время торговли в режиме реального времени.
Выпуск информации изLogStatus()
Функция, когда ведется прямая торговля, не сохраняется в базе данных прямых торгов, но обновляет только содержимое текущей строки состояния прямых торгов.
ВLogStatus()
функция поддерживает печатьbase64
кодированные изображения, начиная с`
и заканчивается`
Например:LogStatus("`data:image/png;base64,AAAA`")
- Да.
ВLogStatus()
Функция поддерживает прохождениеmatplotlib.pyplot
объекты прямо вPython
, пока объект содержитsavefig
метод, он может быть передан в качестве параметра кLogStatus()
функция, например:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
Когда стратегия работает в режиме реального времени, если вы просматриваете историю на странице реального времени, панель статуса будет бездействовать и перестанет обновляться. Только данные панели статуса обновляются, когда журнал находится на первой странице.base64
кодированные изображения в строке состояния, и он также поддерживает выходbase64
Поскольку строка данных зашифрованного изображения, как правило, очень длинная, код образца не отображается.
{@fun/Global/GetCommand GetCommand} - Что ты делаешь?
Включить или отключить регистрацию информации о заказах.
EnableLog (включен)
Еслиenable
параметр установлен на ложное значение, напримерfalse
, журнал заказов (т.е. журнал, генерируемый такими функциями, какexchange.Buy()
) не печатается и не записывается в базу данных торгов в режиме реального времени.
позволить
Истинно
Буль
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}
Настроить функцию рисования диаграммы.
Объект с графиком. объект
Диаграмма (варианты)
Вoptions
Параметр - это конфигурация диаграммы.Chart()
параметр функцииoptions
являетсяJSON
сериализируемыйHighStocks
параметр дляHighcharts.StockChart
Дополнительный__isStock
атрибут добавляется над нативным параметром, и если__isStock:false
Если вы указываете, то он отображается как обычный график.__isStock
атрибут установлен на ложное значение, напримерfalse
, т.е. используемая диаграммаHighcharts
Если__isStock
атрибут установлен на истинное значение, напримерtrue
, т.е. используемая диаграммаHighstocks
График (по умолчанию)__isStock
Это правда, например.true
Вы можете запроситьБиблиотека графиков HighStocks- Да.
варианты
неправда
объект, массив объектов
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});
}
}
Конфигурация чертежа с несколькими диаграммами:
extension.layout
атрибут
Если атрибут установлен с значением extension.height
атрибут
Атрибут используется для настройки высоты диаграммы, либо в виде числового значения, либо в виде extension.col
атрибут
Атрибут используется для установки ширины диаграммы, ширина страницы делится на 12 ячеек, набор 8, то есть диаграмма занимает 8 ячеек ширины.// 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);
}
}
Пример простого рисунка:
// 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);
}
}
Пример рисунка тригонометрической кривой:
/*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;
}
}
Сложные примеры использования гибридных диаграмм:
// 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);
Типовые схемыpie
Например, код в приведенном выше примере обновляет график, используяc.update(chartCfg)
после обновления данных следующим образом:
ВChart()
функция возвращает объект диаграмма, который имеет 4 метода:add()
, reset()
, update()
, del()
.
update()
Метод:
Вupdate()
Параметр этого метода - объект конфигурации диаграммы (JSON).del()
Метод:
Вdel()
Метод может удалить серию данных указанного индекса на основе параметра прошедшей серии.add()
Метод:
Вadd()
Метод может записывать данные на графике, с следующими параметрами в порядке:series
: используется для установки индекса серии данных, который является целым числом.data
: используется для настройки конкретных данных для записи, это массив.index
(необязательно): используется для настройки индекса данных, это целое число. Укажите конкретное положение индекса измененных данных, и он поддерживает отрицательные числа, настройка-1
относится к последним данным набора данных.
Например, при рисовании линии изменять данные в последней точке линии:chart.add(0, [1574993606000, 13.5], -1)
, т.е. изменить данные на предпоследней первой точке диаграммыseries[0].data
- Да.
Вindex
параметр не установлен, что означает, что данные добавляются в последнюю точку текущей серии данных.reset()
Метод:
Вreset()
Метод используется для опустошения данных диаграммы.reset()
Метод может принимать параметрremain
чтобы указать количество записей, которые нужно сохранить.remain
пропускается для очистки всех данных.{@fun/Log/KLineChart KLineChart} Я не знаю.
Функция используется для пользовательского рисования в время выполнения стратегии с использованием метода рисования, аналогичногоPine
language.
Объект диаграммы.KLineChart()
функция возвращает объект диаграмма с несколькими методами, среди которых вам нужно обратить внимание наbegin()
иclose()
. Операция чертежа должна начинаться сbegin()
вызов функции и конец сclose()
вызов функции при пересечении данных KLine для выполнения операции чертежа.
объект
KLineChart ((возможности)
Вoptions
Параметр - это конфигурация диаграммы.
варианты
неправда
объект, массив объектов
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
Если объект управления графиком необходим для рисования в зоне рисования стратегии, используйтеKLineChart()
Параметр к объектуKLineChart()
функция - это структура конфигурации диаграммы, используемая в коде ссылки проста:{overlay: true}
. Эта структура конфигурации диаграмма устанавливает только содержание рисунка, которое должно выводиться на основной диаграмме.overlay
устанавливается на значение false, напримерfalse
, содержание на графике выводится на вторичном графике. Если вам нужно указать чертежную функцию, чтобы нарисовать на главном графике, вы также можете указать параметрoverlay
как истинное значение в конкретном вызове функции, например: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
Функции интерфейса чертежаPine
язык, поддерживаемый в операции черчения:barcolor
, который устанавливает цвет линии К.
barcolor ((цвет, смещение, редактируемые, show_last, заголовок, отображение) параметры отображения необязательны:
ни один , все
c.bgcolor('rgba(0, 255, 0, 0.5)')
c.bgcolor('rgba(0, 255, 0, 0.5)')
// Not supported for now
bgcolor
, заполняет фон линии K указанным цветом.
bgcolor ((цвет, смещение, редактируемые, show_last, заголовок, отображение, наложение) параметры отображения необязательны:
ни один , все
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
, изображает ряд данных на графике.
plot ((серия, заголовок, цвет, ширина строки, стиль, цена отслеживания, histbase, смещение, присоединение, редактируемое, показать_последний, отображение) параметры стиля необязательны:
stepline_diamond , stepline , cross , areabr , area , circles , columns , histogram , linebr , line параметры отображения необязательны: ни один , все
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
, заполнить фон между двумя участками илиhline
с предоставленными цветами.
заполнить ((линия1, линия2, цвет, заголовок, редактируемый, заполнить пробелы, отобразить) параметры отображения необязательны:
ни один , все
С тех порJavaScript
язык не может указать входящие параметры на основе названий функций формальных параметров, чтобы решить эту проблему, вы можете использовать{key: value}
структура для указания параметров, которые должны быть переданы определенному формальному названию параметра.
Например, в коде ссылки используется{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)'}
Указываетcolor
параметрfill
Функция.
Если вам нужно указать несколько параметров с последовательными названиями форм параметров, вы можете использовать{key1: value1, key2: value2, key3: value3}
- Да.
Например, в этом примере дополнительныйtitle
параметр указан:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)', title: 'fill'}
- Да.
Для цветного значения, вы можете установить его с'rgba(255, 0, 0, 0, 0.2)'
или с'#FF0000'
.
c.hline(bar.High)
c.hline(bar.High)
// Not supported for now
hline
, горизонтальная линия представлена на заданном фиксированном ценовом уровне.
hline ((цена, название, цвет, стиль строки, ширина строки, редактируемый, отображаемый) параметры стиля строки необязательны:
полосатый , точечный , твердый параметры отображения необязательны: ни один , все
c.plotarrow(bar.Close - bar.Open)
c.plotarrow(bar.Close - bar.Open)
// Not supported for now
plotarrow
, изображайте стрелки вверх и вниз на диаграмме.
Plotarrow ((серия, заголовок, цветовая разборка, цветовой снижение, смещение, мини-высота, максимальная высота, редактируемые, show_last, отображение) параметры отображения необязательны:
ни один , все
c.plotshape(bar.Low, {style: 'diamond'})
c.plotshape(bar.Low, style = 'diamond')
// Not supported for now
plotshape
, нарисуйте на графике визуальные формы.
Plotshape (серия, заголовок, стиль, местоположение, цвет, смещение, текст, textcolor, редактируемый, размер, show_last, отображение) параметры стиля необязательны:
diamond size.autoЭто размер. параметры отображения необязательны:, square , label_down , label_up , arrow_down , arrow_up , circle , flag , triangle_down , triangle_up , cross , xcross параметры расположения необязательны: верхняя полоса , нижняя полоса , верхняя , нижняя , абсолютная параметры размера необязательны: 10px , 14px , 20px , 40px , 80px , сравнивая size.tiny, size.small, size.normal, size.large, size.huge на языке Пайн. ни один , все
c.plotchar(bar.Close, {char: 'X'})
c.plotchar(bar.Close, char = 'X')
// Not supported for now
plotchar
, нарисуйте визуальные формы на графике с использованием любого определенного символа Unicode.
plotchar ((серия, заголовок, char, местоположение, цвет, смещение, текст, textcolor, редактируемый, размер, show_last, отображение) параметры расположения необязательны:
верхняя полоса size.autoЭто размер. параметры отображения необязательны:, нижняя полоса , верхняя , нижняя , абсолютная параметры размера необязательны: 10px , 14px , 20px , 40px , 80px , сравнивая size.tiny, size.small, size.normal, size.large, size.huge на языке Пайн. ни один , все
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
, изобразить K-линейный график на графике.
plotcandle ((открыть, высоко, низко, близко, название, цвет, wickcolor, редактируемый, show_last, bordercolor, display) параметры отображения необязательны:
ни один , все
c.signal("long", bar.High, 1.5)
c.signal("long", bar.High, 1.5)
// Not supported for now
signal
, функция, недоступная на языке Pine, используется для чертежей сигналов покупки и продажи здесь.
сигнал ((направление, цена, qty, id) Параметр
long передается для указания направления транзакции, вы можете выбрать long , closelong , short , closeshort . bar.High
это положение маркерного сигнала по оси Y. Переданный параметр 1.5 указывает количество транзакций сигнала. Четвертый параметр может быть передан для замены выведенного текстового содержания по умолчанию, а текст выведенного сигнала - направление транзакции, напримерcloselong .
c.reset()
c.reset()
// Not supported for now
reset
, функция, недоступная на языке Pine, используется для опустошения данных диаграммы.
Перезагрузить (остаться) В
reset()
метод может принимать один параметр,remain
, чтобы указать количество данных, которые необходимо хранить.remain
означает очистку всех данных.
Стратегия пользовательский рисунок может использовать только один из способовKLineChart()
функции илиChart()
Для некоторых цветовых и стилевых настроек, используемых вKLineChart()
Функция вызов, пожалуйста, обратитесь кИспользуйте функцию KLineChart, чтобы упростить проектирование чертежей стратегии.
{@fun/Log/Chart Chart} (Смеется)
Очистите бревно.
LogReset ((остаться)
Вremain
Параметр используется для установки количества последних записей журнала.
оставаться
ложное
Номер
function main() {
// Keep the last 10 logs and clear the rest
LogReset(10)
}
def main():
LogReset(10)
void main() {
LogReset(10);
}
Журнал запуска для каждого начала стратегии в режиме реального времени считается одним, поэтому, если параметры не передаются и нет вывода журнала в начале стратегии, никакие журналы не будут отображаться вообще, ожидая возвращения журнала докера (не исключение).
{@fun/Log Log}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log Log}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogVacuum}, {@fun/Log/LogVacuum LogVacuum}, {@fun/Log/LogVacuum}, {@fun/Log/LogVacuum LogVacuum}, {@fun/LogVacuum}, {@fun/Log/LogVacuum}, {@fun/LogVacuum}, {@fun/LogVacuum},
Используется для восстановления места хранения, занятогоSQLiteпри удалении данных после вызоваLogReset()
Функция очистки журнала.
Логавакуум ((()
function main() {
LogReset()
LogVacuum()
}
def main():
LogReset()
LogVacuum()
void main() {
LogReset()
LogVacuum()
}
Причина в том, чтоSQLite
не восстанавливает занимаемое пространство при удалении данных, и он должен выполнятьVACUUM
Операция перемещения файлов происходит при вызове этой функции, и задержка большая, поэтому рекомендуется вызвать в подходящий временной интервал.
{@fun/Log/LogReset LogReset} - Я не знаю.
Он используется для вывода информации о отлаживании в столбце 123456
,console.log
функция выводит информацию о отлаживании на живой странице торговли, и в то же время, создать файл журнала с расширением.log
и написать информацию отладки в/logs/storage/123456/
в каталоге докера, к которому принадлежит прямая торговля, с префиксом файлового имениstdout_
.
консоль.log ((...msgs)
Параметрmsg
является содержанием вывода, и параметрmsg
может пройти более одного.
СМС
ложное
string, number, bool, object, array, null и другие типы, поддерживаемые системой.
function main() {
console.log("test console.log")
}
# Not supported
// Not supported
JavaScript
язык поддерживает эту функцию.[object Object]
, так что постарайтесь вывести как можно больше читаемой информации.{@fun/Log/console.error консоль.error}
Используется для вывода ошибок в поле 123456
,console.error
функция создает файл журнала с расширением.log
в/logs/storage/123456/
каталог докера, где живая торговля принадлежит, и пишет выход ошибки с префиксомstderr_
.
консоль.ошибка...
Параметрmsg
является содержанием вывода, и параметрmsg
может пройти более одного.
СМС
ложное
string, number, bool, object, array, null и другие типы, поддерживаемые системой.
function main() {
console.error("test console.error")
}
# Not supported
// Not supported
JavaScript
язык поддерживает эту функцию.[object Object]
, так что постарайтесь вывести как можно больше читаемой информации.{@fun/Log/console.log консоль.log}
Глобальный Рынок