Этот вид библиотеки часто используется для создания диаграмм и графиков при написании и разработке стратегий.
Изучая дизайн функций экспорта в
$. СюжетMultRecords
Используется для рисования K-линейных диаграмм, разработанных параметров: cfgName, seriesName, records, extension。
cfgName: как единая диаграмма, название конфигурированного объекта;
серияName: название серии данных, для которой в данный момент необходимо провести K-линии;
записи: передаваемые данные K-линии;
расширение: информация о конфигурации размера диаграммы, например: pass{layout: 'single', col: 6, height: '600px'}
, то есть запросить график с конфигурированным именем объекта cfgName, чтобы отображать только ширину: 6, высоту: 600px.
$. ПлощадкаМолтиЛиния Используется для рисования линий, параметры проектирования: cfgName, seriesName, dot, ts, расширение cfgName: как единая диаграмма, название конфигурированного объекта; серияName: название серии данных, для которой необходимо начертить линии в данный момент; точка: ординарное значение точки на чертежах; ts: временная отметка, а именно значение на оси времени X; расширение: информация о конфигурации размера диаграммы.
$. ПлощадкаМолтЛайн
Используется для рисования горизонтальных линий; разработанные параметры: cfgНазвание, значение, этикетка, цвет, стиль
cfgName: настраиваемый объект в диаграмме;
значение: ординарное значение горизонтальной линии;
этикетка: текст, отображаемый на горизонтальной линии;
цвет: цвет линии;
стиль: стиль строки, например:Solid ShortDash ShortDot ShortDashDot ShortDashDotDot Dot Dash LongDash DashDot LongDashDot LongDashDotDot
.
$. Сюжет Многозаголовок Используется для изменения заголовка и подзаголовка диаграммы; разработанные параметры: cfgName, title, chartTitle cfgName: имя конфигурированного объекта; заголовок: подзаголовок; ГрафикTitle: название графика.
$.ПлощадкаMultFlag Используется для рисования флага; параметры проектирования: cfgName, seriesName, ts, текст, название, форма, цвет, onSeriesName cfgName: настраиваемый объект в диаграмме; серияName: название серии данных; ts: дата и время; текст: текст на флаге; название: название флага; форма: форма флага; цвет: цвет флага; onSeriesName: это зависит от того, на какой серии данных отображается; значение является идентификатором серии данных.
$. GetArrCfg Используется для возвращения конфигурированного массива объектов диаграммы.
Для легкого понимания я написал замечания непосредственно на тестовых функциях, объясняя, что делает каждый вызов функции.
// test
function main() {
LogReset(10)
var i = 0
var prePrintTs = 0
while (true) {
var r = exchange.GetRecords() // Get K-line data
var t = exchange.GetTicker() // Get the real-time tick data
$.PlotMultRecords("chart1", "kline1", r, {layout: 'single', col: 6, height: '600px'}) // Create a K-line chart named chart1, and display it solely; the width is 6, and the height is 600px; the K-line data series name is kline1, and use r obtained above as the data source to draw the chart
$.PlotMultRecords("chart2", "kline2", r, {layout: 'single', col: 6, height: '600px'}) // Craete the second K-line chart, named chart2
$.PlotMultLine("chart2", "line1", t.Last, r[r.length - 1].Time) // Add a line to the K-line chart, namely chart2, the name of the data series is line1, and use the Last of the real-time tick data as the Y value of the dot on the line. The timestamp of the last BAR of the K-line data is used as the X value
$.PlotMultLine("chart3", "line2", t.Last) // Create a chart named chart3 that only draws lines, with data series name line2; use the Last of real-time tick data to draw a dot at the current time (X value) (t.Last is Y value); note that the chart is not displayed solely
$.PlotMultLine("chart6", "line6", t.Time) // Create a chart chart6 that only draws lines; note that the chart is not displayed solely, it will be displayed with chart3 on pagination
$.PlotMultLine("chart4", "line3", t.Sell, new Date().getTime(), {layout: 'single', col: 4, height: '300px'}) // Create a chart named chart4 that only draws lines, solely displayed, width 4, height 300px
$.PlotMultLine("chart5", "line4", t.Volume, new Date().getTime(), {layout: 'single', col: 8, height: '300px'}) // Create a chart named chart5 that only draws lines, solely displayed, width 8, height 300px
$.PlotMultHLine("chart1", r[r.length - 1].Close, "HLine1", "blue", "ShortDot") // Add horizontal lines in chart1
$.PlotMultHLine("chart4", t.Sell, "HLine2", "green") // Add horizontal lines in chart4
$.PlotMultTitle("chart3", "change : chart3->test1", "test1") // Modify the title of chart3
var ts = new Date().getTime()
if (ts - prePrintTs > 1000 * 20) {
prePrintTs = ts
// when triggered, draw a flag on chart3
$.PlotMultFlag("chart3", "flag1", new Date().getTime(), "flag test", "flag1")
}
if (i == 10) {
Log("i == 10")
// when triggered, draw a flag on chart4, and chart1
$.PlotMultFlag("chart4", "flag2", new Date().getTime(), "flag test", "flag2")
$.PlotMultFlag("chart1", "flag3", new Date().getTime(), "flag test", "flag3", "squarepin", "green", "kline1")
} else if (i == 20) {
Log("i == 20")
// when triggered, add a line on chart1, but only draw a dot of the line; X coordinate is timestamp, and Y coordinate is the value of t.Last
$.PlotMultLine("chart1", "line5", t.Last, r[r.length - 1].Time)
} else if (i == 30) {
Log("i == 30")
// when triggered, draw a flag on chart2
$.PlotMultFlag("chart2", "flag4", new Date().getTime(), "flag test", "flag4", "circlepin", "black", "kline2")
}
Sleep(1000 * 5)
i++
}
}
Вы можете видеть, что только с одной строкой вызова функции, вы можете легко нарисовать диаграмму, и вы можете отобразить несколько видов диаграмм одновременно.
Параметры:
Внедрение исходного кода стратегии:
var registerInfo = {}
var chart = null
var arrCfg = []
function updateSeriesIdx() {
var index = 0
var map = {}
_.each(arrCfg, function(cfg) {
_.each(cfg.series, function(series) {
var key = cfg.name + "|" + series.name
map[key] = index
index++
})
})
for (var cfgName in registerInfo) {
for (var i in registerInfo[cfgName].seriesIdxs) {
var seriesName = registerInfo[cfgName].seriesIdxs[i].seriesName
var key = cfgName + "|" + seriesName
if (map[key]) {
registerInfo[cfgName].seriesIdxs[i].index = map[key]
}
// Reset preBarTime of K-line data
if (registerInfo[cfgName].seriesIdxs[i].type == "candlestick") {
registerInfo[cfgName].seriesIdxs[i].preBarTime = 0
} else if (registerInfo[cfgName].seriesIdxs[i].type == "line") {
registerInfo[cfgName].seriesIdxs[i].preDotTime = 0
} else if (registerInfo[cfgName].seriesIdxs[i].type == "flag") {
registerInfo[cfgName].seriesIdxs[i].preFlagTime = 0
}
}
}
if (!chart) {
chart = Chart(arrCfg)
}
chart.update(arrCfg)
chart.reset()
_G("registerInfo", registerInfo)
_G("arrCfg", arrCfg)
for (var cfgName in registerInfo) {
for (var i in registerInfo[cfgName].seriesIdxs) {
var buffer = registerInfo[cfgName].seriesIdxs[i].buffer
var index = registerInfo[cfgName].seriesIdxs[i].index
if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "line" && registerInfo[cfgName].seriesIdxs[i].preDotTime == 0) {
_.each(buffer, function(obj) {
chart.add(index, [obj.ts, obj.dot])
registerInfo[cfgName].seriesIdxs[i].preDotTime = obj.ts
})
} else if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "flag" && registerInfo[cfgName].seriesIdxs[i].preFlagTime == 0) {
_.each(buffer, function(obj) {
chart.add(index, obj.data)
registerInfo[cfgName].seriesIdxs[i].preFlagTime = obj.ts
})
}
}
}
}
function checkBufferLen(buffer, maxLen) {
while (buffer.length > maxLen) {
buffer.shift()
}
}
$.PlotMultRecords = function(cfgName, seriesName, records, extension) {
if (typeof(cfgName) == "undefined") {
throw "need cfgName!"
}
var index = -1
var eleIndex = -1
do {
var cfgInfo = registerInfo[cfgName]
if (typeof(cfgInfo) == "undefined") {
var cfg = {
name : cfgName,
__isStock: true,
title : {
text: cfgName
},
tooltip: {
xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
},
legend: {
enabled: true,
},
plotOptions: {
candlestick: {
color: '#d75442',
upColor: '#6ba583'
}
},
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: 2,
inputEnabled: true
},
series: [{
type: 'candlestick',
name: seriesName,
id: seriesName,
data: []
}],
}
if (typeof(extension) != "undefined") {
cfg.extension = extension
}
registerInfo[cfgName] = {
"cfgIdx" : arrCfg.length,
"seriesIdxs" : [{seriesName: seriesName, index: arrCfg.length, type: "candlestick", preBarTime: 0}],
}
arrCfg.push(cfg)
updateSeriesIdx()
}
if (!chart) {
chart = Chart(arrCfg)
} else {
chart.update(arrCfg)
}
_.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
if (ele.seriesName == seriesName && ele.type == "candlestick") {
index = ele.index
eleIndex = i
}
})
if (index == -1) {
arrCfg[registerInfo[cfgName].cfgIdx].series.push({
type: 'candlestick',
name: seriesName,
id: seriesName,
data: []
})
registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "candlestick", preBarTime: 0})
updateSeriesIdx()
}
} while (index == -1)
for (var i = 0 ; i < records.length ; i++) {
if (records[i].Time == registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime) {
chart.add(index, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close], -1)
} else if (records[i].Time > registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime) {
registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime = records[i].Time
chart.add(index, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close])
}
}
return chart
}
$.PlotMultLine = function(cfgName, seriesName, dot, ts, extension) {
if (typeof(cfgName) == "undefined") {
throw "need cfgName!"
}
var index = -1
var eleIndex = -1
do {
var cfgInfo = registerInfo[cfgName]
if (typeof(cfgInfo) == "undefined") {
var cfg = {
name : cfgName,
__isStock: true,
title : {
text: cfgName
},
xAxis: {
type: 'datetime'
},
series: [{
type: 'line',
name: seriesName,
id: seriesName,
data: [],
}]
}
if (typeof(extension) != "undefined") {
cfg.extension = extension
}
registerInfo[cfgName] = {
"cfgIdx" : arrCfg.length,
"seriesIdxs" : [{seriesName: seriesName, index: arrCfg.length, type: "line", buffer: [], preDotTime: 0}],
}
arrCfg.push(cfg)
updateSeriesIdx()
}
if (!chart) {
chart = Chart(arrCfg)
} else {
chart.update(arrCfg)
}
_.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
if (ele.seriesName == seriesName && ele.type == "line") {
index = ele.index
eleIndex = i
}
})
if (index == -1) {
arrCfg[registerInfo[cfgName].cfgIdx].series.push({
type: 'line',
name: seriesName,
id: seriesName,
data: [],
})
registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "line", buffer: [], preDotTime: 0})
updateSeriesIdx()
}
} while (index == -1)
if (typeof(ts) == "undefined") {
ts = new Date().getTime()
}
var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer
if (registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime != ts) {
registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime = ts
chart.add(index, [ts, dot])
buffer.push({ts: ts, dot: dot})
checkBufferLen(buffer, maxBufferLen)
} else {
chart.add(index, [ts, dot], -1)
buffer[buffer.length - 1].dot = dot
}
return chart
}
$.PlotMultHLine = function(cfgName, value, label, color, style) {
if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
throw "need cfgName!"
}
var cfg = arrCfg[registerInfo[cfgName].cfgIdx]
if (typeof(cfg.yAxis) == "undefined") {
cfg.yAxis = {
plotLines: []
}
} else if (typeof(cfg.yAxis.plotLines) == "undefined") {
cfg.yAxis.plotLines = []
}
var obj = {
value: value,
color: color || 'red',
width: 2,
dashStyle: style || 'Solid',
label: {
text: label || '',
align: 'center'
},
}
var found = false
for (var i = 0; i < cfg.yAxis.plotLines.length; i++) {
if (cfg.yAxis.plotLines[i].label.text == label) {
cfg.yAxis.plotLines[i] = obj
found = true
}
}
if (!found) {
cfg.yAxis.plotLines.push(obj)
}
if (!chart) {
chart = Chart(arrCfg)
} else {
chart.update(arrCfg)
}
return chart
}
$.PlotMultTitle = function(cfgName, title, chartTitle) {
if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
throw "need cfgName!"
}
var cfg = arrCfg[registerInfo[cfgName].cfgIdx]
cfg.subtitle = {
text: title
}
if (typeof(chartTitle) !== 'undefined') {
cfg.title = {
text: chartTitle
}
}
if (chart) {
chart.update(arrCfg)
}
return chart
}
$.PlotMultFlag = function(cfgName, seriesName, ts, text, title, shape, color, onSeriesName) {
if (typeof(cfgName) == "undefined" || typeof(registerInfo[cfgName]) == "undefined") {
throw "need cfgName!"
}
var index = -1
var eleIndex = -1
do {
if (!chart) {
chart = Chart(arrCfg)
} else {
chart.update(arrCfg)
}
_.each(registerInfo[cfgName].seriesIdxs, function(ele, i) {
if (ele.seriesName == seriesName && ele.type == "flag") {
index = ele.index
eleIndex = i
}
})
if (index == -1) {
arrCfg[registerInfo[cfgName].cfgIdx].series.push({
type: 'flags',
name: seriesName,
onSeries: onSeriesName || arrCfg[registerInfo[cfgName].cfgIdx].series[0].id,
data: []
})
registerInfo[cfgName].seriesIdxs.push({seriesName: seriesName, index: arrCfg.length, type: "flag", buffer: [], preFlagTime: 0})
updateSeriesIdx()
}
} while(index == -1)
if (typeof(ts) == "undefined") {
ts = new Date().getTime()
}
var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer
var obj = {x: ts, color: color, shape: shape, title: title, text: text}
if (registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime != ts) {
registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime = ts
chart.add(index, obj)
buffer.push({ts: ts, data: obj})
checkBufferLen(buffer, maxBufferLen)
} else {
chart.add(index, obj, -1)
buffer[buffer.length - 1].data = obj
}
return chart
}
$.GetArrCfg = function() {
return arrCfg
}
function init() {
if (isChartReset) {
Log("Reset the chart", "#FF0000")
chart = Chart(arrCfg)
chart.reset()
Log("Empty the persistent data, key:", "registerInfo、arrCfg #FF0000")
_G("registerInfo", null)
_G("arrCfg", null)
} else {
var multChartRegisterInfo = _G("registerInfo")
var multChartArrCfg = _G("arrCfg")
if (multChartRegisterInfo && multChartArrCfg) {
registerInfo = multChartRegisterInfo
arrCfg = multChartArrCfg
Log("Recover registerInfo、arrCfg #FF0000")
} else {
Log("No data can be recovered #FF0000")
}
}
}
function onexit() {
_G("registerInfo", registerInfo)
_G("arrCfg", arrCfg)
Log("Save data, key : registerInfo, arrCfg #FF0000")
}
// test
function main() {
LogReset(10)
var i = 0
var prePrintTs = 0
while (true) {
var r = exchange.GetRecords()
var t = exchange.GetTicker()
$.PlotMultRecords("chart1", "kline1", r, {layout: 'single', col: 6, height: '600px'})
$.PlotMultRecords("chart2", "kline2", r, {layout: 'single', col: 6, height: '600px'})
$.PlotMultLine("chart2", "line1", t.Last, r[r.length - 1].Time)
$.PlotMultLine("chart3", "line2", t.Last)
$.PlotMultLine("chart6", "line6", t.Time)
$.PlotMultLine("chart4", "line3", t.Sell, new Date().getTime(), {layout: 'single', col: 4, height: '300px'})
$.PlotMultLine("chart5", "line4", t.Volume, new Date().getTime(), {layout: 'single', col: 8, height: '300px'})
$.PlotMultHLine("chart1", r[r.length - 1].Close, "HLine1", "blue", "ShortDot")
$.PlotMultHLine("chart4", t.Sell, "HLine2", "green")
$.PlotMultTitle("chart3", "change : chart3->test1", "test1")
var ts = new Date().getTime()
if (ts - prePrintTs > 1000 * 20) {
prePrintTs = ts
$.PlotMultFlag("chart3", "flag1", new Date().getTime(), "flag test", "flag1")
}
if (i == 10) {
Log("i == 10")
$.PlotMultFlag("chart4", "flag2", new Date().getTime(), "flag test", "flag2")
$.PlotMultFlag("chart1", "flag3", new Date().getTime(), "flag test", "flag3", "squarepin", "green", "kline1")
} else if (i == 20) {
Log("i == 20")
$.PlotMultLine("chart1", "line5", t.Last, r[r.length - 1].Time)
} else if (i == 30) {
Log("i == 30")
$.PlotMultFlag("chart2", "flag4", new Date().getTime(), "flag test", "flag4", "circlepin", "black", "kline2")
}
Sleep(1000 * 5)
i++
}
}
Адрес стратегии:https://www.fmz.com/strategy/353264
Если вы заинтересованы, вы можете увеличить поддерживаемые типы диаграмм (например, диаграмма глубины рынка, штрих-графика и пирожной диаграммы и т. Д.) и продолжать обновление.