नीति चार्ट को डिजाइन करने के लिए अक्सर रणनीति चार्टों को डिजाइन करने की आवश्यकता होती है। जावास्क्रिप्ट भाषा, पायथन भाषा का उपयोग करते समय नीति चार्टों को लिखने के लिए। प्रोग्रामिंग से अपरिचित या एफएमजेड प्लेटफॉर्म पर उपयोग किए जाने वाले चार्ट लाइब्रेरी से अपरिचित उपयोगकर्ताओं को अक्सर कस्टम चार्ट पर चित्रित कोड डिजाइन करने में कठिनाई होती है। तो केवल कुछ कोड लिखने के साथ एक समृद्ध नीति चार्ट कैसे बनाया जा सकता है?
यह सरल और शक्तिशाली चित्रण तरीका पाइन भाषा में देखा जा सकता है, जो चित्रों की समृद्ध सुविधाओं के लिए प्रसिद्ध है। यदि पाइन भाषा के चित्रण इंटरफ़ेस को जावास्क्रिप्ट, पायथन भाषा की रणनीतियों में उपयोग किया जा सकता है, तो यह डेवलपर्स के डिजाइन रणनीतियों के लिए चित्रण सुविधाओं को बहुत सुविधाजनक बनाता है। इसलिए एफएमजेड प्लेटफॉर्म ने इस आवश्यकता के आधार पर कस्टम चित्रण सुविधाओं को अपग्रेड किया और उपयोग का विस्तार किया।KLineChart
फ़ंक्शन के लिए कस्टम चार्ट ड्राइंग कैसे करें; एपीआई दस्तावेज़ देखेंःhttps://www.fmz.com/api#klinechart
हम जावास्क्रिप्ट भाषा का उपयोग कर एक सरल उदाहरण लिखने के लिए शुरू करते हैं।
/*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, "volume")
c.close()
}
Sleep(1000)
}
}
यह उदाहरण बहुत सरल है, बस नीति के कस्टम ग्राफ क्षेत्र में एक K रेखाचित्र खींचें और प्रत्येक K रेखा BAR के लिए एक पूर्ण लेनदेन की अवस्था को चार्ट के उप-चित्र स्थान पर खींचें।
हम कोड में सबसे पहले उपयोग करते हैंvar c = KLineChart()
चार्ट ऑब्जेक्ट बनाएं और उसके बाद उसके तरीके को कॉल करके चार्ट बनाएं। फिर लूप में हम K-लाइन डेटा (एर्रे संरचना) प्राप्त करते हैं, और K-लाइन सरणी पर क्रॉसिंग ऑपरेशन करते हैं। उदाहरण में सरल for लूप क्रॉसिंग का उपयोग करके या अन्य तरीकों से क्रॉसिंग किया जा सकता है।
ग्राफ ऑपरेशन सेc.begin(bar)
फ़ंक्शन शुरू होता है,c.close()
फ़ंक्शन खत्म हो गया है।begin
、close
फ़ंक्शन ग्राफ़ ऑब्जेक्ट c के लिए एक तरीका है. सबसे आम रूप से उपयोग किए जाने वाले ग्राफ़ फ़ंक्शन का उपयोग करेंplot
प्रत्येक BAR पर एक लेनदेन की मात्रा रेखाएं बनाएं।
यदि हम एक आरेख बनाना चाहते हैं जिसमें एक ब्रीनिंग सूचक है। हाँ! और प्रत्येक BAR के लिए एक लेनदेन रेखाचित्र है, तो हम इसे इस तरह से डिजाइन कर सकते हैंः
/*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()
// 策略主循环
while(true) {
// 轮询间隔
Sleep(500)
// 获取K线数据
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
continue
}
// 计算布林指标
var boll = TA.BOLL(bars)
bars.forEach(function(bar, index) {
c.begin(bar)
// 画图操作
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // 画在图表主图
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // 画在图表主图
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // 画在图表主图
c.plot(bar.Volume, "volume") // 画在图表副图
c.close()
})
// 策略交易逻辑
// ...
// ..
}
}
जैसा कि आप कोड में देख सकते हैं, हमारे FMZ प्लेटफॉर्म पर रीमेक कॉन्फ़िगरेशन की जानकारी हैः
/*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"}]
*/
इस तरह के एक कॉन्फ़िगरेशन का उपयोग करके Binance एक्सचेंज ऑब्जेक्ट रीट्रेस टेस्ट किया जाता है, जिसका परिणाम इस प्रकार हैः
जैसा कि आप देख सकते हैं, हमने पाइन के चित्रण के तरीके का उपयोग किया है, जो जावास्क्रिप्ट में चित्रण कोड को बहुत सरल बनाता है।
के-लाइन डेटा प्राप्त करना, मापदंडों की गणना करना - ये ऑपरेशन प्लेटफॉर्म रणनीति स्क्वायर के रणनीति पैटर्न और एपीआई दस्तावेजों में आम हैं और बहुत सरल हैं।
// 获取K线数据
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
// 如果获取K线失败,即!bar为真则执行continue,忽略之后的代码,重新执行循环
// 如果bars.length小于等于20,即K线BAR(柱)数量小于20,无法计算指标,也执行continue
continue
}
// 计算布林指标
var boll = TA.BOLL(bars)
布林指标计算函数TA.BOLL,如果不指定布林指标参数,就使用默认参数BOLL(20, 2)
│ब्रिन संकेतक में तीन पंक्तियाँ होती हैं, इसलिए TA.BOLL फ़ंक्शन द्वारा लौटाए गए डेटा एक दो आयामी सरणी है│boll[0],boll[1],boll[2] याboll सरणी के तीन तत्व हैं, जो प्रत्येक एक पंक्ति, एक सरणी का प्रतिनिधित्व करते हैं│
फिर हम देखते हैं कि कैसे K-लाइन डेटा का वॉल्यूम या लेन-देन मात्रा, और गणना की गई ब्रूनिंग इंडिकेटर डेटा को चार्ट पर चित्रित किया जाए।
हम K-लाइन डेटा को बार-बार चित्रित कर रहे हैं, इसलिए हम पूरे K-लाइन सरणी को पार करना चाहते हैं, जो कोड में बार के सरणी को पार करता है; यहाँ उपयोग किया जाता हैforEach
method traversal, या for loop के साथ traversal का उपयोग कर सकते हैं.
bars.forEach(function(bar, index) {
c.begin(bar)
// 画图操作
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // {overlay: true}参数控制,画在图表主图
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // 画在图表主图
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // 画在图表主图
c.plot(bar.Volume, "volume") // 画在图表副图
c.close()
})
ध्यान दें कि जब भी आप किसी बार पर चार्ट बनाने का काम शुरू करते हैं, तो सबसे पहले आपको यह करना होगाc.begin(bar)
फ़ंक्शन कॉल,begin
फ़ंक्शन हमारे ग्राफ़ ऑब्जेक्ट c का एक तरीका है.c.close()
..begin
फ़ंक्शन औरclose
फ़ंक्शन के बीच में हम एक चित्र फ़ंक्शन को कॉल करते हैं, जो कि पाइन भाषा के चित्रण तरीके के समान है.barcolor
bgcolor
plot
fill
hline
plotarrow
plotshape
plotchar
plotcandle
signal
इन कार्यों के पैरामीटर पाइन भाषा के समान हैं, और चित्रण कार्य भी समान हैं।
ऊपर दिए गए ब्रीनिंग सूचक के चित्रण उदाहरण में कुछ ट्रेडिंग सिग्नल तीर, चिह्न, क्षैतिज रेखाएं जोड़ी गई हैं।
/*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()
// 策略主循环
while(true) {
// 轮询间隔
Sleep(500)
// 获取K线数据
let bars = exchange.GetRecords()
if (!bars || bars.length <= 20) {
continue
}
// 计算布林指标
var boll = TA.BOLL(bars)
bars.forEach(function(bar, index) {
c.begin(bar)
// 画图操作
c.plot(boll[0][index], "Boll_Up", {overlay: true}) // 画在图表主图
c.plot(boll[1][index], "Boll_Mid", {overlay: true}) // 画在图表主图
c.plot(boll[2][index], "Boll_Down", {overlay: true}) // 画在图表主图
c.plot(bar.Volume, "volume") // 画在图表副图
c.hline(bar.Open, {overlay: true}) // 水平线
c.plotarrow(bar.Close - bar.Open, {overlay: true}) // 箭头
c.plotshape(bar.Close - bar.Open > 0, {style: 'square', overlay: true}) // 画方块标记
c.plotchar(bar.Close - bar.Open < 0, {char: '❄', size: "20px", overlay: true}) // 画出字符❄
if (boll[0][index] && bar.Close > boll[0][index]) {
c.signal("long", bar.Close, 1.5)
} else if (boll[2][index] && bar.Close < boll[2][index]) {
c.signal("closelong", bar.Close, 1.5)
}
c.close()
})
// 策略交易逻辑
// ...
// ..
}
}
क्योंकि पाइन भाषा की रणनीति के तहत ऑपरेशन स्वचालित रूप से चार्ट पर संकेतों को चिह्नित करता है, इसलिएKLineChart
फ़ंक्शन द्वारा बनाए गए चार्ट ऑब्जेक्ट्स ने एक फ़ंक्शन को भी बढ़ाया है जिसका उपयोग सिग्नल चिह्नों को खरीदने और बेचने के लिए किया जाता हैःc.signal
。
एक संरचना को चार्ट शैली को विन्यस्त करने के लिए घोषित किया जा सकता है, उदाहरण के लिए, निम्न चार्टCfg चर एक ग्रिड लाइन के लिए विन्यस्त जानकारी दर्शाता है।
var chartCfg = {
grid: {
show: true,
// 网格水平线
horizontal: {
show: true,
size: 2,
color: '#FF0000', // 水平网格线的颜色
// 'solid'|'dash'
style: 'dash', // 线的类型
dashValue: [2, 2]
},
// 网格垂直线
vertical: {
show: true,
size: 2,
color: '#32CD32',
// 'solid'|'dash'
style: 'solid',
dashValue: [2, 2]
}
},
}
चार्ट कॉन्फ़िगरेशन ऑब्जेक्ट चार्ट के कुछ गुणों, रूपों आदि की डेटा संरचना को सेट करता है, उदाहरण के लिए, एक ग्रिड शैली का कॉन्फ़िगरेशन। कई विकल्प हैं जिन्हें कॉन्फ़िगर किया जा सकता है, जैसे कि X- अक्ष, Y- अक्ष के लिए संबंधित सेटिंग्स, प्रकाश रेखा की सेटिंग, संकेत सूचना की सेटिंग, तकनीकी संकेतक शैली सेटिंग, K-लाइन BAR शैली सेटिंग्स आदि।
बेशक, अगर आप इनसे परिचित नहीं हैं, तो आप कॉल कर रहे हैंKLineChart
फ़ंक्शन चार्ट ऑब्जेक्ट बनाते समय चार्ट कॉन्फ़िगरेशन ऑब्जेक्ट को नहीं भेज सकता है. तब चार्ट डिफ़ॉल्ट शैली में बनाया जाता है. FMZ प्लेटफॉर्म के एपीआई फ़ंक्शन का उपयोग करके।KLineChart
फ़ंक्शन चार्ट ऑब्जेक्ट बनाता हैः
var c = KLineChart(chartCfg)
ग्रिड लाइन का परीक्षण कोडः
/*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,
// 网格水平线
horizontal: {
show: true,
size: 2,
color: '#FF0000',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
},
// 网格垂直线
vertical: {
show: true,
size: 2,
color: '#32CD32',
// 'solid'|'dash'
style: 'solid',
dashValue: [2, 2]
}
},
}
var c = KLineChart(chartCfg)
// 策略主循环
while(true) {
// 轮询间隔
Sleep(500)
// 获取K线数据
var bars = _C(exchange.GetRecords)
bars.forEach(function(bar, index) {
c.begin(bar)
c.close()
})
// 策略交易逻辑
// ...
// ..
}
}
चार्ट कॉन्फ़िगरेशन शैली के संदर्भ में उपयोग किया जा सकता है।
{
// 网格线
grid: {
show: true,
// 网格水平线
horizontal: {
show: true,
size: 1,
color: '#393939',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
},
// 网格垂直线
vertical: {
show: false,
size: 1,
color: '#393939',
// 'solid'|'dash'
style: 'dash',
dashValue: [2, 2]
}
},
// 蜡烛图
candle: {
// 蜡烛图上下间距,大于1为绝对值,大于0小余1则为比例
margin: {
top: 0.2,
bottom: 0.1
},
// 蜡烛图类型 'candle_solid'|'candle_stroke'|'candle_up_stroke'|'candle_down_stroke'|'ohlc'|'area'
type: 'candle_solid',
// 蜡烛柱
bar: {
upColor: '#26A69A',
downColor: '#EF5350',
noChangeColor: '#888888'
},
// 面积图
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,
// 最高价标记
high: {
show: true,
color: '#D9D9D9',
textMargin: 5,
textSize: 10,
textFamily: 'Helvetica Neue',
textWeight: 'normal'
},
// 最低价标记
low: {
show: true,
color: '#D9D9D9',
textMargin: 5,
textSize: 10,
textFamily: 'Helvetica Neue',
textWeight: 'normal',
},
// 最新价标记
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
}
}
},
// 提示
tooltip: {
// 'always' | 'follow_cross' | 'none'
showRule: 'always',
// 'standard' | 'rect'
showType: 'standard',
labels: ['时间', '开', '收', '高', '低', '成交量'],
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
}
}
},
// 技术指标
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'
},
// 最新值标记
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
}
},
// 提示
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轴
xAxis: {
show: true,
height: null,
// x轴线
axisLine: {
show: true,
color: '#888888',
size: 1
},
// x轴分割文字
tickText: {
show: true,
color: '#D9D9D9',
family: 'Helvetica Neue',
weight: 'normal',
size: 12,
paddingTop: 3,
paddingBottom: 6
},
// x轴分割线
tickLine: {
show: true,
size: 1,
length: 3,
color: '#888888'
}
},
// y轴
yAxis: {
show: true,
width: null,
// 'left' | 'right'
position: 'right',
// 'normal' | 'percentage' | 'log'
type: 'normal',
inside: false,
reverse: false,
// y轴线
axisLine: {
show: true,
color: '#888888',
size: 1
},
// y轴分割文字
tickText: {
show: true,
color: '#D9D9D9',
family: 'Helvetica Neue',
weight: 'normal',
size: 12,
paddingLeft: 3,
paddingRight: 6
},
// y轴分割线
tickLine: {
show: true,
size: 1,
length: 3,
color: '#888888'
}
},
// 图表之间的分割线
separator: {
size: 1,
color: '#888888',
fill: true,
activeBackgroundColor: 'rgba(230, 230, 230, .15)'
},
// 十字光标
crosshair: {
show: true,
// 十字光标水平线及文字
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: {
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'
}
}
},
// 图形
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'
}
}
}
क्या यह रणनीतिक ग्राफ डिजाइन को और आसान बना देगा?
शंकड्रीम, साझा करने के लिए धन्यवाद! मैं एक परिदृश्य के बारे में पूछ रहा हूं, मुझे नहीं पता कि क्या यह इस स्तर पर क्लीनचर का उपयोग करके संभव है। 1. रणनीति कई तरह की लेन-देन है; 2. नीति लोड करते समय, डिफ़ॉल्ट रूप से निर्दिष्ट किस्मों के लिए चार्ट का चित्रण किया जाता है, जिसमें के लाइन, संकेतक, व्यापार संकेत आदि शामिल हैं; 3. फ़िल्टर बॉक्स के माध्यम से, अन्य लेनदेन किस्मों का चयन करें, और वर्तमान समय के अनुरूप K लाइन तक के ऐतिहासिक K लाइन चार्ट प्राप्त करें। इसका उद्देश्य चार्ट के माध्यम से प्रत्यक्ष रूप से देखना है कि क्या विभिन्न प्रकार के लेनदेन उचित रूप से खुले हैं और क्या लेनदेन सामान्य है।
शंकठीक है, प्राप्त!
आविष्कारक मात्रा - छोटे सपने> 1, रणनीति बहुउद्देशीय लेनदेन है; मल्टी-चैट के लिए, KLineChart फ़ंक्शन समर्थित नहीं है, चित्र-चित्र इंटरफ़ेस Chart फ़ंक्शन का उपयोग करके कई चित्र-चित्र लाइन लाइब्रेरी के डिजाइन को संदर्भित किया जा सकता है। > 2। नीति लोड करते समय, डिफ़ॉल्ट रूप से निर्दिष्ट किस्मों के लिए चार्ट का चित्रण, जिसमें के-लाइन, संकेतक, व्यापार संकेत आदि शामिल हैं; एक एकल चार्ट संभव है। > 3, फ़िल्टर बॉक्स के माध्यम से, अन्य लेनदेन किस्मों का चयन करें, वर्तमान समय के अनुरूप K लाइन तक ऐतिहासिक K लाइन ग्राफ प्राप्त करें। सिंगल चार्ट को लागू किया जा सकता है, जिसमें कोड लिखकर ऐतिहासिक K-लाइन डेटा को क्वेरी किया जा सकता है और फिर चित्र चित्र भर दिया जा सकता है। यदि बहु-प्रजाति नीति है, तो चार्ट फ़ंक्शन का उपयोग करना उचित है।