उदाहरण के लिएः
var lineColor = na
n = if bar_index > 10 and bar_index <= 20
lineColor := color.green
else if bar_index > 20 and bar_index <= 30
lineColor := color.blue
else if bar_index > 30 and bar_index <= 40
lineColor := color.orange
else if bar_index > 40
lineColor := color.black
else
lineColor := color.red
plot(close, title="close", color=n, linewidth=5, overlay=true)
plotchar(true, title="bar_index", char=str.tostring(bar_index), location=location.abovebar, color=color.red, overlay=true)
ध्यान देंः निर्णय लेने के लिए उपयोग किए जाने वाले अभिव्यक्ति, बुल मान लौटाते हैं; ध्यान दें कि संकुचन; अधिकतम एक हीelse शाखा हो सकती है; सभी शाखा अभिव्यक्ति गलत हैं, और कोईelse शाखा नहीं है, तो n लौटाता है;
x = if close > open
close
plot(x, title="x")
चूंकि जब K लाइन BAR एक कैनटीन है, यानी close < open, तो if कथन के बाद की अभिव्यक्ति false है, इसलिए if के स्थानीय कोड ब्लॉक को निष्पादित नहीं किया जाता है। इस समय भी कोईelse शाखा नहीं है, यदि कथन na लौटता है। x को na के रूप में असाइन किया गया है। इस बिंदु को चित्र में नहीं खींचा जा सकता है, हम इसे चित्र को वापस करने के माध्यम से भी देख सकते हैं।
स्विच कथन एक शाखागत संरचना वाला कथन है जिसका उपयोग कुछ शर्तों के आधार पर विभिन्न मार्गों को निष्पादित करने के लिए किया जाता है। स्विच कथन में आम तौर पर निम्नलिखित महत्वपूर्ण ज्ञान बिंदु होते हैंः
1, स्विच कथन यदि कथन की तरह ही, एक मान वापस कर सकता है । 2. अन्य भाषाओं में स्विच स्टेटमेंट के विपरीत, स्विच संरचना को निष्पादित करने पर, इसके कोड में केवल एक स्थानीय ब्लॉक निष्पादित किया जाता है, इसलिए ब्रेक घोषणा की आवश्यकता नहीं होती है (यानी ब्रेक जैसे कीवर्ड लिखने की आवश्यकता नहीं होती है) । 3. स्विच की प्रत्येक शाखा के लिए एक स्थानीय कोड ब्लॉक लिखा जा सकता है, और इस स्थानीय कोड ब्लॉक की अंतिम पंक्ति में लौटाया गया मान है (यह मानों का एक घटक हो सकता है) । यदि कोई भी शाखा नहीं चलाया गया है, तो स्थानीय कोड ब्लॉक na लौटाता है। 4. स्विच संरचना में अभिव्यक्ति के स्थान का निर्धारण, स्ट्रिंग, चर, अभिव्यक्ति या फ़ंक्शन कॉल लिख सकते हैं। 5. स्विच एक रिटर्न वैल्यू निर्दिष्ट करने की अनुमति देता है, जिसे संरचना में कोई अन्य स्थिति नहीं होने पर उपयोग करने के लिए डिफ़ॉल्ट मान के रूप में उपयोग किया जाता है।
स्विच को दो रूपों में विभाजित किया गया है, हम उदाहरणों को एक-एक करके देखते हैं और इसका उपयोग कैसे करते हैं।
एक, अभिव्यक्ति के साथswitch
उदाहरण के लिएः
// input.string: defval, title, options, tooltip
func = input.string("EMA", title="指标名称", tooltip="选择要使用的指标函数名称", options=["EMA", "SMA", "RMA", "WMA"])
// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="周期参数")
fastPeriod = input.int(10, title="快线周期参数", options=[5, 10, 20])
slowPeriod = input.int(20, title="慢线周期参数", options=[20, 25, 30])
data = input(close, title="数据", tooltip="选择使用收盘价、开盘价、最高价...")
fastColor = color.red
slowColor = color.red
[fast, slow] = switch func
"EMA" =>
fastLine = ta.ema(data, fastPeriod)
slowLine = ta.ema(data, slowPeriod)
fastColor := color.red
slowColor := color.red
[fastLine, slowLine]
"SMA" =>
fastLine = ta.sma(data, fastPeriod)
slowLine = ta.sma(data, slowPeriod)
fastColor := color.green
slowColor := color.green
[fastLine, slowLine]
"RMA" =>
fastLine = ta.rma(data, fastPeriod)
slowLine = ta.rma(data, slowPeriod)
fastColor := color.blue
slowColor := color.blue
[fastLine, slowLine]
=>
runtime.error("error")
plot(fast, title="fast" + fastPeriod, color=fastColor, overlay=true)
plot(slow, title="slow" + slowPeriod, color=slowColor, overlay=true)
पहले हमने इनपुट फ़ंक्शन सीखे थे, और अब हम इनपुट के समान दो फ़ंक्शन सीखते हैंःinput.string
、input.int
फ़ंक्शन ।input.string
एक बार जब हम एक स्ट्रिंग को पुनः प्राप्त करते हैं, तो हम एक स्ट्रिंग को पुनः प्राप्त करते हैं।input.int
फ़ंक्शन का उपयोग पूर्णांक को वापस करने के लिए किया जाता है. उदाहरण में, वास्तव में एक नया जोड़ा गया है.options
यह कैसे किया जाता है?options
पैरामीटर एक चयन योग्य मानों के साथ एक सरणी में पारित किया जा सकता है; उदाहरण के लिए उदाहरण में।options=["EMA", "SMA", "RMA", "WMA"]
औरoptions=[5, 10, 20]
(ध्यान दें कि एक स्ट्रिंग प्रकार है और दूसरा संख्या प्रकार है) । इस प्रकार, नीति इंटरफ़ेस पर नियंत्रणों को विशिष्ट संख्याओं को दर्ज करने की आवश्यकता नहीं है, बल्कि नियंत्रणों को ड्रॉप-डाउन बॉक्स में बदल दिया जाता है, जो विकल्पों पैरामीटर में दिए गए विकल्पों का चयन करता है।
चर func का मान एक स्ट्रिंग के रूप में होता है, चर func स्विच के लिए एक अभिव्यक्ति (एक चर, एक फ़ंक्शन कॉल, एक अभिव्यक्ति हो सकती है) के रूप में कार्य करता है, जो निर्धारित करता है कि स्विच में कौन सा शाखा निष्पादित की जाती है। यदि चर func स्विच में किसी भी शाखा पर अभिव्यक्ति से मेल नहीं खाता है (यानी बराबर है), तो डिफ़ॉल्ट शाखा कोड ब्लॉक निष्पादित किया जाता है, जो निष्पादित होता है।runtime.error("error")
फ़ंक्शन की वजह से पॉलिसी को असामान्य रूप से रोक दिया जाता है.
हमारे ऊपर दिए गए परीक्षण कोड में, स्विच के डिफ़ॉल्ट शाखा कोड ब्लॉक की अंतिम पंक्ति runtime.error के बाद, हम [na, na] जैसे कोड को शामिल नहीं करते हैं ताकि संगतता को वापस किया जा सके, और ट्रेडिंग दृश्य में इस समस्या को ध्यान में रखना आवश्यक है, यदि प्रकार असंगत है, तो यह त्रुटि देता है। लेकिन एफएमजेड पर इस प्रकार के संगतता कोड को छोड़ दिया जा सकता है क्योंकि कोई सख्त प्रकार की आवश्यकता नहीं है। इसलिए एफएमजेड पर यदि, स्विच शाखा के प्रकार के संगतता के मुद्दे को ध्यान में रखने की आवश्यकता नहीं है।
strategy("test", overlay=true)
x = if close > open
close
else
"open"
plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)
एफएमजेड में कोई त्रुटि नहीं, ट्रेडिंग दृश्य में त्रुटि; क्योंकि if शाखा लौटाई गई टाइप असंगत है।
2। कोई अभिव्यक्ति नहींswitch
अब हम देखेंगे।switch
एक अन्य उपयोग है, जो बिना अभिव्यक्ति के लिखा जाता है।
up = close > open // up = close < open
down = close < open
var upOfCount = 0
var downOfCount = 0
msgColor = switch
up =>
upOfCount += 1
color.green
down =>
downOfCount += 1
color.red
plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true)
plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)
परीक्षण कोड के उदाहरण से यह देखा जा सकता है कि स्विच निष्पादन शाखा की शर्तों पर सही स्थानीय कोड ब्लॉक से मेल खाता है. आम तौर पर, स्विच कथन के बाद की शाखा शर्तें परस्पर विरोधी होनी चाहिए. यानी उदाहरण में ऊपर और नीचे दोनों एक साथ सच नहीं हो सकते हैं. चूंकि स्विच केवल एक शाखा के स्थानीय कोड ब्लॉक को निष्पादित कर सकता है, इसलिए कोड में इस पंक्ति को रखना दिलचस्प हैःup = close > open // up = close < open
इसके बजाय, टिप्पणी में जो कुछ भी है, उसका परीक्षण करके परिणामों को देखें। यह पता चलेगा कि स्विच शाखा केवल पहली शाखा को निष्पादित कर सकती है। इसके अलावा, यह ध्यान रखना आवश्यक है कि स्विच की शाखा में फ़ंक्शन कॉल न करें, क्योंकि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जा सकता है, जिससे कुछ डेटा गणना समस्याएं हो सकती हैं।switch
उदाहरण में, निष्पादन शाखा निर्धारित है और रणनीति के संचालन के दौरान नहीं बदला जाएगा) ।
返回值 = for 计数 = 起始计数 to 最终计数 by 步长
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
for कथन का उपयोग बहुत सरल है, for चक्र एक अंत में एक मान ((या [a, b, c] के रूप में कई मानों को वापस कर सकता है) । जैसा कि उपरोक्त pseudo कोड में "वापसी मान" के स्थान पर दिए गए चर को असाइन किया गया है। for कथन के बाद एक "गणना" चर का उपयोग चक्र संख्या को नियंत्रित करने, अन्य मानों का उल्लेख करने आदि के लिए किया जाता है। "गणना" चर को चक्र शुरू होने से पहले "शुरुआती गणना" के रूप में असाइन किया जाता है, और फिर "विकास" सेटिंग के अनुसार, "गणना" संख्या "अंतिम चर" से अधिक होने पर चक्र बंद हो जाता है।
for के लिए उपयोग किया जाता हैbreak
कीवर्डः जब किया जाता हैbreak
एक वाक्य के बाद, चक्र बंद हो जाता है।
for के लिए उपयोग किया जाता हैcontinue
कीवर्डः जब किया जाता हैcontinue
वाक्य के बाद, लूप को अनदेखा कर दिया जाता हैcontinue
इसके बाद का कोड, सीधे अगले लूप को निष्पादित करता है. for कथन पिछले लूप निष्पादन पर लौटाया गया मान लौटाता है. यदि कोई कोड निष्पादित नहीं किया गया है तो रिक्त मान लौटाता है.
यहाँ हम एक सरल उदाहरण के साथ दिखाते हैंः
ret = for i = 0 to 10 // 可以增加by关键字修改步长,暂时FMZ不支持 i = 10 to 0 这样的反向循环
// 可以增加条件设置,使用continue跳过,break跳出
runtime.log("i:", i)
i // 如果这行不写,就返回空值,因为没有可返回的变量
runtime.log("ret:", ret)
runtime.error("stop")
for ... in
यह वाक्य दो रूपों में आता है, जिसका वर्णन नीचे दिए गए झूठे कोड में किया गया है।
返回值 = for 数组元素 in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
आप देख सकते हैं कि दोनों रूपों में मुख्य अंतर यह है कि for कीवर्ड के बाद क्या होता है, एक चर को एक चर के रूप में संदर्भित करता है। दूसरा चर को संदर्भित करने के लिए एक संरचना का उपयोग करता है जिसमें एक सूचकांक चर, एक सरणी तत्व चर होता है। दूसरा वापसी मान नियम, ब्रेक का उपयोग करना, जारी रखना और for लूप के साथ संगत है। हम एक सरल उदाहरण के साथ भी इसका उपयोग करते हैं।
testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray // 修改成 [i, ele]的形式:for [i, ele] in testArray , runtime.log("ele:", ele, ", i:", i)
runtime.log("ele:", ele)
runtime.error("stop")
जब आपको सूचकांक का उपयोग करने की आवश्यकता हो, तो उपयोग करेंfor [i, ele] in testArray
यह लेख लिखा गया है।
for पुनरावर्ती अनुप्रयोग
जब पाइन भाषा द्वारा प्रदान किए गए अंतर्निहित कार्यों का उपयोग करके कुछ लूपिकल लॉजिक गणनाएं की जा सकती हैं, तो लूपिकल संरचना का उपयोग करके सीधे लिखा जा सकता है, या अंतर्निहित फ़ंक्शन प्रसंस्करण का उपयोग किया जा सकता है। हम दो उदाहरण देते हैं।
1, गणना औसत
पुनरावर्ती संरचना डिजाइन का उपयोग करते समयः
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
उदाहरण में, for चक्रव्यूह जोड़ने का उपयोग किया जाता है, और फिर सममूल्य की गणना की जाती है।
सीधे अंतर्निहित फ़ंक्शन का उपयोग करके औसत रेखा की गणना करेंः
plot(ta.sma(close, length), title="ta.sma", overlay=true)
सीधे अंतर्निहित फ़ंक्शन का उपयोग करेंta.sma
समोच्च रेखा के लिए एक अंतर्निहित फ़ंक्शन का उपयोग करना स्पष्ट रूप से सरल है। चार्ट पर तुलना में, आप गणना के परिणामों को पूरी तरह से देखते हैं।
दो, जोड़
या फिर ऊपर दिए गए उदाहरण का उपयोग करके इसे समझाएं।
पुनरावर्ती संरचना डिजाइन का उपयोग करते समयः
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
किसी सरणी के सभी तत्वों के लिए जो कि एक चक्र का उपयोग करके संसाधित किए जा सकते हैं, एक अंतर्निहित फ़ंक्शन का भी उपयोग किया जा सकता हैarray.sum
यह एक बहुत अच्छा तरीका है।
एक अंतर्निहित फ़ंक्शन का उपयोग करके सीधे योग की गणना करेंः
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
plot(array.sum(a) / length, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
यह देखा जा सकता है कि गणना किए गए डेटा को चार्ट पर प्लॉट चित्र का उपयोग करके पूरी तरह से प्रदर्शित किया गया है।
यदि आप इन कार्यों को एक अंतर्निहित फ़ंक्शन के साथ पूरा कर सकते हैं, तो फिर लूप का डिज़ाइन क्यों करें? 1, सरणी के लिए कुछ ऑपरेशन, गणना । 2. इतिहास की समीक्षा करें, उदाहरण के लिए यह पता लगाने के लिए कि पिछले बार के उच्चतम बिंदु वर्तमान बार के उच्चतम बिंदु से कितने अधिक हैं। चूंकि वर्तमान बार के उच्चतम बिंदु केवल उस बार पर ज्ञात हैं जहां स्क्रिप्ट चल रही है, इसलिए समय पर वापस जाने और पिछले बार का विश्लेषण करने के लिए एक लूप की आवश्यकता होती है। 3. पाइन भाषा का उपयोग करने वाले अंतर्निहित फ़ंक्शन पिछले बार पर गणना नहीं कर सकते हैं।
while
कथन उस कोड को चलाता है जो उस लूप भाग में तब तक चलाया जाता है जब तक कि while संरचना में निर्णय की शर्त झूठी न हो।
返回值 = while 判断条件
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
while के अन्य नियम for लूप के समान हैं, जबकि लूप के स्थानीय कोड ब्लॉक की अंतिम पंक्ति एक रिटर्न मान है, जो कई मानों को वापस कर सकता है। जब "लूप की शर्तें" वास्तविक समय में लूप निष्पादित करती हैं, तो शर्तें झूठी होती हैं। लूप में भी break, continue कथन का उपयोग किया जा सकता है।
एक उदाहरण के रूप में, मैं एक समतल रेखा का उपयोग कर दिखाता हूंः
length = 10
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
यह देखा जा सकता है कि जबकि चक्र का उपयोग करना भी बहुत सरल है, कुछ गणना तर्क को भी डिज़ाइन किया जा सकता है जो अंतर्निहित कार्यों के साथ प्रतिस्थापित नहीं किए जा सकते हैं, जैसे कि गुणांक गणनाः
counter = 5
fact = 1
ret = while counter > 0
fact := fact * counter
counter := counter - 1
fact
plot(ret, title="ret") // ret = 5 * 4 * 3 * 2 * 1
पाइन भाषा में एक सरणी का परिभाषा अन्य प्रोग्रामिंग भाषाओं में सरणी की परिभाषा के समान है, पाइन का सरणी एक आयामी सरणी है। यह आमतौर पर एक निरंतर डेटा सेट को संग्रहीत करने के लिए उपयोग किया जाता है। सरणी में संग्रहीत एकल डेटा को सरणी के तत्व कहा जाता है, और इन तत्वों के प्रकार हो सकते हैंः पूर्णांक, फ़्लोटिंग प्रकार, स्ट्रिंग, रंग मान, बुल मान। FMZ पर पाइन भाषा में बहुत सख्त प्रकार की आवश्यकता नहीं है, यहां तक कि एक सरणी में स्ट्रिंग और संख्याओं को एक साथ संग्रहीत किया जा सकता है। क्योंकि सरणी का आधार भी एक सरणी संरचना है, यदि इतिहास ऑपरेटर का उपयोग करके पिछले BAR पर सरणी की स्थिति को संदर्भित किया जाता है तो इतिहास ऑपरेटर का उपयोग नहीं किया जाता है। इसलिए सरणी में किसी तत्व को संदर्भित करते समय इतिहास ऑपरेटर का उपयोग नहीं किया जाता है।[]
यह उपयोग करने के लिए है।array.get()
औरarray.set()
फ़ंक्शन. किसी सरणी में तत्वों के सूचकांक क्रम के अनुसार, सरणी के पहले तत्व का सूचकांक 0 है और अगले तत्व का सूचकांक 1 से बढ़ता है.
हम इसे एक सरल कोड के साथ समझाते हैंः
var a = array.from(0)
if bar_index == 0
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 1
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 2
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2])
else if bar_index == 3
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2], ", 向前数3根BAR上的a,即a[3]值:", a[3])
else if bar_index == 4
// 使用array.get 按索引获取元素,使用array.set按索引修改元素
runtime.log("数组修改前:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
array.set(a, 1, 999)
runtime.log("数组修改后:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
उपयोगarray<int> a
、float[] b
एक घोषित सरणी या केवल एक चर घोषित किया जा सकता है, उदाहरण के लिएः
array<int> a = array.new(3, bar_index)
float[] b = array.new(3, close)
c = array.from("hello", "fmz", "!")
runtime.log("a:", a)
runtime.log("b:", b)
runtime.log("c:", c)
runtime.error("stop")
सरणी चर को आरंभ करने के लिए सामान्य उपयोगarray.new
औरarray.from
函数。Pine语言中还有很多和类型相关的与array.new类似的函数:array.new_int()
、array.new_bool()
、array.new_color()
、array.new_string()
और इस तरह।
var कीवर्ड भी किसी array के declaration mode के साथ काम कर सकता है, var कीवर्ड के declaration का उपयोग करने वाले arrays को केवल पहले BAR पर initialized किया जाता है. हम एक उदाहरण के माध्यम से देखते हैंः
var a = array.from(0)
b = array.from(0)
if bar_index == 1
array.push(a, bar_index)
array.push(b, bar_index)
else if bar_index == 2
array.push(a, bar_index)
array.push(b, bar_index)
else if barstate.islast
runtime.log("a:", a)
runtime.log("b:", b)
runtime.error("stop")
जैसा कि देखा जा सकता है कि array a के परिवर्तन लगातार निर्धारित किए जाते हैं और फिर से नहीं रखे जाते हैं; array b को प्रत्येक BAR पर initialized किया जाता है; अंत में, array a के परिवर्तनों को पुनः सेट किया जाता है।barstate.islast
वास्तविक समय में प्रिंट करते समय केवल एक तत्व रहता है, जिसका मान 0 है।
array.get का उपयोग करके एक सरणी में निर्दिष्ट सूचकांक स्थान के तत्वों को प्राप्त करें, और array.set का उपयोग करके सरणी में निर्दिष्ट सूचकांक स्थान के तत्वों को संशोधित करें।
array.get का पहला पैरामीटर संसाधित करने के लिए एक सरणी है, और दूसरा पैरामीटर निर्दिष्ट सूचकांक है। array.set का पहला पैरामीटर उस सरणी का है जिसे संसाधित किया जाना है, दूसरा पैरामीटर निर्दिष्ट सूचकांक है, और तीसरा पैरामीटर उस तत्व का है जिसे लिखा जाना है।
यह एक सरल उदाहरण के साथ समझाया जा सकता हैः
lookbackInput = input.int(100)
FILL_COLOR = color.green
var fillColors = array.new(5)
if barstate.isfirst
array.set(fillColors, 0, color.new(FILL_COLOR, 70))
array.set(fillColors, 1, color.new(FILL_COLOR, 75))
array.set(fillColors, 2, color.new(FILL_COLOR, 80))
array.set(fillColors, 3, color.new(FILL_COLOR, 85))
array.set(fillColors, 4, color.new(FILL_COLOR, 90))
lastHiBar = - ta.highestbars(high, lookbackInput)
fillNo = math.min(lastHiBar / (lookbackInput / 5), 4)
bgcolor(array.get(fillColors, int(fillNo)), overlay=true)
plot(lastHiBar, title="lastHiBar")
plot(fillNo, title="fillNo")
इस उदाहरण में आधार रंग हरे रंग को आरंभ किया गया है, रंगों को संग्रहीत करने के लिए एक सरणी की घोषणा और आरंभ किया गया है, और फिर रंगों को अलग-अलग पारदर्शिता दी गई है ((color.new फ़ंक्शन का उपयोग करना) । रंग रैंकिंग की गणना वर्तमान BAR की दूरी से 100 रिव्यू चक्रों में उच्चतम मूल्य के लिए सबसे बड़ी दूरी की गणना करके की जाती है । हाल के 100 रिव्यू चक्रों में उच्चतम मूल्य के करीब रैंकिंग जितनी अधिक होगी, उतनी ही गहराई होगी ((पारदर्शिता कम होगी) । कई समान रणनीतियाँ इस तरह से वर्तमान मूल्य को N रिव्यू चक्रों में दर्शाती हैं ।
एक सरणी को कैसे पार किया जाए, यह हम पहले से सीख चुके for/for in/while कथन का उपयोग करके भी कर सकते हैं।
a = array.from(1, 2, 3, 4, 5, 6)
for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1)
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
i = 0
while i < array.size(a)
array.set(a, i, i)
i += 1
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
for [i, ele] in a
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
इन तीनों तरीकों से एक ही परिणाम मिलता है।
सरणी को स्क्रिप्ट के वैश्विक दायरे में घोषित किया जा सकता है, या फ़ंक्शन या यदि शाखा के स्थानीय दायरे में घोषित किया जा सकता है
सरणी में तत्वों के उपयोग के लिए, निम्नलिखित विधि समकक्ष है, हम निम्नलिखित उदाहरणों से देख सकते हैं कि चार्ट पर दो पंक्तियों के समूहों को चित्रित किया गया है, प्रत्येक में दो पंक्तियाँ हैं, प्रत्येक में दो पंक्तियों का संख्यात्मक मान बिल्कुल समान है।
a = array.new_float(1)
array.set(a, 0, close)
closeA1 = array.get(a, 0)[1]
closeB1 = close[1]
plot(closeA1, "closeA1", color.red, 6)
plot(closeB1, "closeB1", color.black, 2)
ma1 = ta.sma(array.get(a, 0), 20)
ma2 = ta.sma(close, 20)
plot(ma1, "ma1", color.aqua, 6)
plot(ma2, "ma2", color.black, 2)
1, सरणी के अतिरिक्त संचालन के लिए संबंधित कार्यः
array.unshift()
、array.insert()
、array.push()
。
2, सरणी के हटाने के संचालन के लिए संबंधित फ़ंक्शनः
array.remove()
、array.shift()
、array.pop()
、array.clear()
。
हम निम्नलिखित उदाहरणों का उपयोग करके इन सरणियों का परीक्षण करते हैं।
a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.insert(a, 1, "Y")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.push(a, "D")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.remove(a, 2)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.shift(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.pop(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.clear(a)
runtime.log("数组a:", a, ", ret:", ret)
runtime.error("stop")
जोड़ने और हटाने के अनुप्रयोगः एक पंक्ति के रूप में एक सरणी
हम एक "पंक्तिबद्ध" डेटा संरचना का निर्माण कर सकते हैं। पंक्तियों का उपयोग टिक मूल्य के लिए चलती औसत की गणना करने के लिए किया जा सकता है, और कुछ छात्र पूछ सकते हैंः क्यों पंक्तियों का निर्माण? क्या हम पहले पंक्तियों का उपयोग करके औसत नहीं कर सकते थे?
कतार एक ऐसा ढांचा है जो प्रोग्रामिंग में अक्सर उपयोग किया जाता है।
पहले कतार में आने वाले तत्व, पहले कतार से बाहर निकलें.
यह सुनिश्चित करता है कि कतार में मौजूद डेटा नवीनतम है, और कतार की लंबाई अंतहीन रूप से नहीं बढ़ेगी (अंतहीन रूप से बढ़ते कोड को केवल दोपहर के समय लिखा जा सकता है, क्योंकि जल्दी या बाद में समस्याएं हो सकती हैं) ।
निम्नलिखित उदाहरण में हम एक कतार संरचना का उपयोग करते हैं जो प्रत्येक टिक मूल्य को रिकॉर्ड करती है, टिक स्तर पर चलती औसत मूल्य की गणना करती है, और फिर 1 मिनट के लाइन स्तर पर चलती औसत के साथ तुलना करती है।
strategy("test", overlay=true)
varip a = array.new_float(0)
var length = 10
if not barstate.ishistory
array.push(a, close)
if array.size(a) > length
array.shift(a)
sum = 0.0
for [index, ele] in a
sum += ele
avgPrice = array.size(a) == length ? sum / length : na
plot(avgPrice, title="avgPrice")
plot(ta.sma(close, length), title="ta.sma")
ध्यान दें, जब हम a को घोषित करते हैं, तो हम keyword का उपयोग करते हुए declaration mode निर्दिष्ट करते हैं।varip
इस प्रकार, प्रत्येक मूल्य परिवर्तन को a सरणी में दर्ज किया जाता है।
संबंधित फ़ंक्शन की गणना करेंः
array.avg()
एक सरणी के सभी तत्वों का औसत है।array.min()
सबसे छोटा तत्व है।array.max()
सबसे बड़ा तत्व,array.stdev()
एक सरणी में सभी तत्वों के लिए मानक भिन्नताarray.sum()
सरणी में सभी तत्वों का योग।
ऑपरेशन से संबंधित फ़ंक्शनःarray.concat()
दो सरणियों को जोड़ना या जोड़ना।array.copy()
दोहराने वाला सरणी।array.join
सरणी के सभी तत्वों को एक स्ट्रिंग में जोड़ता है.array.sort()
यह क्रम क्रमशः ऊपर या नीचे की ओर है।array.reverse()
इनवर्टर सरणी ।array.slice()
सरणी का टुकड़ा करना।array.includes()
तत्वों का आकलन करना।array.indexof()
यह उस सूचकांक को लौटाता है जहां पैरामीटर का मान पहली बार आया था. यदि यह नहीं मिला है, तो -1 लौटाता है.array.lastindexof()
अंतिम बार दिखाई देने वाले मान को ढूंढें.
अंकगणितीय गणना के लिए संबंधित कार्यों के परीक्षण उदाहरणः
a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)
runtime.log("数组a的算数平均:", array.avg(a))
runtime.log("数组a中的最小元素:", array.min(a))
runtime.log("数组a中的最大元素:", array.max(a))
runtime.log("数组a中的标准差:", array.stdev(a))
runtime.log("数组a的所有元素总和:", array.sum(a))
runtime.error("stop")
ये सबसे अधिक उपयोग किए जाने वाले अंकगणितीय कार्य हैं।
संबंधित कार्यों का संचालन करने के उदाहरणः
a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)
runtime.log("数组a:", a, ", 数组b:", b)
runtime.log("数组a,数组b连接在一起:", array.concat(a, b))
c = array.copy(b)
runtime.log("复制一个数组b,赋值给变量c,变量c:", c)
runtime.log("使用array.join处理数组c,给每个元素中间增加符号+,连接所有元素结果为字符串:", array.join(c, "+"))
runtime.log("排序数组b,按从小到大顺序,使用参数order.ascending:", array.sort(b, order.ascending)) // array.sort函数修改原数组
runtime.log("排序数组b,按从大到小顺序,使用参数order.descending:", array.sort(b, order.descending)) // array.sort函数修改原数组
runtime.log("数组a:", a, ", 数组b:", b)
array.reverse(a) // 此函数修改原数组
runtime.log("反转数组a中的所有元素顺序,反转之后数组a为:", a)
runtime.log("截取数组a,索引0 ~ 索引3,遵循左闭右开区间规则:", array.slice(a, 0, 3))
runtime.log("在数组b中搜索元素11:", array.includes(b, 11))
runtime.log("在数组a中搜索元素100:", array.includes(a, 100))
runtime.log("将数组a和数组b连接,搜索其中第一次出现元素2的索引位置:", array.indexof(array.concat(a, b), 2), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.log("将数组a和数组b连接,搜索其中最后一次出现元素6的索引位置:", array.lastindexof(array.concat(a, b), 6), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.error("stop")
पाइन भाषा में कस्टम फ़ंक्शन डिज़ाइन किए जा सकते हैं, और आम तौर पर पाइन भाषा में कस्टम फ़ंक्शन के लिए निम्नलिखित नियम हैंः
१, सभी फ़ंक्शन स्क्रिप्ट के वैश्विक दायरे में परिभाषित होते हैं. एक फ़ंक्शन को दूसरे फ़ंक्शन में घोषित नहीं किया जा सकता.
2, फ़ंक्शन को अपने कोड में अपने आप को कॉल करने की अनुमति नहीं देता है।
3, सिद्धांत रूप में सभी पाइन भाषाओं में अंतर्निहित चित्रण फ़ंक्शन हैंbarcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()
) को कस्टम फ़ंक्शन के भीतर नहीं बुलाया जा सकता है.
4. फ़ंक्शन को सिंगल लाइन या मल्टीलाइन लिखा जा सकता है. अंतिम वाक्य का रिटर्न वैल्यू वर्तमान फ़ंक्शन का रिटर्न वैल्यू होता है, जो कि एक एलिमेंट फॉर्म में रिटर्न किया जा सकता है.
पिछले ट्यूटोरियल में हमने कई बार कस्टम फ़ंक्शन का उपयोग किया है, जैसे कि एक पंक्ति के कस्टम फ़ंक्शन को डिज़ाइन करनाः
barIsUp() => close > open
यह फ़ंक्शन वापस आता है कि क्या वर्तमान BAR सूर्य के प्रकाश के लिए है।
कई पंक्तियों वाले कस्टम फ़ंक्शन के रूप में डिज़ाइन किया गयाः
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
एक स्मा औसत रेखा के लिए एक फ़ंक्शन जिसे हम स्वयं कस्टम फ़ंक्शन के साथ लागू करते हैं।
इसके अलावा, दो चरों के लिए एक कस्टम फ़ंक्शन उदाहरण लौटाया जा सकता हैः
twoEMA(data, fastPeriod, slowPeriod) =>
fast = ta.ema(data, fastPeriod)
slow = ta.ema(data, slowPeriod)
[fast, slow]
[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)
एक फ़ंक्शन दो ईएमए समोच्च संकेतकों के लिए एक तेज़ रेखा, एक धीमी रेखा, और एक समोच्च रेखा की गणना कर सकता है।
अंतर्निहित फ़ंक्शन आसानी सेFMZ PINE स्क्रिप्ट दस्तावेज़इस बारे में पूछताछ करें।
पाइन भाषा में अंतर्निहित फ़ंक्शन वर्गीकरणः
1. स्ट्रिंग प्रोसेसिंग फ़ंक्शनstr.
श्रृंखला ।
2, रंग मान प्रसंस्करण कार्यcolor.
श्रृंखला ।
3, पैरामीटर इनपुट फ़ंक्शनinput.
श्रृंखला ।
4, सूचक गणना कार्यta.
श्रृंखला ।
5. चित्र फ़ंक्शनplot.
श्रृंखला ।
6, अंकगणितीय प्रसंस्करण कार्यarray.
श्रृंखला ।
7. लेनदेन से संबंधित फ़ंक्शनstrategy.
श्रृंखला ।
8. गणितीय कार्यों से संबंधित कार्यmath.
श्रृंखला ।
9, अन्य फ़ंक्शन ((समय प्रसंस्करण, गैर-प्लॉट श्रृंखला चित्रण फ़ंक्शन,request.
श्रृंखला फ़ंक्शन, प्रकार प्रसंस्करण फ़ंक्शन आदि) ।
strategy.
सीरियल फ़ंक्शन वे फ़ंक्शन हैं जिनका उपयोग हम डिज़ाइन रणनीतियों में अक्सर करते हैं, जो रणनीतियों के विशिष्ट संचालन के दौरान लेन-देन करने के लिए बहुत संबंधित हैं।
1、strategy.entry
strategy.entry
फ़ंक्शन एक ऐसा फ़ंक्शन है जो हमारी रणनीति लिखने के लिए बहुत महत्वपूर्ण है, और यह फ़ंक्शन कई पैरामीटर के लिए बहुत महत्वपूर्ण है जैसेःid
, direction
, qty
, when
और इस तरह।
पैरामीटरः
id
: किसी ट्रेडिंग स्थिति के लिए एक नाम के संदर्भ में समझा जा सकता है. इस आईडी को वापस लेने, ऑर्डर को संशोधित करने, समतल करने के लिए संदर्भित किया जा सकता है.direction
: यदि आदेश की दिशा अधिक है (खरीद) तो यह पैरामीटर पारित होता हैstrategy.long
यह अंतर्निहित चर, यदि खाली करना है तो बेचना हैstrategy.short
यह चर है।qty
: आदेश की मात्रा निर्दिष्ट करें, यदि यह पैरामीटर पारित नहीं किया जाता है तो डिफ़ॉल्ट रूप से आदेश की मात्रा प्रयोग की जाती है ।when
: निष्पादन शर्तें, इस पैरामीटर को निर्दिष्ट करने के लिए नियंत्रित किया जा सकता है कि क्या वर्तमान उप-ऑर्डर ऑपरेशन को ट्रिगर करना है या नहीं.limit
: ऑर्डर की सीमित कीमत निर्दिष्ट करें.stop
: स्टॉप लॉस प्राइस ।strategy.entry
फ़ंक्शन के विशिष्ट निष्पादन विवरणstrategy
फ़ंक्शन को कॉल करते समय पैरामीटर सेटिंग को नियंत्रित किया जा सकता है।"पाइन भाषा लेनदेन पुस्तकालय टेम्पलेट पैरामीटर"नियंत्रण सेट करें, पाइन भाषा लेन-देन वर्ग के लिए एक टेम्पलेट पैरामीटर नियंत्रण के लिए अधिक जानकारी के लिए, लिंक पर दस्तावेज़ देखें।
यहाँ मुख्य बात है।strategy
फ़ंक्शन में,pyramiding
、default_qty_value
पैरामीटर. निम्नलिखित कोड का उपयोग करके परीक्षण करेंः
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
ema10 = ta.ema(close, 10)
findOrderIdx(idx) =>
if strategy.opentrades == 0
false
else
ret = false
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := true
break
ret
if not findOrderIdx("long1")
strategy.entry("long1", strategy.long)
if not findOrderIdx("long2")
strategy.entry("long2", strategy.long, 0.2, when = close > ema10)
if not findOrderIdx("long3")
strategy.entry("long3", strategy.long, 0.2, limit = low[1])
strategy.entry("long3", strategy.long, 0.3, limit = low[1])
if not findOrderIdx("long4")
strategy.entry("long4", strategy.long, 0.2)
plot(ema10, title="ema10", color=color.red)
कोड प्रारंभ/*backtest ... */
पैकेज का हिस्सा रीसेट के लिए सेट किया गया है, ताकि उस समय रीसेट सेटिंग समय और अन्य जानकारी को रिकॉर्ड किया जा सके, ताकि डिबगिंग में आसानी हो सके, न कि नीति कोड।
कोड मेंःstrategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
और जब हम निर्दिष्टpyramiding
यदि हम एक ही दिशा में ट्रेड करने के लिए 3 बार सेट करते हैं, तो उदाहरण में 4 बार।strategy.entry
नीचे दिए गए ऑपरेशन में से एक को निष्पादित नहीं किया गया है. क्योंकि हमने भी निर्दिष्ट किया हैdefault_qty_value
पैरामीटर 0.1 है, इसलिए आईडी चिह्न है कि यह एक हैstrategy.entry
उपशीर्षक के लिए उपशीर्षक की मात्रा डिफ़ॉल्ट रूप से 0.1 पर सेट है.strategy.entry
फ़ंक्शन को कॉल करने के लिए हम निर्दिष्टdirection
समानstrategy.long
इस प्रकार, एक बार जब आप परीक्षण के लिए आवेदन करते हैं, तो आपको भुगतान करना होगा।
कोड में ध्यान देंstrategy.entry("long3", ...
निम्नलिखित क्रिया दो बार बोली जाती है, एक ही आईडी के लिएः strategy.entry
निम्नलिखित क्रियाओं का कोई लेनदेन नहीं हुआ है, दूसरा कॉलstrategy.entry
फ़ंक्शन इस आईडी को संशोधित करने वाले ऑर्डर के लिए है ((रिटस्ट टेस्ट के दौरान दिखाए गए डेटा में यह भी देखा जा सकता है कि इस सीमा आदेश के तहत ऑर्डर की मात्रा 0.3 के लिए संशोधित की गई है) । एक अन्य स्थिति में, उदाहरण के लिए, यदि पहली बार आईडी के लिए एक ऑर्डर किया गया है, तो इस ऑर्डर के अनुसार जारी रखें।strategy.entry
फ़ंक्शन ऑर्डर करता है, तो ऑर्डर की स्थिति आईडी लॉन्ग 3 लॉन्ग पर जमा हो जाती है।
2、strategy.close
strategy.close
फंक्शन का उपयोग समतल स्थिति को निर्दिष्ट करने के लिए किया जाता है।id
,when
,qty
,qty_percent
。
पैरामीटरः
id
: हमें लॉगिन आईडी की आवश्यकता है, जो हम उपयोग करते हैंstrategy.entry
आईडी, जो कि लॉग इन करने के लिए एक ही फ़ंक्शन के लिए खुला है।when
: कार्यान्वयन की शर्तें ।qty
: बेंचमार्क की संख्या ।qty_percent
: समतलता प्रतिशत ।इस फ़ंक्शन के उपयोग के विवरण को एक उदाहरण से परिचित कराएंः
कोड में/*backtest ... */
是FMZ.COM国际站回测时的配置信息,可以删掉,设置自己需要测试的市场、品种、时间范围等信息。
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("close Demo", pyramiding=3)
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.2)
if strategy.opentrades >= 3
strategy.close("long1") // 多个入场订单,不指定qty参数,全部平仓
// strategy.close() // 不指定id参数,会平掉当前的持仓
// strategy.close("long2") // 如果指定一个不存在的id则什么都不操作
// strategy.close("long1", qty=0.15) // 指定qty参数平仓
// strategy.close("long1", qty_percent=50) // qty_percent设置50即为平掉long1标识仓位的50%持仓
// strategy.close("long1", qty_percent=80, when=close<open) // 指定when参数,修改为close>open就不触发了
enableStop := true
परीक्षण रणनीति में दिखाया गया है कि तीन बार लगातार बहु-प्रवेश करना शुरू करें, प्रत्येक प्रवेश आईडी 1 टन है, और फिर उपयोग करेंstrategy.close
फ़ंक्शन के अलग-अलग पैरामीटर को समतल सेट करने पर अलग-अलग परिणाम प्राप्त होते हैं.strategy.close
इस फ़ंक्शन में कोई पैरामीटर नहीं है जिसके द्वारा समतल करने के लिए ऑर्डर मूल्य निर्दिष्ट किया जा सके। यह फ़ंक्शन मुख्य रूप से वर्तमान बाजार मूल्य पर तत्काल समतल करने के लिए उपयोग किया जाता है।
3、strategy.close_all
strategy.close_all
फ़ंक्शन का उपयोग वर्तमान में सभी होल्डिंग्स को समतल करने के लिए किया जाता है, क्योंकि पाइन भाषा के स्क्रिप्ट में केवल एक दिशा में होल्डिंग की अनुमति है, यदि वर्तमान होल्डिंग की दिशा के विपरीत संकेत ट्रिगर किया जाता है तो वर्तमान होल्डिंग को समतल कर दिया जाता है और संकेत के आधार पर ट्रेड शुरू किया जाता है।strategy.close_all
जब कॉल किया जाता है, तो वर्तमान दिशा में सभी होल्डिंग्स को समतल कर देता है।strategy.close_all
फ़ंक्शन के मुख्य पैरामीटर हैंःwhen
。
पैरामीटरः
when
: कार्यान्वयन की शर्तें ।हम एक उदाहरण का उपयोग करते हुए देखते हैंः
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("closeAll Demo")
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open)
strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open)
if strategy.position_size < 0
strategy.close_all()
enableStop := true
परीक्षण कोड की शुरुआत में, स्टॉक की मात्रा 0 है।strategy.position_size==0
सही है), इसलिए जब जब पैरामीटर सेट की शर्तों को पूरा करता है, तो केवल आईडी के रूप में चलाया जाता हैstrategy.entry
प्रवेश फ़ंक्शन.strategy.position_size
यदि यह 0 से अधिक है, तो आईडी के लिए लॉग इन फ़ंक्शन को निष्पादित किया जा सकता है, क्योंकि वर्तमान में कई पदों पर कब्जा कर लिया गया है, इस समय दिखाई देने वाला रिक्तता रिवर्स सिग्नल कई पदों पर कब्जा करने के बाद फिर से रिक्त हो जाएगा। फिर हम यदि शर्त में लिखते हैं जबstrategy.position_size < 0
जब, यानी, खाली सिर रखने पर, वर्तमान धारित दिशा में सभी होल्डिंग्स को समतल करें; और चिह्नित करेंenableStop := true
⇒ लॉग को देखने के लिए नीति को निष्पादित करना बंद करें.
आप देख सकते हैंstrategy.close_all
इस फ़ंक्शन में कोई पैरामीटर नहीं है जिसके द्वारा समतल करने के लिए ऑर्डर मूल्य निर्दिष्ट किया जा सके। यह फ़ंक्शन मुख्य रूप से वर्तमान बाजार मूल्य पर तत्काल समतल करने के लिए उपयोग किया जाता है।
4、strategy.exit
strategy.exit
यह फ़ंक्शन इनपुट होल्डिंग के लिए उपयोग किया जाता है, जो कि इस फ़ंक्शन से अलग हैstrategy.close
औरstrategy.close_all
फ़ंक्शन को वर्तमान बाजार मूल्य पर तुरंत समतल किया जाता है।strategy.exit
फ़ंक्शन पैरामीटर सेटिंग्स के आधार पर योजना स्थिरीकरण करता है।
पैरामीटरः
id
: इस वर्तमान बेंचमार्क की शर्त सूची के लिए ऑर्डर आईडी।from_entry
: उपयोग किया जाता है निर्दिष्ट करने के लिए लॉगिन आईडी के लिए निष्क्रिय ऑपरेशन ।qty
: बेंचमार्क की संख्या ।qty_percent
: समतलता प्रतिशत, सीमाः 0 ~ 100//profit
लाभ लक्ष्य, अंकित किया गया।loss
: स्टॉप-लॉस लक्ष्य, अंकित किया गया ।limit
: लाभ लक्ष्य, कीमत पर निर्दिष्ट ।stop
इस तरह की एक घटना के बाद, एक और घटना सामने आई।when
: कार्यान्वयन की शर्तें ।प्रत्येक पैरामीटर के उपयोग को समझने के लिए एक परीक्षण रणनीति का उपयोग करें।
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("strategy.exit Demo", pyramiding=3)
varip isExit = false
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0)
strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0)
strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0)
if not isExit and strategy.opentrades > 0
// strategy.exit("exitAll") // 如果仅仅指定一个id参数,则该退场订单无效,参数profit, limit, loss, stop等出场条件也至少需要设置一个,否则也无效
strategy.exit("exit1", "long1", profit=50) // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1
strategy.exit("exit2", "long2", qty=0.1, profit=100) // 指定参数qty,平掉ID为long2的持仓中0.1个持仓
strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000) // 指定参数qty_percent,平掉ID为long3的持仓中50%的持仓
isExit := true
if bar_index == 0
runtime.log("每点价格为:", syminfo.mintick) // 每点价格和Pine语言模板参数上「定价货币精度」参数设置有关
वास्तविक समय में मूल्य मॉडल का उपयोग करके परीक्षण करने के लिए, यह परीक्षण रणनीति तीन प्रवेश संचालन करने के लिए शुरू होती है।strategy.entry
फ़ंक्शन), limit
पैरामीटर, हुंडई ऑर्डर की कीमत 1 है जो इसे निष्क्रिय कर देती है; फिर परीक्षण शर्तों को बाहर निकालेंstrategy.exit
⇒ बिंदु संख्या के आधार पर रोकथाम, मूल्य के आधार पर रोकथाम, समतल संख्या के पदों का उपयोग, प्रतिशत के आधार पर समतल का उपयोग किया जाता है।strategy.exit
फ़ंक्शन में और भी अधिक जटिल ट्रैकिंग स्टॉप-लॉस पैरामीटर हैंःtrail_price
、trail_points
、trail_offset
आप इस उदाहरण में इसका उपयोग करने के तरीके का परीक्षण भी कर सकते हैं।
5、strategy.cancel
strategy.cancel
फ़ंक्शन का उपयोग सभी प्रीपेंडिंग कमांड को रद्द/निष्क्रिय करने के लिए किया जाता है.strategy.order
, strategy.entry
, strategy.exit
लॉग इन आईडी उत्पन्न कर सकते हैं.id
、when
。
पैरामीटरः
id
: लॉग इन आईडी रद्द करना।when
: कार्यान्वयन की शर्तें ।इस फ़ंक्शन को बहुत अच्छी तरह से समझा जाता है कि यह बिना लेनदेन के लॉगिन कमांड को रद्द करने के लिए है.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel("long1")
strategy.cancel("long2")
strategy.cancel("long3")
isStop := true
6、strategy.cancel_all
strategy.cancel_all
फ़ंक्शन औरstrategy.cancel
इस प्रकार के कार्यों में से एक है ⇒ सभी पूर्वनिर्मित आदेशों को रद्द/निष्क्रिय करना ⇒ निर्दिष्ट किया जा सकता हैwhen
पैरामीटर ।
पैरामीटरः
when
: कार्यान्वयन की शर्तें ।/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel_all()
isStop := true
7、strategy.order
strategy.order
फ़ंक्शन के फ़ंक्शन, पैरामीटर सेटिंग आदि लगभग समान हैंstrategy.entry
एकजुटता,strategy.order
फ़ंक्शन के द्वारा समर्थित हैstrategy
फ़ंक्शन काpyramiding
पैरामीटर सेटिंग्स का प्रभाव, नीचे एक बार की संख्या की कोई सीमा नहीं है।
पैरामीटरः
id
: किसी ट्रेडिंग स्थिति के लिए एक नाम के संदर्भ में समझा जा सकता है. इस आईडी को वापस लेने, ऑर्डर को संशोधित करने, समतल करने के लिए संदर्भित किया जा सकता है.direction
: यदि आदेश की दिशा अधिक है (खरीद) तो यह पैरामीटर पारित होता हैstrategy.long
यह अंतर्निहित चर, यदि खाली करना है तो बेचना हैstrategy.short
यह चर है।qty
: आदेश की मात्रा निर्दिष्ट करें, यदि यह पैरामीटर पारित नहीं किया जाता है तो डिफ़ॉल्ट रूप से आदेश की मात्रा प्रयोग की जाती है ।when
: निष्पादन शर्तें, इस पैरामीटर को निर्दिष्ट करने के लिए नियंत्रित किया जा सकता है कि क्या वर्तमान उप-ऑर्डर ऑपरेशन को ट्रिगर करना है या नहीं.limit
: ऑर्डर की सीमित कीमत निर्दिष्ट करें.stop
: स्टॉप लॉस प्राइस ।हम उपयोग करते हैंstrategy.order
यह गुण है, जो कि एक ही संख्या में सीमित नहीं है।strategy.exit
सशर्त निकासी फ़ंक्शन↑ एक स्क्रिप्ट का निर्माण करें जो कि ग्रिड लेनदेन के समान है↑ उदाहरण बहुत सरल है, केवल सीखने के लिएः
/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/
varip beginPrice = -1
if not barstate.ishistory
if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0)
beginPrice := close
for i = 0 to 20
strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)
इस ट्यूटोरियल में रणनीति उदाहरण केवल शिक्षण रणनीति, मार्गदर्शन रणनीति डिजाइन विचारों के लिए उपयोग किया जाता है, कोई व्यापार मार्गदर्शन, सुझाव नहीं है।
strategy("supertrend", overlay=true)
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)
if direction < 0
if supertrend > supertrend[2]
strategy.entry("entry long", strategy.long)
else if strategy.position_size < 0
strategy.close_all()
else if direction > 0
if supertrend < supertrend[3]
strategy.entry("entry short", strategy.short)
else if strategy.position_size > 0
strategy.close_all()
पाइन भाषा का उपयोग करके प्रवृत्ति रणनीति लिखने के लिए बहुत सरल है, यहाँ हम एक सुपर प्रवृत्ति संकेतक के साथ एक सरल प्रवृत्ति ट्रैकिंग रणनीति डिजाइन करते हैं। आइए इस रणनीति के स्रोत कोड का विश्लेषण करें।
सबसे पहले, रणनीति कोड का उपयोग करना शुरू करेंstrategy
फ़ंक्शन कुछ सरल सेटिंग्स करता हैःstrategy("supertrend", overlay=true)
, बस एक रणनीति शीर्षक सेट करें सुपरट्रेंड टैग सेट करें.overlay
पैरामीटर हैtrue
हम एक पाइन रणनीति डिजाइन या एक पाइन रणनीति स्क्रिप्ट सीखने के लिए सबसे पहले रणनीति इंटरफ़ेस पैरामीटर डिजाइन को देखने के लिए, हम "सुपर ट्रेंड इंडिकेटर रणनीति" के स्रोत को देखते हैं, जिसमें हमने पहले के पाठ्यक्रमों में सीखा हैinput
फ़ंक्शन
[सुपरट्रेंड, दिशा] = ta.सुपरट्रेंड(इनपुट(5,
कारक input.int(10,), त्रिअवधि ))
input
फ़ंक्शन कॉल सीधे उपयोग किया जाता हैta.supertrend
सूचकांक फ़ंक्शन के पैरामीटर सुपरट्रेंड सूचकांक की गणना करने के लिए उपयोग किए जाते हैं; जिनमें सेः
फ़ंक्शन डिफ़ॉल्ट रूप से पाइन भाषा नीति इंटरफ़ेस पर दो पैरामीटर नियंत्रण सेट करता है, जैसेः
आप देख सकते हैं कि नियंत्रण पर डिफ़ॉल्ट मान हैinput
फ़ंक्शन औरinput
और यह है कि यह हैinput.int
) का पहला पैरामीटर, जो पिछले अध्याय में भी समझाया गया है. इन दो कार्यों के साथ हम रणनीति इंटरफ़ेस पर सेट कर सकते हैंta.supertrend
फ़ंक्शन के पैरामीटर है. सुपर ट्रेंड इंडिकेटर फ़ंक्शन एक मूल्य डेटा की गणना करता है.supertrend
और एक दिशा डेटाdirection
.. और फिर इस्तेमाल करें.plot
फ़ंक्शन ग्राफ़, ध्यान दें कि जब ग्राफ़िंग सुपर ट्रेंड इंडिकेटर के अनुसार दिशा में चित्रित किया जाता है, तो केवल वर्तमान दिशा को चित्रित किया जाता है; जबdirection
- 1 के लिए वर्तमान बाजार का रुझान ऊपर की ओर है, जबdirection
1 बजे के लिए, वर्तमान बाजार नीचे की ओर है। इसलिए हम देख सकते हैं।plot
फ़ंक्शन ग्राफ़िंग करते समय निर्णय लेंdirection
0 से बड़ा, 0 से छोटा.
अगलाif ... else if
तर्क व्यापार संकेतों का न्याय करता है, जब अभिव्यक्तिdirection < 0
वास्तविक समय में यह दर्शाता है कि वर्तमान बाजार ऊपर की ओर है, जब सुपर ट्रेंड इंडिकेटर में मूल्य डेटाsupertrend
पहले 2 बार पर सुपर ट्रेंड इंडिकेटर की कीमत से ऊपर (यानीsupertrend[2],还记得历史操作符引用某个变量历史数据吧
) इसे अधिक करने के लिए प्रवेश संकेत के रूप में लेते हैं. याद है? यदि वर्तमान में होल्डिंग है, तो इस समय रिवर्स डाउन सिंगल फ़ंक्शन कॉल करें जो पहले की होल्डिंग को समतल कर देगा, और फिर वर्तमान ट्रेडिंग दिशा के अनुसार स्थिति खोलेगा.supertrend > supertrend[2]
इस समय तक, हम इस बात पर सहमत नहीं हैं कि हम क्या कर रहे हैं।strategy.position_size < 0
और यह भी कि अगर आप एक खाली जगह रखते हैं, तो यह ट्रिगर करता है।strategy.close_all()
फ़ंक्शन निष्पादित करें, सभी समतल करें।
direction > 0
जब नीचे की ओर चल रहा है, तो यह समान है, यदि कई होल्डिंग्स सभी समतल हैं, तो शर्तें पूरी होती हैं।supertrend < supertrend[3]
और अगर आप इस तरह के एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है कि आप एक संकेत है।[3]
क्या पहले तीसरे बार पर सुपर ट्रेंडिंग इंडिकेटर के मूल्य डेटा का संदर्भ दिया गया है? शायद रणनीतिकारों का इरादा है, क्योंकि कुछ बाजारों में, जैसे कि अनुबंध व्यापार बाजार में, जोखिम लेने का जोखिम थोड़ा अधिक है।
के लिएta.supertrend
एक सूचक, क्या कुछ छात्रों को दिलचस्पी है कि यह कैसे पता चलता है कि वर्तमान रुझान ऊपर है या नीचे है?
वास्तव में, यह सूचक पाइन भाषा में एक कस्टम फ़ंक्शन के रूप में भी लागू किया जा सकता हैः
pine_supertrend(factor, atrPeriod) =>
src = hl2
atr = ta.atr(atrPeriod)
upperBand = src + factor * atr
lowerBand = src - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
direction := 1
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
यह एक कस्टम फ़ंक्शन है और एक अंतर्निहित फ़ंक्शन है.ta.supertrend
एक ही एल्गोरिथ्म, और निश्चित रूप से गणना किए गए सूचक डेटा समान हैं।
इस कस्टम फ़ंक्शन एल्गोरिथ्म से हम देख सकते हैं कि पाइन के अंतर्निहित सुपर ट्रेंड इंडिकेटर का उपयोग किया जाता हैhl2
अंतर्निहित चर (सबसे अधिक मूल्य, न्यूनतम मूल्य जोड़ा गया और 2 से विभाजित, उच्चतम मूल्य, न्यूनतम मूल्य का औसत) और फिर पैरामीटर trPeriod के आधार पर एक निश्चित चक्र के लिए एटीआर संकेतक (लहर चौड़ाई) का गणना की गई; और फिर hL2 और एटीआर का उपयोग करके ऊपर की ओर, नीचे की ओर, ऊपर की ओर और नीचे की ओर बनाया गया।
कोड में तीन-आयामी अभिव्यक्ति के आधार पर अद्यतन करेंlowerBand
औरupperBand
。
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: नीचे की पटरी, यह जानने के लिए कि क्या ऊपर की ओर रुझान बदल रहा है;upperBand: ऊपर की पटरी, यह जानने के लिए कि क्या नीचे की ओर रुझान बदल रहा है;lowerBand और upperBand हमेशा गणना की जा रही है, केवल इस कस्टम फ़ंक्शन के अंत में वर्तमान रुझान की दिशा का पता लगाने के लिए।
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
यहाँ यह निर्धारित करने के लिए है कि अगर पिछले बार पर सुपर ट्रेंड मूल्य हैprevUpperBand
यदि आप इस समय नीचे की ओर बढ़ रहे हैं, तो आप नीचे की ओर बढ़ रहे हैं।close
से अधिकupperBand
एक बार जब कीमतें टूट जाती हैं, तो यह माना जाता है कि इस समय रुझान बदल जाता है और ऊपर की ओर बढ़ जाता है।direction
दिशा चर -1 ((ऊपर की ओर प्रवृत्ति) पर सेट है; अन्यथा यह अभी भी 1 ((नीचे की ओर प्रवृत्ति) पर सेट है; इसलिए आप सुपर ट्रेंड रणनीति में देखेंगेif direction < 0
जब सिग्नल की स्थिति ट्रिगर हो जाती है, तो अधिक करें।direction > 0
जब सिग्नल की स्थिति ट्रिगर हो जाती है तो खाली हो जाता है।
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
अंत में, दिशा के अनुसार चयनित विशिष्ट सुपरट्रेंड इंडिकेटर मूल्य डेटा और दिशा डेटा लौटाते हैं।
/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/
varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")
maxDiffValue = input(1000, "maxDiffValue")
if balance - close * stocks > maxDiffValue and not barstate.ishistory
// more balance , open long
tradeAmount = (balance - close * stocks) / 2 / close
strategy.order("long", strategy.long, tradeAmount)
balance := balance - tradeAmount * close
stocks := stocks + tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
else if close * stocks - balance > maxDiffValue and not barstate.ishistory
// more stocks , open short
tradeAmount = (close * stocks - balance) / 2 / close
strategy.order("short", strategy.short, tradeAmount)
balance := balance + tradeAmount * close
stocks := stocks - tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)
हम पाइन भाषा में रणनीति डिजाइन के कुछ उदाहरणों को सीखना जारी रखते हैं, इस बार हम एक गतिशील संतुलन रणनीति के बारे में बात करते हैं।BaseCurrency
(व्यापार की जाती है) की राशि औरQuoteCurrency
(मुद्राओं के लिए) राशि हमेशा संतुलन का निपटान करता है; किसी भी संपत्ति के सापेक्ष मूल्य में वृद्धि, खाते में रखे गए मूल्य में वृद्धि के लिए बेचने के लिए कौन सी संपत्ति; यदि किसी भी संपत्ति के सापेक्ष मूल्य में कमी आती है, तो खाते में रखे गए मूल्य में कमी आती है, तो इस संपत्ति को खरीदें। यह तथाकथित गतिशील संतुलन रणनीति है। वास्तव में गतिशील संतुलन रणनीति एक ग्रिड रणनीति है, जो अस्थिर बाजार में अच्छी तरह से काम करती है। लेकिन प्रवृत्ति बाजार में निरंतर घाटे की आवश्यकता होती है, और कीमतों के लौटने का इंतजार करने के लिए नुकसान को कम करने के लिए धीरे-धीरे कम किया जा सकता है ताकि लाभदायक हो सके, लेकिन गतिशील संतुलन रणनीति हमेशा बाजार में अस्थिरता को पकड़ सकती है।
इस रणनीति का नुकसान यह है कि, जैसा कि इस रणनीति के रीट्रीट चार्ट में दिखाया गया है, मूल्य वृद्धि (या गिरावट) के चरणों में यह रणनीति अधिक लाभप्रद है। इसलिए यह रणनीति मौद्रिक रणनीति के लिए अच्छी है, लेकिन वायदा में इसका उपयोग जोखिम को नियंत्रित करने की आवश्यकता है।
एक बार फिर, हम एक बार फिर से एक बार फिर से एक बार फिर से एक बार फिर से शुरू करते हैं।
हमने एक सरलीकृत डिजाइन का उपयोग किया है, जो रणनीति में एक अनुकरण है।balance
(अर्थात QuoteCurrency की संपत्ति की संख्या) औरstocks
(अर्थात, बेस करेंसी परिसंपत्तियों की संख्या) संतुलन सूचना. हम खाते में वास्तविक संपत्ति की संख्या नहीं पढ़ते हैं, हम केवल अनुकरणीय राशि का उपयोग करते हैं उचित खरीदने और बेचने के लिए गणना करने के लिए. और फिर इस गतिशील संतुलन रणनीति को खींचने वाले ग्रिड को प्रभावित करने वाले महत्वपूर्ण पैरामीटर हैंmaxDiffValue
, यह पैरामीटर संतुलन का न्याय करने का मापदंड है.BaseCurrency
औरQuoteCurrency
अधिक विचलनmaxDiffValue
यह समय संतुलन बनाने का है, उच्च मूल्य वाली संपत्ति बेचने का है, कम मूल्य वाली संपत्ति खरीदने का है और फिर से संतुलन बनाने का है।
रणनीतिक व्यापार संकेतों को वास्तविक समय के बार चरण में ट्रिगर किया जाना चाहिए, इसलिए रणनीतिक व्यापार की शर्तें यदि निर्णय में सेट की जाती हैंnot barstate.ishistory
◊ जब वर्तमान कीमतों के आधार पर गणना की जाती है,balance
मूल्य से अधिकstocks
मूल्य के समय खरीदें. इसके विपरीत बेचें. लेनदेन के बाद अपडेट करेंbalance
औरstocks
एक बार जब आप एक चर को बदलते हैं, तो आप अगले संतुलन को ट्रिगर करने की प्रतीक्षा करते हैं।
उपरोक्त रणनीति retracement जानकारी में रणनीति retracement शुरू होने के समय के लिए किस्म की कीमत है, जो कि 1458 है, इसलिए मैंने जानबूझकर पैरामीटर सेट किया है।balance
4374 ((1458*3) के लिए पैरामीटर सेट करेंstocks
3. संपत्ति को शुरू में संतुलन में रखना।
पिछले पाठों में हमने सीखा हैstrategy.exit
स्थिति निकासी फ़ंक्शन, जिसमें ट्रैकिंग स्टॉप लॉस स्टॉप कैप फ़ंक्शन है, इसका कोई उदाहरण नहीं है। इस खंड में रणनीति डिजाइन उदाहरण के लिए हम उपयोग करते हैंstrategy.exit
एक सुपर ट्रेंडिंग रणनीति को अनुकूलित करने के लिए फ़ंक्शन का ट्रैकिंग स्टॉप-लॉस-स्टॉप फ़ंक्शन।
सबसे पहले हम देखते हैं।strategy.exit
फ़ंक्शन के लिए ट्रैकिंग स्टॉप-लॉस-स्टॉप पैरामीटरः
1、trail_price
पैरामीटरः ट्रिगर करने के लिए स्थान पर रखने के लिए ट्रैक बंद करो बंद करो बंद करो लॉस समाप्ति आदेश के इस तार्किक व्यवहार ((कीमत में निर्दिष्ट)