Khi thiết kế một chiến lược, nó thường cần thiết để thiết kế một biểu đồ chiến lược để hiển thị, khi viết các chiến lược trong ngôn ngữ JavaScript, ngôn ngữ Python, người dùng không quen thuộc với lập trình hoặc thư viện biểu đồ được sử dụng trong nền tảng FMZ thường gặp khó khăn với thiết kế mã để vẽ trên biểu đồ tùy chỉnh.
Cách vẽ đơn giản và mạnh mẽ này có thể được thấy trong ngôn ngữ Pine, được biết đến với các chức năng vẽ phong phú của nó. Nếu giao diện vẽ của ngôn ngữ Pine có thể được kết nối với các chiến lược của ngôn ngữ JavaScript và Python, nó sẽ tạo điều kiện cho chức năng vẽ của chiến lược thiết kế của nhà phát triển.KLineChart
Bạn có thể tham khảo tài liệu API tại:https://www.fmz.com/api#klinechart
Hãy bắt đầu bằng cách viết một ví dụ đơn giản sử dụng ngôn ngữ JavaScript để chuyển đổi.
/*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)
}
}
Ví dụ này rất đơn giản, chỉ cần vẽ một biểu đồ K-line trong khu vực vẽ tùy chỉnh của chiến lược, và vẽ một đường cong khối lượng tương ứng với mỗi K-line BAR trong vị trí biểu đồ phụ của biểu đồ.
Trong mã, chúng tôi sử dụngvar c = KLineChart()
để tạo một đối tượng biểu đồ trước, và sau đó sử dụng phương thức của nó để vẽ biểu đồ. Sau đó trong vòng lặp, chúng ta lấy dữ liệu đường K (cấu trúc mảng), và đi qua mảng đường K. Nó có thể được đi qua bằng cách sử dụng một vòng lặp đơn giản như trong ví dụ, hoặc nó có thể được đi qua theo những cách khác.
Hoạt động vẽ bắt đầu vớic.begin(bar)
chức năng và kết thúc vớic.close()
chức năng.begin
vàclose
các hàm là tất cả các phương thức của đối tượng biểu đồ c. Tiếp theo, sử dụng các chức năng vẽ thường được sử dụng nhấtplot
để vẽ đường cong khối lượng trên mỗi BAR.
Giả sử chúng ta muốn thiết kế một biểu đồ với chỉ số Bollinger đính kèm. và nó cũng đi kèm với một biểu đồ khối lượng của mỗi BAR, có thể được thiết kế như thế này:
/*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
// ...
// ..
}
}
Như chúng ta có thể thấy trong mã, thông tin cấu hình backtest của chúng tôi trên nền tảng FMZ là:
/*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"}]
*/
Một cấu hình như vậy là sử dụng Binance spot exchange object backtesting test. hiệu ứng backtesting được hiển thị như sau:
Bạn có thể thấy rằng chúng tôi sử dụng phương pháp vẽ của Pine
Các hoạt động thu thập dữ liệu đường K và tính toán các chỉ số là phổ biến và đơn giản trong các ví dụ chiến lược trong Quảng trường chiến lược nền tảng và trong tài liệu 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)
Chức năng tính toán chỉ số Bollinger TA.BOLL, nếu các tham số chỉ số Bollinger không được chỉ định, các tham số mặc địnhBOLL(20, 2)
Chỉ số Bollinger có ba dòng, vì vậy dữ liệu được trả về bởi hàm TA.BOLL là một mảng hai chiều. boll[0], boll[1], và boll[2] là ba phần tử của mảng boll, mỗi phần đại diện cho một đường và là một mảng.
Sau đó chúng ta sẽ xem làm thế nào để vẽ khối lượng của dữ liệu K-line, đó là, khối lượng, và các dữ liệu chỉ số Bollinger tính toán trên biểu đồ.
Chúng ta vẽ dữ liệu K-line Bar by Bar, vì vậy chúng ta cần phải đi qua toàn bộ K-line mảng, đó là, đi qua mảng thanh trong mã.forEach
phương pháp được sử dụng ở đây để đi qua, hoặc vòng lặp for có thể được sử dụng để đi qua.
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()
})
Cần lưu ý rằng bất cứ khi nào bạn bắt đầu một hoạt động vẽ biểu đồ trên một thanh, bạn phải thực hiện mộtc.begin(bar)
gọi chức năng đầu tiên.begin
function là một trong những phương pháp đối tượng biểu đồ c của chúng tôi.c.close()
cần phải được gọi.begin
chức năng vàclose
function là hàm vẽ mà chúng ta gọi tương tự như phương pháp vẽ của ngôn ngữ Pine.barcolor
bgcolor
plot
fill
hline
plotarrow
plotshape
plotchar
plotcandle
signal
, bạn có thể vẽ đường, mũi tên, đánh dấu thông tin, v.v. Các thông số của các hàm này là giống như các thông số hàm tương ứng với ngôn ngữ Pine, và các chức năng vẽ cũng giống nhau.
Thêm một số mũi tên tín hiệu giao dịch, dấu hiệu, đường ngang vào ví dụ biểu đồ Bollinger Bands ở trên.
/*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
// ...
// ..
}
}
Một cấu trúc có thể được tuyên bố để cấu hình phong cách biểu đồ. Ví dụ, biến chartCfg sau đây đại diện cho thông tin cấu hình của đường lưới.
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]
}
},
}
Đối tượng cấu hình biểu đồ là cấu trúc dữ liệu thiết lập một số thuộc tính và ngoại hình của biểu đồ. Ví dụ, cấu hình kiểu đường lưới được sử dụng trong ví dụ. Ngoài ra còn có nhiều tùy chọn có thể được cấu hình và sửa đổi, chẳng hạn như thiết lập trục X, thiết lập liên quan đến trục Y, cài đặt đường cursor, cài đặt thông báo cảnh báo, cài đặt kiểu chỉ số kỹ thuật, cài đặt kiểu K-line BAR, v.v.
Tất nhiên, nếu bạn không quen thuộc với những điều này, bạn không thể vượt qua trong các đối tượng cấu hình biểu đồ khi gọiKLineChart
sử dụng hàm API để tạo một đối tượng biểu đồ. sau đó biểu đồ được tạo là kiểu mặc định.KLineChart
chức năng của nền tảng FMZ để tạo đối tượng biểu đồ:
var c = KLineChart(chartCfg)
Mã thử nghiệm để vẽ đường lưới:
/*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
// ...
// ..
}
}
Nó có thể được sử dụng để tham khảo các thiết lập phong cách cấu hình biểu đồ.
{
// 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'
}
}
}
Điều này không làm cho việc thiết kế chiến lược dễ dàng hơn?