Ce type de bibliothèque est souvent utilisé pour créer des graphiques et des graphiques lors de l'écriture et la conception de stratégies.
En apprenant de la conception de la fonction d'exportation de
$. PlotMultRecords
Utilisé pour dessiner des graphiques de lignes K, paramètres conçus: cfgNom, sérieNom, enregistrements, extension。
cfgName: en tant que graphique unique, le nom de l'objet configuré;
sérieName: le nom de la série de données devant être dessinée en ce moment;
enregistrements: les données de ligne K transmises;
extension: les informations relatives à la configuration des dimensions du graphique, par exemple: passer{layout: 'single', col: 6, height: '600px'}
, c'est-à-dire demander au graphique avec le nom d'objet configuré de cfgName d'afficher uniquement la largeur: 6, la hauteur: 600px.
$. PlotMultLine Utilisé pour tracer des lignes, paramètres conçus: cfgNom, sérieNom, point, ts, extension cfgName: en tant que graphique unique, le nom de l'objet configuré; sérieName: le nom de la série de données qui doit être tracée à l'heure actuelle; point: la valeur ordonnée du point sur les lignes à tracer; ts: horodatage, c'est-à-dire la valeur sur l'axe X; extension: les informations relatives à la configuration des dimensions du graphique.
$. PlotMultHLine
Utilisé pour tracer des lignes horizontales; paramètres conçus: cfgNom, valeur, étiquette, couleur, style
cfgName: l'objet configuré dans le graphique;
valeur: la valeur ordonnée de la ligne horizontale;
étiquette: le texte affiché sur la ligne horizontale;
couleur: couleur des lignes;
style: style de ligne, par exemple:Solid ShortDash ShortDot ShortDashDot ShortDashDotDot Dot Dash LongDash DashDot LongDashDot LongDashDotDot
.
$. PlotMultTitle Utilisé pour modifier le titre et le sous-titre du graphique; paramètres conçus: cfgNom, titre, graphiqueTitre cfgName: le nom de l'objet configuré; titre: sous-titre; Tableau Titre: le titre du tableau.
$. PlotMultFlag Utilisé pour dessiner le drapeau; paramètres conçus: cfgNom, sérieNom, ts, texte, titre, forme, couleur, onSeriesNom cfgName: l'objet configuré dans le graphique; sérieNom: le nom de la série de données; ts: étiquette de l'heure; texte: le texte du drapeau; titre: le titre du pavillon; forme: la forme du drapeau; couleur: la couleur du drapeau; onSeriesName: il est basé sur la série de données à afficher; la valeur est l'id de la série de données.
Je suis désolée. Utilisé pour renvoyer le tableau d'objets configuré du graphique.
Pour faciliter la compréhension, j'ai écrit des remarques directement sur les fonctions de test, expliquant ce que fait chaque appel de fonction.
// 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++
}
}
Vous pouvez voir qu'avec une seule ligne d'appel de fonction, vous pouvez facilement dessiner un graphique, et vous pouvez afficher plusieurs types de graphiques en même temps.
Paramètres définis:
Mise en œuvre du code source de la stratégie:
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++
}
}
Adresse de la stratégie:https://www.fmz.com/strategy/353264
Si vous êtes intéressé, vous pouvez augmenter les types de graphiques pris en charge (tels que le graphique de profondeur de marché, le graphique à barres et le graphique à tournesols, etc.) et continuer à mettre à jour.