Lors de la conception d'une stratégie, il est souvent nécessaire de concevoir un diagramme de stratégie à afficher, lors de l'écriture de stratégies en langage JavaScript, langage Python, les utilisateurs qui ne sont pas familiers avec la programmation ou la bibliothèque de graphiques utilisée dans la plate-forme FMZ ont souvent du mal avec la conception de code pour dessiner sur des graphiques personnalisés.
Cette façon simple et puissante de dessiner peut être vue dans le langage Pine, qui est connu pour ses riches fonctions de dessin. Si l'interface de dessin du langage Pine peut être connectée aux stratégies des langages JavaScript et Python, cela facilitera grandement la fonction de dessin de la stratégie de conception du développeur.KLineChart
Vous pouvez consulter la documentation de l'API à:https://www.fmz.com/api#klinechart
Commençons par écrire un exemple simple en utilisant le langage JavaScript pour la transition.
/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 30m
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
function main() {
var c = KLineChart()
while (true) {
var bars = _C(exchange.GetRecords)
for (var i = 0 ; i < bars.length ; i++) {
var bar = bars[i]
c.begin(bar)
c.plot(bar.Volume, "Close")
c.close()
}
Sleep(1000)
}
}
Cet exemple est très simple, il suffit de dessiner un graphique de ligne K dans la zone de dessin personnalisée de la stratégie, et de dessiner une courbe de volume correspondant à chaque BAR de ligne K dans la position de sous-graphique du graphique.
Dans le code, nous utilisonsvar c = KLineChart()
Pour créer un objet de diagramme d'abord, et ensuite utiliser sa méthode pour dessiner un diagramme. Ensuite, dans la boucle, nous obtenons les données de ligne K (structure d'array), et traversons le tableau de ligne K. Il peut être traversé en utilisant une simple boucle for comme dans l'exemple, ou il peut être traversé d'autres façons.
L'opération de dessin commence par lec.begin(bar)
fonction et se terminent par lec.close()
La fonctionbegin
etclose
les fonctions sont toutes des méthodes de l'objet graphique c. Ensuite, utiliser la fonction de dessin la plus couramment utiliséeplot
pour tracer la courbe de volume sur chaque BAR.
Supposons que nous voulons concevoir un graphique avec l'indicateur de Bollinger attaché. et il vient aussi avec un graphique de volume de chaque BAR, qui peut être conçu comme ceci:
/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
function main() {
var c = KLineChart()
// main strategy loop
while(true) {
// polling interval
Sleep(500)
// get K-line data
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
continue
}
// calculate the Bollinger indicator
var boll = TA.BOLL(bars)
bars.forEach(function(bar, index) {
c.begin(bar)
// drawing operation
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // Draw on the main chart
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // Draw on the main chart
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // Draw on the main chart
c.plot(bar.Volume, "volume") // Draw on the sub-chart
c.close()
})
// Strategy trading logic
// ...
// ..
}
}
Comme nous pouvons le voir dans le code, nos informations de configuration de backtest sur la plateforme FMZ sont:
/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
Une telle configuration consiste à utiliser le test de backtesting de l'objet d'échange Binance.
On peut voir que nous utilisons la méthode de dessin de Pine
Les opérations d'obtention des données de ligne K et de calcul des indicateurs sont courantes et simples dans les exemples de stratégie du carré de stratégie de la plateforme et dans la documentation de l'API.
// obtain K-line data
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
// If the acquisition of the K line fails, that is, if !bar is true, execute continue, ignore the following code, and re-execute the loop
// If bars.length is less than or equal to 20, that is, the number of K-line BAR (bar) is less than 20, the indicator cannot be calculated, and continue is also executed
continue
}
// Calculate the Bollinger indicator
var boll = TA.BOLL(bars)
La fonction de calcul de l'indicateur Bollinger TA.BOLL, si les paramètres de l'indicateur Bollinger ne sont pas spécifiés, les paramètres par défautBOLL(20, 2)
L'indicateur de Bollinger a trois lignes, donc les données renvoyées par la fonction TA.BOLL sont un tableau bidimensionnel. boll[0], boll[1], et boll[2] sont les trois éléments du tableau boll, dont chacun représente une ligne et est un tableau.
Ensuite, nous verrons comment dessiner le volume des données de la ligne K, c'est-à-dire le volume, et les données calculées de l'indicateur de Bollinger sur le graphique.
Nous dessinons les données K-ligne Bar par Bar, donc nous devons traverser l'ensemble du tableau K-ligne, c'est à dire traverser le tableau des barres dans le code.forEach
la méthode est utilisée ici pour traverser, ou la boucle for peut être utilisée pour traverser.
bars.forEach(function(bar, index) {
c.begin(bar)
// Drawing operations
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // {overlay: true} Parameter control, drawn on the main chart
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // Draw on the main chart
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // Draw on the main chart
c.plot(bar.Volume, "volume") // Draw on the sub-chart
c.close()
})
Il convient de noter que chaque fois que vous démarrez une opération de dessin de graphique sur une barre, vous devez faire unc.begin(bar)
L'appel de la fonction en premier.begin
fonction est l'une de nos objets de diagramme c méthode. à la fin de l'opération de dessin,c.close()
Il faut appeler.begin
fonction et leclose
la fonction est la fonction de dessin que nous appelons similaire à la méthode de dessin de la langue Pine.barcolor
bgcolor
plot
fill
hline
plotarrow
plotshape
plotchar
plotcandle
signal
, vous pouvez dessiner des lignes, des flèches, marquer des informations, etc. Les paramètres de ces fonctions sont les mêmes que les paramètres de fonction correspondant au langage Pine, et les fonctions de dessin sont également les mêmes.
Ajoutez des flèches, des marqueurs et des lignes horizontales de signaux de négociation à l'exemple de graphique ci-dessus.
/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
function main() {
var c = KLineChart({overlay : true})
// Strategy main loop
while(true) {
// Polling interval
Sleep(500)
// Obtain K-line data
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
continue
}
// Calculate Bollinger indicator
var boll = TA.BOLL(bars)
bars.forEach(function(bar, index) {
c.begin(bar)
// Drawing operations
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // Draw on the main chart
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // Draw on the main chart
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // Draw on the main chart
c.plot(bar.Volume, "volume", {overlay: false}) // Draw on the sub-chart
c.hline(bar.Open, {overlay: true}) // Horizontal line
c.plotarrow(bar.Close - bar.Open, {overlay: true}) // Arrow
c.plotshape(bar.Close - bar.Open > 0, {style: 'square'}) // Draw square markers
c.plotchar(bar.Close - bar.Open < 0, {char: 'X'}) // Draw the character X
c.close()
})
// Strategy trading logic
// ...
// ..
}
}
Une structure peut être déclarée pour configurer le style du graphique. Par exemple, la variable chartCfg suivante représente les informations de configuration d'une ligne de grille.
var chartCfg = {
grid: {
show: true,
// Grid horizontal line
horizontal: {
show: true,
size: 2,
color: '#FF0000', // Color of horizontal grid line
// 'solid'|'dash'
style: 'dash', // Type of line
dashValue: [2, 2]
},
// Grid vertical line
vertical: {
show: true,
size: 2,
color: '#32CD32',
// 'solid'|'dash'
style: 'solid',
dashValue: [2, 2]
}
},
}
L'objet de configuration du graphique est la structure de données qui définit certaines propriétés et l'apparence du graphique. Par exemple, une configuration de style de ligne de grille est utilisée dans l'exemple. Il existe également de nombreuses options qui peuvent être configurées et modifiées, telles que l'axe X, les paramètres liés à l'axe Y, les paramètres de ligne du curseur, les paramètres de message d'alerte, les paramètres de style de l'indicateur technique, les paramètres de style BAR de la ligne K, etc.
Bien sûr, si vous n'êtes pas familier avec ceux-ci, vous ne pouvez pas passer dans l'objet de configuration graphique lors de l'appel de laKLineChart
la fonction pour créer un objet graphique. Ensuite, le graphique créé est le style par défaut. Utilisez la fonction APIKLineChart
fonction de la plateforme FMZ pour créer un objet de graphique:
var c = KLineChart(chartCfg)
Code d'essai pour le dessin des lignes de grille:
/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
function main() {
var chartCfg = {
grid: {
show: true,
// Grid horizontal line
horizontal: {
show: true,
size: 2,
color: '#FF0000',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
},
// Grid vertical line
vertical: {
show: true,
size: 2,
color: '#32CD32',
// 'solid'|'dash'
style: 'solid',
dashValue: [2, 2]
}
},
}
var c = KLineChart(chartCfg)
// Strategy main loop
while(true) {
// Polling interval
Sleep(500)
// Obtain K-line data
var bars = _C(exchange.GetRecords)
bars.forEach(function(bar, index) {
c.begin(bar)
c.close()
})
// Strategy trading logic
// ...
// ..
}
}
Il peut être utilisé pour faire référence aux paramètres de style de configuration de graphique.
{
// Gridlines
grid: {
show: true,
// Grid horizontal line
horizontal: {
show: true,
size: 1,
color: '#393939',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
},
// Grid vertical line
vertical: {
show: false,
size: 1,
color: '#393939',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
}
},
// Candlestick chart
candle: {
// The distance between the top and bottom of the candlestick chart, greater than 1 is the absolute value, greater than 0, and 1 is the proportion
margin: {
top: 0.2,
bottom: 0.1
},
// Type of Candlestick Charts 'candle_solid'|'candle_stroke'|'candle_up_stroke'|'candle_down_stroke'|'ohlc'|'area'
type: 'candle_solid',
// Candle pillar
bar: {
upColor: '#26A69A',
downColor: '#EF5350',
noChangeColor: '#888888'
},
// Area map
area: {
lineSize: 2,
lineColor: '#2196F3',
value: 'close',
backgroundColor: [{
offset: 0,
color: 'rgba(33, 150, 243, 0.01)'
}, {
offset: 1,
color: 'rgba(33, 150, 243, 0.2)'
}]
},
priceMark: {
show: true,
// Highest price marker
high: {
show: true,
color: '#D9D9D9',
textMargin: 5,
textSize: 10,
textFamily: 'Helvetica Neue',
textWeight: 'normal'
},
// Lowest price marker
low: {
show: true,
color: '#D9D9D9',
textMargin: 5,
textSize: 10,
textFamily: 'Helvetica Neue',
textWeight: 'normal',
},
// Latest price marker
last: {
show: true,
upColor: '#26A69A',
downColor: '#EF5350',
noChangeColor: '#888888',
line: {
show: true,
// 'solid'|'dash'
style: 'dash',
dashValue: [4, 4],
size: 1
},
text: {
show: true,
size: 12,
paddingLeft: 2,
paddingTop: 2,
paddingRight: 2,
paddingBottom: 2,
color: '#FFFFFF',
family: 'Helvetica Neue',
weight: 'normal',
borderRadius: 2
}
}
},
// Tips
tooltip: {
// 'always' | 'follow_cross' | 'none'
showRule: 'always',
// 'standard' | 'rect'
showType: 'standard',
labels: ['time', 'open', 'close', 'high', 'low', 'volume'],
values: null,
defaultValue: 'n/a',
rect: {
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 6,
offsetLeft: 8,
offsetTop: 8,
offsetRight: 8,
borderRadius: 4,
borderSize: 1,
borderColor: '#3f4254',
backgroundColor: 'rgba(17, 17, 17, .3)'
},
text: {
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
color: '#D9D9D9',
marginLeft: 8,
marginTop: 6,
marginRight: 8,
marginBottom: 0
}
}
},
// Technical indicators
technicalIndicator: {
margin: {
top: 0.2,
bottom: 0.1
},
bar: {
upColor: '#26A69A',
downColor: '#EF5350',
noChangeColor: '#888888'
},
line: {
size: 1,
colors: ['#FF9600', '#9D65C9', '#2196F3', '#E11D74', '#01C5C4']
},
circle: {
upColor: '#26A69A',
downColor: '#EF5350',
noChangeColor: '#888888'
},
// Latest value marker
lastValueMark: {
show: false,
text: {
show: false,
color: '#ffffff',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
paddingLeft: 3,
paddingTop: 2,
paddingRight: 3,
paddingBottom: 2,
borderRadius: 2
}
},
// Tips
tooltip: {
// 'always' | 'follow_cross' | 'none'
showRule: 'always',
// 'standard' | 'rect'
showType: 'standard',
showName: true,
showParams: true,
defaultValue: 'n/a',
text: {
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
color: '#D9D9D9',
marginTop: 6,
marginRight: 8,
marginBottom: 0,
marginLeft: 8
}
}
},
// x-axis
xAxis: {
show: true,
height: null,
// x-axis line
axisLine: {
show: true,
color: '#888888',
size: 1
},
// x-axis split text
tickText: {
show: true,
color: '#D9D9D9',
family: 'Helvetica Neue',
weight: 'normal',
size: 12,
paddingTop: 3,
paddingBottom: 6
},
// x-axis split line
tickLine: {
show: true,
size: 1,
length: 3,
color: '#888888'
}
},
// y-axis
yAxis: {
show: true,
width: null,
// 'left' | 'right'
position: 'right',
// 'normal' | 'percentage' | 'log'
type: 'normal',
inside: false,
reverse: false,
// y-axis line
axisLine: {
show: true,
color: '#888888',
size: 1
},
// y-axis split text
tickText: {
show: true,
color: '#D9D9D9',
family: 'Helvetica Neue',
weight: 'normal',
size: 12,
paddingLeft: 3,
paddingRight: 6
},
// y-axis split line
tickLine: {
show: true,
size: 1,
length: 3,
color: '#888888'
}
},
// Split line between charts
separator: {
size: 1,
color: '#888888',
fill: true,
activeBackgroundColor: 'rgba(230, 230, 230, .15)'
},
// Crosshair
crosshair: {
show: true,
// Horizontal line and text of crosshair
horizontal: {
show: true,
line: {
show: true,
// 'solid'|'dash'
style: 'dash',
dashValue: [4, 2],
size: 1,
color: '#888888'
},
text: {
show: true,
color: '#D9D9D9',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
paddingLeft: 2,
paddingRight: 2,
paddingTop: 2,
paddingBottom: 2,
borderSize: 1,
borderColor: '#505050',
borderRadius: 2,
backgroundColor: '#505050'
}
},
// Vertical line and text of crosshair
vertical: {
show: true,
line: {
show: true,
// 'solid'|'dash'
style: 'dash',
dashValue: [4, 2],
size: 1,
color: '#888888'
},
text: {
show: true,
color: '#D9D9D9',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
paddingLeft: 2,
paddingRight: 2,
paddingTop: 2,
paddingBottom: 2,
borderSize: 1,
borderColor: '#505050',
borderRadius: 2,
backgroundColor: '#505050'
}
}
},
// Graph
shape: {
point: {
backgroundColor: '#2196F3',
borderColor: '#2196F3',
borderSize: 1,
radius: 4,
activeBackgroundColor: '#2196F3',
activeBorderColor: '#2196F3',
activeBorderSize: 1,
activeRadius: 6
},
line: {
// 'solid'|'dash'
style: 'solid'
color: '#2196F3',
size: 1,
dashValue: [2, 2]
},
polygon: {
// 'stroke'|'fill'
style: 'stroke',
stroke: {
// 'solid'|'dash'
style: 'solid',
size: 1,
color: '#2196F3',
dashValue: [2, 2]
},
fill: {
color: 'rgba(33, 150, 243, 0.1)'
}
},
arc: {
// 'stroke'|'fill'
style: 'stroke',
stroke: {
// 'solid'|'dash'
style: 'solid',
size: 1,
color: '#2196F3',
dashValue: [2, 2]
},
fill: {
color: '#2196F3'
}
},
text: {
style: 'fill',
color: '#2196F3',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
offset: [0, 0]
}
},
annotation: {
// 'top' | 'bottom' | 'point'
position: 'top',
offset: [20, 0]
symbol: {
// 'diamond' | 'circle' | 'rect' | 'triangle' | 'custom' | 'none'
type: 'diamond',
size: 8,
color: '#2196F3',
activeSize: 10,
activeColor: '#FF9600'
}
},
tag: {
// 'top' | 'bottom' | 'point'
position: 'point',
offset: 0,
line: {
show: true,
style: LineStyle.DASH,
dashValue: [4, 2],
size: 1,
color: '#2196F3'
},
text: {
color: '#FFFFFF',
backgroundColor: '#2196F3',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
paddingLeft: 2,
paddingRight: 2,
paddingTop: 2,
paddingBottom: 2,
borderRadius: 2,
borderSize: 1,
borderColor: '#2196F3'
},
mark: {
offset: 0,
color: '#FFFFFF',
backgroundColor: '#2196F3',
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
paddingLeft: 2,
paddingRight: 2,
paddingTop: 2,
paddingBottom: 2,
borderRadius: 2,
borderSize: 1,
borderColor: '#2196F3'
}
}
}
Cela ne facilite-t-il pas la conception de la stratégie?