[TOC]
समर्थन वीडियो ट्यूटोरियलःhttps://www.youtube.com/watch?v=CA3SwJQb_1g
एफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म पाइन भाषा रणनीति लेखन, बैकटेस्टिंग और पाइन भाषा रणनीतियों के लाइव ट्रेडिंग का समर्थन करता है, और यह पाइन भाषा के निचले संस्करणों के साथ संगत है।रणनीति वर्गएफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म पर (FMZ.COM).
एफएमजेड न केवल पाइन भाषा का समर्थन करता है, बल्कि पाइन भाषा के शक्तिशाली ड्राइंग फ़ंक्शन का भी समर्थन करता है। एफएमजेड प्लेटफॉर्म पर विभिन्न कार्य, समृद्ध और व्यावहारिक उपकरण, कुशल और सुविधाजनक प्रबंधन पाइन रणनीति (स्क्रिप्ट) की व्यावहारिकता को और बढ़ाता है। पाइन भाषा के साथ संगतता के आधार पर, एफएमजेड भी पाइन भाषा का विस्तार, अनुकूलन और एक निश्चित हद तक ट्रिम करता है। आधिकारिक तौर पर ट्यूटोरियल में प्रवेश करने से पहले, आइए देखें कि मूल संस्करण की तुलना में एफएमजेड पर पाइन भाषा में क्या बदलाव किए गए हैं।
कुछ स्पष्ट मतभेदों का संक्षिप्त अवलोकन:
//@version
औरstrategy
, indicator
कोड की शुरुआत में बयान लिखने के लिए अनिवार्य नहीं हैं, FMZ समर्थन नहीं करताimport
आयात करनाlibrary
अभी के लिए काम करता है।यह देखा जा सकता है कि कुछ रणनीतियाँ इस तरह लिखी गई हैंः
//@version=5
indicator("My Script", overlay = true)
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue)
plot(b, color = color.black)
plotshape(c, color = color.red)
या इसे इस तरह लिखें:
//@version=5
strategy("My Strategy", overlay=true)
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
एफएमजेड पर इसे सरल किया जा सकता हैः
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue, overlay=true)
plot(b, color = color.black, overlay=true)
plotshape(c, color = color.red, overlay=true)
या:
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
समापन मूल्य मॉडल और वास्तविक समय मूल्य मॉडल
व्यापारिक दृश्य पर, हम उपयोग कर सकते हैंcalc_on_every_tick
पैरामीटरstrategy
समारोह रणनीति स्क्रिप्ट सेट करने के लिए वास्तविक समय में रणनीति तर्क निष्पादित करने के लिए जब कीमत हर बार बदल जाता है। इस समय,calc_on_every_tick
पैरामीटर को सेट किया जाना चाहिएtrue
.calc_on_every_tick
डिफ़ॉल्ट पैरामीटर हैfalse
, यानी रणनीति तर्क तभी निष्पादित होता है जब रणनीति का वर्तमान K-लाइन BAR पूरी तरह पूरा हो जाता है।
एफएमजेड पर, यह
संख्यात्मक सटीक नियंत्रण, जैसे कि मूल्य और आदेश राशि जब रणनीति निष्पादित की जाती है FMZ पर निर्दिष्ट किया जाना चाहिए ट्रेडिंग व्यू में, वास्तविक ट्रेडिंग ऑर्डर रखने पर सटीकता की कोई समस्या नहीं होती है, क्योंकि इसका केवल सिमुलेशन में परीक्षण किया जा सकता है। एफएमजेड पर, वास्तविक ट्रेडिंग में पाइन रणनीति चलाना संभव है। फिर रणनीति को ट्रेडिंग किस्म की मूल्य सटीकता और ऑर्डर राशि सटीकता को लचीले ढंग से निर्दिष्ट करने में सक्षम होना चाहिए। सटीकता सेटिंग्स प्रासंगिक डेटा में दशमलव स्थानों की संख्या को नियंत्रित करती हैं ताकि डेटा को एक्सचेंज की ऑर्डर आवश्यकताओं को पूरा नहीं करने से रोका जा सके और इस प्रकार ऑर्डर करने में विफल रहे।
वायदा अनुबंध कोड
यदि एफएमजेड पर ट्रेडिंग उत्पाद एक अनुबंध है, तो इसमें दो विशेषताएं हैं, वे क्रमशः swap
उदाहरण के लिए, कुछ एक्सचेंजों में त्रैमासिक अनुबंध होते हैं, आप भर सकते हैंquarter
ये अनुबंध कोड एफएमजेड
अन्य सेटिंग्स के लिए, जैसे कि न्यूनतम ऑर्डर राशि, डिफ़ॉल्ट ऑर्डर राशि, आदि, कृपया पैरामीटर परिचय देखें।
runtime.debug
, runtime.log
, runtime.error
डिबगिंग के लिए प्रयोग किया जाता है.डीबगिंग के लिए एफएमजेड प्लेटफॉर्म में 3 फ़ंक्शन जोड़े गए हैं।
runtime.debug
: कंसोल पर चर सूचना मुद्रित करें, जिसका सामान्यतः इस कार्य के साथ उपयोग नहीं किया जाता है।
runtime.log
: लॉग में आउटपुट। FMZ पर PINE भाषा-विशिष्ट कार्य।
runtime.log(1, 2, 3, close, high, ...), Multiple parameters can be passed.
runtime.error
: यह संदेश पैरामीटर में निर्दिष्ट त्रुटि संदेश के साथ एक रनटाइम त्रुटि का परिणाम होगा जब बुलाया जाता है.
runtime.error(message)
overlay
पैरामीटर ड्राइंग कार्यों में से कुछ में विस्तारित हैFMZ पर पाइन भाषा में, ड्राइंग कार्योंplot
, plotshape
, plotchar
, आदि ने जोड़ा हैoverlay
पैरामीटर समर्थन, जो मुख्य चार्ट या उप-चार्ट पर ड्राइंग को निर्दिष्ट करने की अनुमति देता है।overlay
पर सेट हैtrue
मुख्य चार्ट पर आकर्षित करने के लिए, औरfalse
उप-चार्ट पर आकर्षित करने के लिए सेट किया गया है, जो एफएमजेड पर पाइन रणनीति को एक ही समय में मुख्य चार्ट और उप-चार्ट को आकर्षित करने में सक्षम बनाता है।
syminfo.mintick
अंतर्निहित चरके अंतर्निहित चरsyminfo.mintick
वर्तमान प्रतीक के लिए न्यूनतम टिक मान के रूप में परिभाषित किया गया है। इस मूल्य को FMZ पर syminfo.mintick
0.01 है।
उदाहरण के लिए: ऑर्डर की कीमत 8000 है, बिक्री की दिशा, मात्रा 1 लॉट (टुकड़ा, शीट) है, लेनदेन के बाद औसत कीमत 8000 नहीं है, लेकिन 8000 से कम है (लागत में हैंडलिंग शुल्क शामिल है) ।
जब आप पाइन भाषा की मूल बातें सीखना शुरू करते हैं, तो निर्देशों और कोड व्याकरण के कुछ उदाहरण हो सकते हैं जिनसे हम परिचित नहीं हैं। इससे कोई फर्क नहीं पड़ता कि आप इसे नहीं समझते हैं, हम पहले अवधारणाओं से परिचित हो सकते हैं और परीक्षण के उद्देश्य को समझ सकते हैं, या आप निर्देशों के लिए एफएमजेड पर पाइन भाषा प्रलेखन की जांच कर सकते हैं। फिर विभिन्न व्याकरणों, निर्देशों, कार्यों और अंतर्निहित चरों से परिचित होने के लिए ट्यूटोरियल चरण-दर-चरण का पालन करें।
पाइन भाषा सीखने की शुरुआत करते समय, पाइन भाषा स्क्रिप्ट प्रोग्राम की निष्पादन प्रक्रिया जैसी संबंधित अवधारणाओं को समझना बहुत आवश्यक है। पाइन भाषा रणनीति चार्ट के आधार पर चलती है। यह समझा जा सकता है कि पाइन भाषा रणनीति गणनाओं और संचालन की एक श्रृंखला है, जो चार्ट पर लोड किए गए सबसे शुरुआती डेटा से समय श्रृंखला के क्रम में चार्ट पर निष्पादित की जाती है। डेटा की मात्रा जो चार्ट शुरू में लोड करता है वह सीमित है। वास्तविक व्यापार में, अधिकतम डेटा की मात्रा आमतौर पर एक्सचेंज इंटरफ़ेस द्वारा लौटाए गए अधिकतम डेटा वॉल्यूम के आधार पर निर्धारित की जाती है, और बैकटेस्टिंग के दौरान डेटा की अधिकतम मात्रा बैकटेस्टिंग सिस्टम के डेटा स्रोत द्वारा प्रदान किए गए डेटा के आधार पर निर्धारित की जाती है। चार्ट पर सबसे बाईं ओर के-लाइन बार, यानी चार्ट के पहले डेटा सेट का सूचकांक मान 0 है।bar_index
पाइन भाषा में।
plot(bar_index, "bar_index")
..plot
समारोह हम भविष्य में अधिक उपयोग करेंगे कार्यों में से एक है. उपयोग बहुत सरल है, यह इनपुट मापदंडों के अनुसार चार्ट पर एक रेखा खींचने के लिए है, इनपुट डेटा हैbar_index
, और लाइन का नाम हैbar_index
. यह देखा जा सकता है कि पहले बार पर bar_index नामक पंक्ति का मान 0 है, और यह बार बढ़ने के साथ 1 से दाईं ओर बढ़ता है।
क्योंकि रणनीति की सेटिंग अलग है, रणनीति के मॉडल निष्पादन के तरीके अलग हैं, उन्हें विभाजित किया जा सकता हैclosing price model
औरreal-time price model
हमने पहले भी संक्षेप में इनकी अवधारणाओं का परिचय दिया है।
समापन मूल्य मॉडल
जब रणनीति कोड निष्पादित किया जाता है, तो वर्तमान K-लाइन बार की अवधि पूरी तरह से निष्पादित की जाती है, और जब K-लाइन बंद हो जाती है, तो K-लाइन अवधि पूरी हो जाती है। इस बिंदु पर, पाइन रणनीति तर्क एक बार निष्पादित किया जाता है, और ट्रिगर किए गए ट्रेडिंग सिग्नल को अगले K-लाइन बार की शुरुआत में निष्पादित किया जाएगा।
वास्तविक समय मूल्य मॉडल
जब रणनीति कोड निष्पादित किया जाता है, भले ही वर्तमान के-लाइन बार बंद हो या नहीं, पाइन रणनीति तर्क निष्पादित किया जाएगा जब बाजार हर बार बदलता है, और ट्रिगर ट्रेडिंग सिग्नल तुरंत निष्पादित किया जाएगा।
जब पाइन भाषा रणनीति चार्ट पर बाएं से दाएं निष्पादित की जाती है, तो चार्ट पर के-लाइन बार में विभाजित होते हैंHistorical Bars
औरReal-time Bars
:
ऐतिहासिक बार
जब रणनीति Historical Bars
. रणनीति तर्क प्रत्येक पर केवल एक बार निष्पादित किया जाता हैhistorical bar
..
जब रणनीति को historical bars
. रणनीति तर्क प्रत्येक पर केवल एक बार निष्पादित किया जाता हैhistorical bar
.
ऐतिहासिक बारों के आधार पर गणनाः रणनीति कोड ऐतिहासिक पट्टी के बंद होने की स्थिति में एक बार निष्पादित किया जाता है, और फिर रणनीति कोड अगले ऐतिहासिक पट्टी में निष्पादित किया जाता है जब तक कि सभी ऐतिहासिक पट्टी एक बार निष्पादित नहीं हो जाती हैं।
वास्तविक समय बार
जब रणनीति को अंतिम K-लाइन बार पर निष्पादित किया जाता है, तो बार एक वास्तविक समय बार है। वास्तविक समय बार बंद होने के बाद, बार एक पारित वास्तविक समय बार (ऐतिहासिक बार बन जाता है) बन जाता है। चार्ट के सबसे दाईं ओर एक नया वास्तविक समय बार उत्पन्न होगा।
जब रणनीति को
वास्तविक समय बार पर आधारित गणनाः
यदि रणनीति को high
, low
, close
ऐतिहासिक बार पर निर्धारित होते हैं, और ये मूल्य हर बार बदल सकते हैं जब बाजार वास्तविक समय के बार पर बदलता है। इसलिए, इन मूल्यों के आधार पर गणना किए गए संकेतकों जैसे डेटा भी वास्तविक समय में बदलेंगे। वास्तविक समय के बार पर,close
हमेशा वर्तमान नवीनतम मूल्य को दर्शाता है, औरhigh
औरlow
हमेशा वर्तमान वास्तविक समय पट्टी की शुरुआत के बाद से प्राप्त उच्चतम बिंदु और निम्नतम बिंदु का प्रतिनिधित्व करते हैं। ये अंतर्निहित चर वास्तविक समय पट्टी के अंतिम मूल्य का प्रतिनिधित्व करते हैं जब इसे अंतिम बार अपडेट किया गया था।
रीयल-टाइम बार (रीयल-टाइम प्राइस मॉडल) पर रणनीतियों को निष्पादित करते समय रोलबैक तंत्रः वास्तविक समय बार निष्पादन के दौरान, रणनीति के प्रत्येक नए पुनरावृत्ति से पहले उपयोगकर्ता-परिभाषित चर को रीसेट करना रोलबैक कहा जाता है। आइए निम्नलिखित परीक्षण कोड के उदाहरण के साथ रोलबैक तंत्र को समझें।
ध्यान दें:
/*backtest
...
..
.
*/
पैकेज की सामग्री बैकटेस्ट कॉन्फ़िगरेशन जानकारी है जो एफएमजेड प्लेटफॉर्म पर कोड के रूप में सहेजी गई है।
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
var n = 0
if not barstate.ishistory
runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
n := n + 1
runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
plot(n, title="n")
हम केवल वास्तविक समय के दौरान निष्पादित दृश्य की जांच बार, तो हम का उपयोगnot barstate.ishistory
केवल वास्तविक समय बार में चर n के संचय को सीमित करने के लिए अभिव्यक्ति, और उपयोगruntime.log
संचयन क्रिया से पहले और बाद में रणनीति लॉग में जानकारी आउटपुट करने के लिए कार्य। ड्राइंग फ़ंक्शन का उपयोग करके खींची गई वक्र n सेplot
, यह देखा जा सकता है कि n हमेशा 0 होता है जब रणनीति ऐतिहासिक बारों में चल रही होती है। जब वास्तविक समय बार निष्पादित होता है, तो 1 को n में जोड़ने का ऑपरेशन ट्रिगर किया जाता है, और 1 को n में जोड़ने का ऑपरेशन वास्तविक समय बार के प्रत्येक दौर में रणनीति निष्पादित होने पर निष्पादित होता है। यह लॉग संदेश से देखा जा सकता है कि n को पिछले बार निष्पादन रणनीति द्वारा अंतिम रूप से प्रस्तुत मूल्य पर रीसेट किया जाएगा जब रणनीति कोड प्रत्येक दौर में फिर से निष्पादित किया जाता है। n मान अद्यतन तब प्रस्तुत किया जाएगा जब रणनीति कोड वास्तविक समय बार पर अंतिम बार निष्पादित किया जाता है, इसलिए आप देख सकते हैं कि आरेख पर वास्तविक समय बार से शुरू होने वाले बार की प्रत्येक वृद्धि के साथ वक्र n का मूल्य 1 बढ़ता है।
सारांश:
डेटा रोलबैक के कारण, चार्ट पर वक्र जैसे ड्राइंग ऑपरेशन भी पुनः ड्राइंग का कारण बन सकते हैं। उदाहरण के लिए, लाइव ट्रेडिंग के लिए अभी परीक्षण कोड को संशोधित करेंः
var n = 0
if not barstate.ishistory
runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
n := open > close ? n + 1 : n
runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
plot(n, title="n")
समय A का स्क्रीनशॉट
समय B का स्क्रीनशॉट
हमने केवल वाक्य को संशोधित किया:n := open > close ? n + 1 : n
, केवल 1 को n में जोड़ें जब वर्तमान वास्तविक समय पट्टी एक नकारात्मक रेखा है (यानी, उद्घाटन मूल्य समापन मूल्य से अधिक है) । यह देखा जा सकता है कि पहले चार्ट (समय ए) में, क्योंकि उद्घाटन मूल्य उस समय समापन मूल्य (नकारात्मक रेखा) से अधिक था, n को 1 द्वारा संचित किया गया था, और चार्ट वक्र पर प्रदर्शित n का मूल्य 5 था। फिर बाजार बदल गया और मूल्य दूसरे चार्ट (समय बी) में दिखाए गए अनुसार अद्यतन किया गया। इस समय, उद्घाटन मूल्य समापन मूल्य (सकारात्मक रेखा) से कम है, और n मूल्य 1 द्वारा वृद्धि के बिना वापस रोल करता है। चार्ट में n की वक्र भी तुरंत फिर से तैयार की जाती है, और वक्र पर n का मूल्य 4 है। इसलिए, क्रॉसअप और वास्तविक समय पट्टी पर प्रदर्शित क्रॉसडाउन जैसे संकेत अनिश्चित हैं और बदल सकते हैं।
कार्यों में परिवर्तनीय संदर्भ
आइए पाइन भाषा फ़ंक्शन में चरों का एक साथ अध्ययन करें। पाइन ट्यूटोरियल पर कुछ विवरणों के अनुसार, फ़ंक्शन में चरों में फ़ंक्शन के बाहर के चरों से निम्नलिखित अंतर हैंः
पाइन फ़ंक्शन में उपयोग किए जाने वाले श्रृंखला चरों का इतिहास फ़ंक्शन के प्रत्येक क्रमिक कॉल के साथ बनाया जाता है। यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है जिस पर स्क्रिप्ट चलती है, तो इसका परिणाम फ़ंक्शन के स्थानीय ब्लॉक के अंदर और बाहर श्रृंखला के ऐतिहासिक मूल्यों के बीच विसंगति होगा। इसलिए, यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है, तो फ़ंक्शन के अंदर और बाहर संदर्भित श्रृंखला एक ही सूचकांक मूल्य के साथ एक ही ऐतिहासिक बिंदु को संदर्भित नहीं करेगी।
यह समझ में थोड़ा मुश्किल है? परवाह नहीं, हम यह एक परीक्षण कोड FMZ पर चल रहा के साथ पता चल जाएगाः
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
f(a) => a[1]
f2() => close[1]
oneBarInTwo = bar_index % 2 == 0
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
plot(close[2], title = "close[2]", color = color.red, overlay = true)
plot(close[1], title = "close[1]", color = color.green, overlay = true)
बैकटेस्ट चलाने का स्क्रीनशॉट
परीक्षण कोड अपेक्षाकृत सरल है, मुख्य रूप से दो विधियों द्वारा संदर्भित डेटा की जांच करने के लिए, अर्थात्ःf(a) => a[1]
औरf2() => close[1]
.
f(a) => a[1]
: पैरामीटर पास करने की विधि का उपयोग करें, फ़ंक्शन को लौटाता हैa[1]
finally.
f2() => close[1]
: अंतर्निहित चर का प्रयोग करेंclose
सीधे, और फ़ंक्शन लौटता है करने के लिएclose[1]
finally.
..[]
प्रतीक का उपयोग डेटा श्रृंखला चर के ऐतिहासिक मूल्य को संदर्भित करने के लिए किया जाता है, और बंद[1] वर्तमान समापन मूल्य से पहले बार पर समापन मूल्य डेटा को संदर्भित करता है। हमारा परीक्षण कोड चार्ट पर कुल 4 प्रकार के डेटा खींचता हैः
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
एक वर्ण f(close)
.
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
एक वर्ण f2()
.
plot(close[2], title = "close[2]", color = color.red, overlay = true)
एक रेखा खींचें, रंग लाल है, और खींची गई स्थिति (वाई-अक्ष पर) हैःclose[2]
, जो वर्तमान पट्टी (बाईं ओर 2 पट्टी गिनती) से पहले दूसरे पट्टी का समापन मूल्य है।
plot(close[1], title = "close[1]", color = color.green, overlay = true)
एक रेखा खींचें, रंग हरा है, और खींची गई स्थिति (वाई-अक्ष पर) हैःclose[1]
, जो वर्तमान पट्टी से पहले पहले पट्टी की समापन कीमत है (बाईं ओर 1 पट्टी गिनती) ।
यह रणनीति बैकटेस्टिंग के स्क्रीनशॉट से देखा जा सकता है कि हालांकि दोनों समारोहf(a) => a[1]
ए मार्कर और समारोह आकर्षित करने के लिए इस्तेमाल कियाf2() => close[1]
डेटा श्रृंखला पर ऐतिहासिक डेटा को संदर्भित करने के लिए बी मार्कर का उपयोग [1] करने के लिए उपयोग किया जाता है, चार्ट पर plot(close[2], title = "close[2]", color = color.red, overlay = true)
, रेखा खींचने के लिए उपयोग किए जाने वाले डेटा हैclose[2]
.
इसका कारण यह गणना करना है कि क्या K-लाइन बार के सूचकांक के माध्यम से bar_index
f(a) => a[1]
फ़ंक्शन द्वारा संदर्भित मान के समान नहीं होगाf2() => close[1]
यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है (भले ही वे दोनों एक ही सूचकांक जैसे [1] का उपयोग करें) ।
कुछ अंतर्निहित कार्यों को उनके परिणामों को सही ढंग से गणना करने के लिए प्रत्येक बार पर गणना की जानी चाहिए
इस स्थिति को एक सरल उदाहरण से स्पष्ट करने के लिए:
res = close > close[1] ? ta.barssince(close < close[1]) : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
हम फ़ंक्शन कॉल कोड लिखते हैंta.barssince(close < close[1])
तृतीयक संचालक मेंcondition ? value1 : value2
. यह ta.barssince फ़ंक्शन को केवल तब बुलाया जाता है जबclose > close[1]
. लेकिनta.barssince
समारोह पिछली बार के बाद से के लाइनों की संख्या की गणना करने के लिए हैclose < close[1]
जब ta.barssince फ़ंक्शन को बुलाया जाता है, तो यह हमेशा बंद > बंद होता है[1], अर्थात, वर्तमान समापन मूल्य पिछले बार के समापन मूल्य से अधिक होता है। जब ta.barssince फ़ंक्शन को बुलाया जाता है, तो बंद < बंद [1] की स्थिति स्थापित नहीं होती है, और कोई हालिया स्थिति नहीं होती है जहां यह पकड़ती है।
ta.barssince: जब बुलाया जाता है, तो फ़ंक्शन na लौटाता है यदि वर्तमान K-लाइन से पहले शर्त कभी पूरी नहीं हुई है.
जैसा कि चार्ट में दिखाया गया हैः
तो जब चार्ट तैयार किया जाता है, केवल डेटा के लिए एक मूल्य के साथ res चर (-1) तैयार किया जाता है।
इस समस्या से बचने के लिए, हम बस लेta.barssince(close < close[1])
फ़ंक्शन टर्नरी ऑपरेटर से बाहर कॉल करता है और इसे किसी भी संभव सशर्त शाखाओं के बाहर लिखता है, जिससे यह प्रत्येक K-लाइन बार पर गणना करता है।
a = ta.barssince(close < close[1])
res = close > close[1] ? a : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
पाइन भाषा में समय श्रृंखला की अवधारणा बहुत महत्वपूर्ण है, और यह एक अवधारणा है जिसे हमें पाइन भाषा सीखने पर समझना चाहिए। समय श्रृंखला एक प्रकार नहीं है बल्कि समय के साथ चर के निरंतर मानों को संग्रहीत करने के लिए एक बुनियादी संरचना है। हम जानते हैं कि पाइन स्क्रिप्ट चार्ट पर आधारित हैं, और चार्ट में प्रदर्शित सबसे बुनियादी सामग्री के-लाइन चार्ट है। समय श्रृंखला जहां प्रत्येक मूल्य के-लाइन बार के टाइमस्टैम्प से जुड़ा हुआ है।open
पाइन भाषा का एक अंतर्निहित चर है, और इसकी संरचना प्रत्येक के-लाइन बार के उद्घाटन मूल्य की समय श्रृंखला को संग्रहीत करना है। यह समझा जा सकता है कि पाइन भाषा का समय श्रृंखला संरचनाopen
वर्तमान K-लाइन चार्ट की शुरुआत में पहले बार से वर्तमान K-लाइन चार्ट के लिए जहां वर्तमान स्क्रिप्ट निष्पादित किया जाता है बार के लिए सभी K-लाइन बार के उद्घाटन कीमतों का प्रतिनिधित्व करता है। यदि वर्तमान K-लाइन चार्ट एक 5 मिनट की अवधि है, जब हम बोली (या उपयोग)open
पाइन रणनीति कोड में, यह K-लाइन बार की शुरुआती कीमत है जब रणनीति कोड वर्तमान में निष्पादित किया जाता है। यदि आप एक समय श्रृंखला में ऐतिहासिक मूल्यों का उल्लेख करना चाहते हैं, तो आपको[]
ऑपरेटर. जब पाइन रणनीति एक निश्चित K-लाइन बार पर निष्पादित किया जाता है, का उपयोगopen[1]
पिछले के-लाइन बार (यानी, पिछले के-लाइन अवधि की शुरुआती कीमत) के शुरुआती मूल्य का संदर्भ देने के लिए जो संदर्भित करता हैopen
समय श्रृंखला जिस पर इस K-लाइन बार वर्तमान में स्क्रिप्ट द्वारा निष्पादित किया जा रहा है.
समय श्रृंखला पर चर कंप्यूटिंग के लिए बहुत सुविधाजनक हैं
चलो अंतर्निहित फ़ंक्शन लेते हैंta.cum
उदाहरण के तौर परः
ta.cum
Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
ta.cum(source) → series float
RETURNS
Total sum series.
ARGUMENTS
source (series int/float)
SEE ALSO
math.sum
परीक्षण कोडः
v1 = 1
v2 = ta.cum(v1)
plot(v1, title="v1")
plot(v2, title="v2")
plot(bar_index+1, title="bar_index")
कई अंतर्निहित कार्य हैं जैसे किta.cum
जो समय श्रृंखलाओं पर डेटा को सीधे संसाधित कर सकते हैं. उदाहरण के लिए,ta.cum
प्रत्येक K-लाइन बार पर पारित चर के अनुरूप मूल्यों का संचय है, और अगले हम इसे समझने के लिए आसान बनाने के लिए एक चार्ट का उपयोग करें।
रणनीति संचालन प्रक्रिया | अंतर्निहित चर bar_index | v1 | v2 |
---|---|---|---|
रणनीति पहले के-लाइन बार पर चलता है | 0 | 1 | 1 |
रणनीति दूसरे के-लाइन बार पर चलता है | 1 | 1 | 2 |
रणनीति तीसरे के-लाइन बार पर चलता है | 2 | 1 | 3 |
… | … | … | … |
रणनीति N + 1 वीं K-लाइन बार पर चलता है | एन | 1 | एन+1 |
यह देखा जा सकता है कि v1, v2 और यहां तक कि bar_index सभी समय श्रृंखला संरचनाएं हैं, और प्रत्येक बार पर संबंधित डेटा है। चाहे परीक्षण कोड
चूंकि चर v1 प्रत्येक बार पर 1 है, जबta.cum(v1)
फ़ंक्शन पहले K-लाइन बार पर निष्पादित किया जाता है, वहाँ केवल पहले बार है, तो गणना परिणाम 1 है और चर v2 के लिए सौंपा जाता है।
कबta.cum(v1)
दूसरे के-लाइन बार पर निष्पादित किया जाता है, पहले से ही 2 के-लाइन बार हैं (पहले के अनुरूप अंतर्निहित चर bar_index 0, और अंतर्निहित चर bar_index के अनुरूप दूसरा 1 है), इसलिए गणना परिणाम 2 है, जो चर v2 को सौंपा गया है, और इसी तरह। वास्तव में यह देखा जा सकता है कि v2 चार्ट में K-लाइन बार की संख्या है, क्योंकि K-लाइन का सूचकांकbar_index
0 से बढ़ाया जाता है, तोbar_index + 1
वास्तव में के लाइन बार की संख्या है। चार्ट पर, हम यह भी देख सकते हैं कि लाइनोंv2
औरbar_index
वास्तव में ओवरलैप करते हैं।
इसी प्रकार, मैं भी उपयोग कर सकते हैंta.cum
वर्तमान चार्ट पर सभी बार्स के लिए समापन कीमतों के योग की गणना करने के लिए अंतर्निहित समारोह. सब मुझे क्या करने की जरूरत है इस तरह लिखने के लिए हैःta.cum(close)
, जब रणनीति वास्तविक समय पट्टी पर सबसे दाईं ओर चलाता है, परिणाम द्वारा गणना की जाती हैta.cum(close)
चार्ट पर सभी बार्स के समापन मूल्य का योग है (यदि यह सबसे दाईं ओर नहीं चलता है, तो यह केवल वर्तमान बार तक जमा होता है) ।
समय श्रृंखला पर चरों की गणना ऑपरेटरों का उपयोग करके भी की जा सकती है, जैसे कि कोडःta.sma(high - low, 14)
, अंतर्निहित चर घटाएंhigh
(के-लाइन बार का उच्चतम मूल्य) सेlow
(के-लाइन बार का सबसे कम मूल्य), और अंत में उपयोग करेंta.sma
औसत मूल्य की गणना करने के लिए कार्य।
फ़ंक्शन कॉल का परिणाम भी समय श्रृंखला में मानों के निशान छोड़ देगा.
v1 = ta.highest(high, 10)[1]
v2 = ta.highest(high[1], 10)
plot(v1, title="v1", overlay=true)
plot(v2, title="v2", overlay=true)
परीक्षण कोड बैकटेस्टिंग के दौरान चलाया जाता है, और यह देखा जा सकता है किv1
औरv2
फ़ंक्शन कॉल द्वारा गणना किया गया परिणाम समय श्रृंखला में मान के निशान छोड़ देगा, जैसे किta.highest(high, 10)
कोड मेंta.highest(high, 10)[1]
. फ़ंक्शन कॉल द्वारा गणना परिणाम भी उपयोग कर सकते हैं [1] अपने ऐतिहासिक मूल्य को संदर्भित करने के लिए.ta.highest(high, 10)
वर्तमान पट्टी के पिछले पट्टी के अनुरूप, गणना का परिणाम हैta.highest(high[1], 10)
तो.ta.highest(high[1], 10)
औरta.highest(high, 10)[1]
बिल्कुल समान हैं।
किसी अन्य ड्राइंग फ़ंक्शन का उपयोग करके जानकारी सत्यापन आउटपुट करें:
a = ta.highest(close, 10)[1]
b = ta.highest(close[1], 10)
plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
हम देख सकते हैं कि समय श्रृंखला में चर a और चर b के मान संबंधित Bars के ऊपर और नीचे प्रदर्शित होते हैं। हम सीखने की प्रक्रिया के दौरान इस ड्राइंग कोड को रख सकते हैं, क्योंकि हमें अक्सर बैकटेस्टिंग और प्रयोग के दौरान अवलोकन के लिए चार्ट पर जानकारी आउटपुट करने की आवश्यकता हो सकती है।
ट्यूटोरियल के आरंभिक भाग में, हमने एफएमजेड और ट्रेडिंग व्यू पर पाइन भाषा का उपयोग करने में कुछ अंतरों का सारांश दिया है। जब आप एफएमजेड पर पाइन कोड लिखते हैं, तो आप संस्करण संख्या को छोड़ सकते हैं,indicator()
, strategy()
, औरlibrary()
वर्तमान में समर्थित नहीं है। बेशक, पाइन स्क्रिप्ट के पुराने संस्करणों के साथ संगत होने के लिए, रणनीतियाँ जैसेः//@version=5
, indicator()
, strategy()
कुछ रणनीति सेटिंग्स भी में पैरामीटर पारित करके सेट किया जा सकता हैstrategy()
function.
<version>
<declaration_statement>
<code>
..<version>
संस्करण नियंत्रण जानकारी को छोड़ दिया जा सकता है।
पाइन भाषा का प्रयोग करता है//
एक पंक्ति के टिप्पणी प्रतीक के रूप में, क्योंकि पाइन भाषा में एक बहु-पंक्ति टिप्पणी प्रतीक नहीं है। एफएमजेड टिप्पणी प्रतीक का विस्तार करता है/**/
बहु-पंक्ति टिप्पणियों के लिए।
स्क्रिप्ट में जो पंक्तियाँ टिप्पणी या संकलक निर्देश नहीं हैं, वे कथन हैं, जो स्क्रिप्ट के एल्गोरिथ्म को लागू करते हैं। एक कथन इनमें से एक सामग्री हो सकती है।
if
, for
, while
याswitch
संरचनाबयानों को विभिन्न तरीकों से व्यवस्थित किया जा सकता है
space
या ```tab` (टैब कुंजी). उनका पहला वर्ण भी पंक्ति का पहला वर्ण होना चाहिए। पहली स्थिति से शुरू होने वाली पंक्तियाँ, परिभाषा के अनुसार, स्क्रिप्ट के वैश्विक दायरे का हिस्सा बन जाती हैं।local block
एक स्थानीय ब्लॉक को एक टैब या चार रिक्त स्थानों से इंडेंट किया जाना चाहिए (अन्यथा, इसे पिछली पंक्ति के संबद्ध कोड के रूप में पार्स किया जाएगा, अर्थात, कोड की पिछली पंक्ति की निरंतर सामग्री माना जाएगा), और प्रत्येक स्थानीय ब्लॉक एक अलग स्थानीय दायरे को परिभाषित करता है।उदाहरण के लिए, इसमें तीन स्थानीय ब्लॉक शामिल हैं, एक कस्टम फ़ंक्शन घोषणा में, और दो चर घोषणा में यदि संरचना का उपयोग करके, निम्नानुसारः
indicator("", "", true) // declaration statement (global scope), can be omitted
barIsUp() => // function declaration (global scope)
close > open // local block (local scope)
plotColor = if barIsUp() // variable declaration (global scope)
color.green // local block (local scope)
else
color.red // local block (local scope)
runtime.log("color", color = plotColor) // Call a built-in function to output the log (global scope)
लंबी रेखाओं को कई रेखाओं पर विभाजित किया जा सकता है, या
a = open + high + low + close
इसे इस प्रकार से पैक किया जा सकता है (ध्यान दें कि प्रति पंक्ति में इंद्रधनुष वाले रिक्त स्थानों की संख्या 4 का गुणक नहीं हो सकती):
a = open +
high +
low +
close
एक लंबा प्लॉट ((() कॉल को इस तरह से लपेटा जा सकता हैः
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid daily level closing price data series for the current trading pair
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 240-minute level closing price data series for the current trading pair
plot(ta.correlation(close, open, 100), // line-long plot() calls can be wrapped
color = color.new(color.purple, 40),
style = plot.style_area,
trackprice = true)
उपयोगकर्ता-परिभाषित फ़ंक्शन घोषणाओं में कथन भी लपेटा जा सकता है। हालांकि, चूंकि एक स्थानीय ब्लॉक को व्याकरण में एक इंडेंट से शुरू होना चाहिए (4 रिक्त स्थान या 1 टैब), जब इसे अगली पंक्ति पर विभाजित किया जाता है, तो कथन की निरंतरता एक से अधिक इंडेंट से शुरू होनी चाहिए (अंतर के 4 गुणकों के बराबर नहीं) । उदाहरण के लिएः
test(c, o) =>
ret = c > o ?
(c > o+5000 ?
1 :
0):
(c < o-5000 ?
-1 :
0)
a = test(close, open)
plot(a, title="a")
चरों को पहचानने से पहले, हमें पहले
(A-Z)
या छोटा अक्षर(a-z)
अक्षर या रेखांकित(_)
मार्कर के पहले अक्षर के रूप में।जैसे कि निम्नलिखित नामित मार्कर:
fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown // Wrong naming! It used a numeric character as the leading character of the marker
अधिकांश प्रोग्रामिंग भाषाओं की तरह, पाइन भाषा में लेखन सुझाव भी हैं। पहचानकर्ताओं का नामकरण करते समय आम तौर पर यह अनुशंसा की जाती हैः
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// name functions
zeroOne(boolValue) => boolValue ? 1 : 0
ऑपरेटर कुछ ऑपरेशन प्रतीक हैं जो प्रोग्रामिंग भाषाओं में अभिव्यक्ति बनाने के लिए उपयोग किए जाते हैं, और अभिव्यक्ति कुछ कंप्यूटेशनल उद्देश्यों के लिए डिज़ाइन किए गए कंप्यूटेशनल नियम हैं जब हम रणनीतियाँ लिखते हैं। पाइन भाषा में ऑपरेटरों को फ़ंक्शन के अनुसार वर्गीकृत किया जाता हैः
असाइनमेंट ऑपरेटर, अंकगणितीय ऑपरेटर, तुलना ऑपरेटर, तार्किक ऑपरेटर,? :
तृतीयक संचालक,[]
ऐतिहासिक संदर्भ संचालक।
अंकगणितीय संचालक लेना*
उदाहरण के रूप में, यह ट्रेडिंग व्यू पर पाइन भाषा ऑपरेटर के रिटर्न परिणाम के कारण होने वाली प्रकार समस्या से अलग है। निम्नलिखित परीक्षण कोड प्रदान किया गया हैः
//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength) // Compilation error!
plot(ma)
ट्रेडिंग दृश्य पर इस स्क्रिप्ट को निष्पादित करते समय, एक संकलन त्रुटि होगी। कारण यह है कि गुणा करने के बादadjustedLength = lenInput * factor
, परिणाम हैseries int
प्रकार (श्रृंखला), लेकिन समारोह के दूसरे पैरामीटरta.ema
लेकिन एफएमजेड पर ऐसे कोई सख्त प्रतिबंध नहीं हैं, उपरोक्त कोड सामान्य रूप से चलाया जा सकता है।
आइए विभिन्न ऑपरेटरों के उपयोग को एक साथ देखें।
असाइनमेंट ऑपरेटर के 2 प्रकार हैंः=
, :=
, जो हम ट्यूटोरियल के शुरुआती भाग में कई उदाहरणों में देखा है.
..=
ऑपरेटर का उपयोग एक चर को एक मान सौंपने के लिए किया जाता है जब यह आरंभिक या घोषित किया जाता है। चर जो आरंभिक, घोषित और आरंभिक के साथ असाइन किए जाते हैं=
प्रत्येक बाद के बार पर उस मूल्य के साथ शुरू होगा. ये वैध चर घोषणाएं हैंः
a = close // Use built-in variables to assign values to a
b = 10000 // Use numerical assignment
c = "test" // Use string assignment
d = color.green // Use color value assignment
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)
ध्यान दें कि असाइनमेंट स्टेटमेंटa = close
, प्रत्येक बार पर चर a बार का वर्तमान समापन मूल्य (बंद) है। अन्य चरb
, c
, d
अपरिवर्तित हैं और एफएमजेड पर बैकटेस्ट सिस्टम में परीक्षण किया जा सकता है, और परिणाम चार्ट पर देखे जा सकते हैं।
:=
इसका प्रयोग मौजूदा चरों के लिए मूल्यों को फिर से असाइन करने के लिए किया जाता है।:=
ऑपरेटर का उपयोग घोषित और आरंभिकरण किए गए चर के मानों को संशोधित करने के लिए किया जाता है।
यदि हम:=
ऑपरेटर एक अनइनिशियल या घोषित चर के लिए एक मान असाइन करने के लिए, यह एक त्रुटि का कारण होगा, उदाहरण के लिएः
a := 0
इसलिए,:=
असाइनमेंट ऑपरेटर का उपयोग आमतौर पर मौजूदा चर को फिर से असाइन करने के लिए किया जाता है, उदाहरण के लिएः
a = close > open
b = 0
if a
b := b + 1
plot(b)
यह देखते हुए किclose > open
(यानी वर्तमान BAR एक सकारात्मक रेखा है), चर एक सच है। यदि कथन के स्थानीय ब्लॉक में कोडb := b + 1
निष्पादित किया जाता है, और असाइनमेंट ऑपरेटर:=
b को फिर से आवंटित करने के लिए प्रयोग किया जाता है, और 1 जोड़ा जाता है। फिर हम चार्ट पर समय श्रृंखला के प्रत्येक BAR पर चर b का मूल्य आकर्षित करने के लिए प्लॉट फ़ंक्शन का उपयोग करते हैं, और उन्हें एक रेखा में जोड़ते हैं।
क्या हमें लगता है कि जब एक सकारात्मक रेखा BAR दिखाई देती है, तो b 1 से जमा होता रहेगा? निश्चित रूप से नहीं, यहां हम किसी भी कीवर्ड पदनाम का उपयोग किए बिना चर b को 0 के रूप में घोषित और आरंभ करते हैं। यह वाक्यb=0
प्रत्येक बार पर निष्पादित किया जाता है, तो हम देख सकते हैं कि इस कोड का परिणाम 0 के लिए b चर को रीसेट करने के लिए हर बार है, यदि चर एक सच है, कि है, के साथ लाइन में हैclose > open
, तो b को 1 से बढ़ाया जाएगा जब कोड इस दौर में निष्पादित किया जाता है, और b 1 है जब प्लॉट फ़ंक्शन ड्रॉ करता है, लेकिन b को अगले दौर में कोड निष्पादित होने पर 0 में फिर से असाइन किया जाता है। यह वह जगह भी है जहां पाइन भाषा के शुरुआती फंसने के लिए प्रवण होते हैं।
जब यह असाइनमेंट ऑपरेटरों की बात आती है, तो हमें दो कीवर्ड पर विस्तार करना चाहिएःvar
, varip
विर
वास्तव में, हमने इस कीवर्ड को पिछले ट्यूटोरियल में देखा और इस्तेमाल किया है, लेकिन हमने उस समय विस्तार से चर्चा नहीं की। आइए पहले इस कीवर्ड के विवरण को देखेंः
var एक कीवर्ड है जिसका उपयोग चर को आवंटित करने और एक बार आरंभ करने के लिए किया जाता है। सामान्य तौर पर, चर असाइनमेंट व्याकरण जिसमें कीवर्ड var नहीं होता है, प्रत्येक बार डेटा अपडेट होने पर चर
s मान को अधिलेखित कर देता है। इसके विपरीत, जब चर को कीवर्ड var का उपयोग करके असाइन किया जाता है, तो वे डेटा अपडेट के बावजूद राज्य बनाए रख सकते हैं।
हम अभी भी इस उदाहरण का उपयोग करते हैं, लेकिन हम का उपयोगvar
यहाँ b को मान निर्दिष्ट करते समय कीवर्ड।
a = close > open
var b = 0
if a
b := b + 1
plot(b)
..var
कीवर्ड चर b को केवल प्रारंभिक असाइनमेंट करने की अनुमति देता है, और फिर यह हर बार रणनीति तर्क निष्पादित होने पर b को 0 पर रीसेट नहीं करेगा, इसलिए यह रनटाइम पर खींची गई रेखा से देखा जा सकता है कि b सकारात्मक रेखा BARs की संख्या है जो तब दिखाई दी है जब वर्तमान K रेखा BAR बैकटेस्ट किया गया था।
var द्वारा घोषित चर न केवल वैश्विक दायरे में, बल्कि कोड ब्लॉक में भी लिखे जा सकते हैं, जैसे कि यह उदाहरणः
strategy(overlay=true)
var a = close
var b = 0.0
var c = 0.0
var green_bars_count = 0
if close > open
var x = close
b := x
green_bars_count := green_bars_count + 1
if green_bars_count >= 10
var y = close
c := y
plot(a, title = "a")
plot(b, title = "b")
plot(c, title = "c")
चर
विविधता
हम खोजशब्द देखते हैंvarip
पहली बार, हम इस कीवर्ड के विवरण को देख सकते हैंः
varp (var intrabar persist) चर को असाइन करने और एक बार आरंभ करने के लिए एक कीवर्ड है। यह var कीवर्ड के समान है, लेकिन वास्तविक समय के-लाइन अपडेट के दौरान varip के साथ घोषित चर अपने मानों को बनाए रखते हैं।
क्या यह समझना मुश्किल है? इससे कोई फर्क नहीं पड़ता, हम इसे एक उदाहरण के माध्यम से समझाते हैं, यह समझना आसान है।
strategy(overlay=true)
// test var varip
var i = 0
varip ii = 0
// Print the i and ii changed in each round of the strategy logic on the chart
plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)
// Increment i and ii by 1 for each round of logic execution
i := i + 1
ii := ii + 1
इस परीक्षण कोड में
पट्टी मॉडलः
क्या आपको याद है कि रणनीति निष्पादन हम पहले समझाया ऐतिहासिक बार चरण और वास्तविक समय बार चरण में विभाजित है? बार मॉडल में, ऐतिहासिक के लाइन चरण, चरi
, ii
में घोषितvar
, varip
रणनीति कोड के निष्पादन के प्रत्येक दौर में वृद्धिशील संचालन करें। इसलिए यह देखा जा सकता है कि बैकटेस्ट परिणाम के के-लाइन बार पर प्रदर्शित संख्याओं को एक-एक करके बढ़ाया जाता है। जब ऐतिहासिक के-लाइन चरण समाप्त होता है, तो वास्तविक समय के-लाइन चरण शुरू होता है। var और varip द्वारा घोषित चर अलग-अलग परिवर्तनों से गुजरना शुरू करते हैं। क्योंकि यह बार मॉडल है, इसलिए रणनीति कोड एक बार निष्पादित किया जाएगा।i := i + 1
औरii := ii + 1
एक बार निष्पादित किया जाएगा। अंतर यह है कि ii हर बार संशोधित किया जाता है। हालांकि i हर बार संशोधित किया जाता है, पिछले मूल्य को बहाल किया जाएगा जब रणनीति तर्क अगले दौर में निष्पादित किया जाता है (रोलबैक तंत्र याद रखें जिसे हमने पिछले अध्याय में समझाया था?), और वर्तमान के-लाइन BAR पूरा होने तक i का मूल्य अपडेट नहीं किया जाएगा (यानी, पिछले मूल्य को बहाल नहीं किया जाएगा जब रणनीति तर्क अगले दौर में निष्पादित किया जाता है) । इसलिए यह देखा जा सकता है कि चर i अभी भी प्रत्येक BAR के लिए 1 से बढ़ाया जाता है। लेकिन चर ii प्रत्येक BAR के लिए कई बार जमा होता है।
टिक मॉडलः चूंकि टिक मॉडल प्रति K-लाइन BAR में केवल एक बार रणनीति तर्क निष्पादित करता है। इसलिए समापन मूल्य मॉडल में, var और varip द्वारा घोषित चर ऐतिहासिक K-लाइन चरण और वास्तविक समय K-लाइन चरण के दौरान प्रत्येक K-लाइन BAR के लिए 1 से बढ़ते हुए उपरोक्त उदाहरण में बिल्कुल समान व्यवहार करते हैं।
ऑपरेटर | विवरण |
---|---|
+ | जोड़ना |
- | घटाव |
* | गुणन |
/ | डिवीजन |
% | मॉड्यूल |
..+
और-
अन्य अंकगणितीय संचालकों का उपयोग केवल द्विआधारी संचालकों के रूप में किया जा सकता है और यह एक त्रुटि रिपोर्ट करेगा यदि इसका उपयोग युनरी संचालकों के रूप में किया गया था।
+
, गणना का परिणाम एक स्ट्रिंग है, मान स्ट्रिंग रूप में परिवर्तित किया जाएगा, और फिर स्ट्रिंग एक साथ सिलाई कर रहे हैं। यदि यह अन्य अंकगणितीय संचालक है, यह स्ट्रिंग को मान में परिवर्तित करने का प्रयास करेगा और फिर ऑपरेशन पर ले जाएगा।a = 1 + 1
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN
एफएमजेड पर पाइन भाषा ट्रेडिंग व्यू पर पाइन भाषा से थोड़ा अलग है, एफएमजेड पर पाइन भाषा चर प्रकारों के बारे में बहुत सख्त नहीं है। उदाहरण के लिएः
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
यह FMZ पर काम करता है, लेकिन यह ट्रेडिंग व्यू पर एक प्रकार की त्रुटि की रिपोर्ट करता है। यदि अंकगणितीय ऑपरेटर के दोनों ऑपरेड स्ट्रिंग हैं, तो सिस्टम स्ट्रिंग को संख्यात्मक मानों में परिवर्तित करता है और फिर उन्हें गणना करता है। यदि एक गैर-संख्यात्मक स्ट्रिंग की गणना नहीं की जा सकती है, तो सिस्टम ऑपरेशन का परिणाम शून्य मान है।
तुलना ऑपरेटर सभी बाइनरी ऑपरेटर हैं।
ऑपरेटर | विवरण |
---|---|
< | < |
> | > |
<= | <= |
>= | >= |
== | == |
!= | != |
परीक्षण उदाहरणः
a = 1 > 2
b = 1 < 2
c = "1" <= 2
d = "1" >= 2
e = 1 == 1
f = 2 != 1
g = open > close
h = na > 1
i = 1 > na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false
जैसा कि हम देख सकते हैं, तुलना संचालक का उपयोग करने के लिए बहुत आसान है, लेकिन यह भी संचालक हम सबसे अधिक उपयोग करते हैं जब रणनीतियों लिखने के लिए है। दोनों संख्यात्मक मान और अंतर्निहित चर तुलना की जा सकती है, जैसे किclose
, open
आदि।
ऑपरेटर के साथ के रूप में, FMZ और ट्रेडिंग व्यू के बीच पाइन भाषा के बारे में एक अंतर है। FMZ प्रकार के लिए विशेष रूप से सख्त आवश्यकताओं नहीं है, इसलिए, इस तरह के बयानd = "1" >= 2
एफएमजेड पर कोई त्रुटि रिपोर्ट नहीं करेगा, और इसे पहले स्ट्रिंग को मान में परिवर्तित करके और फिर ऑपरेशन की तुलना करके निष्पादित किया जाएगा। ट्रेडिंग व्यू पर, यह त्रुटि रिपोर्ट करेगा।
ऑपरेटर | कोड चिह्न | विवरण |
---|---|---|
नहीं | नहीं | यूनरी ऑपरेटर, ऑपरेशन नहीं |
और | और | द्विआधारी संचालक और संचालन |
या | या | बाइनरी ऑपरेटर या ऑपरेशन |
जब यह तार्किक संचालकों के लिए आता है, तो हम सही मूल्य तालिकाओं के बारे में बात करनी चाहिए. वही हम हाई स्कूल में सीखा है, यहाँ हम सिर्फ परीक्षण और हमारे बैकटेस्टिंग प्रणाली में सीखनेः
a = 1 == 1 // An expression formed by using comparison operators, the result is a Boolean value
b = 1 != 1
c = not b // Logical not operators
d = not a // Logical not operators
runtime.log("test the logical operator:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)
runtime.log("test the logical operator:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)
runtime.error("stop")
संदेशों को ओवरप्रिंट नहीं करने के लिए, हम एक त्रुटि फेंक के साथruntime.error("stop")
और इसे एक बार प्रिंट करने के बाद रोक दें। उसके बाद, हम आउटपुट जानकारी का निरीक्षण कर सकते हैं, और हम पा सकते हैं कि मुद्रित सामग्री वास्तव में वास्तविक मूल्य तालिका के समान है।
तृतीयक संचालक का प्रयोग करने वाले तृतीयक अभिव्यक्ति? :
संचालकों के साथ संयुक्तcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
हमने उन्हें पिछले पाठों में भी इस्तेमाल किया है। तथाकथित तृतीयक अभिव्यक्ति, तृतीयक ऑपरेटर का अर्थ है कि इसमें तीन ऑपरेड हैं।
मेंcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
, condition
यदि यह सच है, तो अभिव्यक्ति का मान हैःvalueWhenConditionIsTrue
यदिcondition
गलत है, तो अभिव्यक्ति का मूल्य हैvalueWhenConditionIsFalse
.
एक सुविधाजनक प्रदर्शन का उदाहरण, हालांकि व्यावहारिक उपयोग का बहुत कमः
a = close > open
b = a ? "positive line" : "negative line"
c = not a ? "negative line" : "positive line"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
अगर हम एक डोजी का सामना करते हैं तो क्या करें? इससे कोई फर्क नहीं पड़ता! टर्नरी एक्सप्रेशंस को भी नेस्टेड किया जा सकता है, जैसा कि हमने पिछले ट्यूटोरियल में किया था।
a = close > open
b = a ? math.abs(close-open) > 30 ? "positive line" : "doji" : math.abs(close-open) > 30 ? "negative line" : "doji"
c = not a ? math.abs(close-open) > 30 ? "negative line" : "doji" : math.abs(close-open) > 30 ? "positive line" : "doji"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
दरअसल, यह प्रतिस्थापन के बराबर है।valueWhenConditionIsTrue
औरvalueWhenConditionIsFalse
मेंcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
एक और तृतीयक अभिव्यक्ति के साथ।
इतिहास संचालक का प्रयोग करें[]
एक समय श्रृंखला पर ऐतिहासिक मूल्यों का संदर्भ देने के लिए. इन ऐतिहासिक मूल्यों वर्तमान K-लाइन पट्टी से पहले K-लाइन पट्टी पर चर के मूल्य हैं जब स्क्रिप्ट चल रहा था.[]
ऑपरेटर का प्रयोग चर, अभिव्यक्ति और फ़ंक्शन कॉल के बाद किया जाता है.[]
वर्ग कोष्ठक वर्तमान K-लाइन BAR से संदर्भित करने के लिए हम चाहते हैं ऐतिहासिक डेटा के ऑफसेट है. उदाहरण के लिए अगर मैं पिछले K-लाइन BAR के समापन मूल्य उद्धृत करना चाहते हैं, हम इसे के रूप में लिखते हैंःclose[1]
.
हमने पिछले पाठों में कुछ इस तरह देखा हैः
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
..[]
ऑपरेटर का उपयोग एक ही मान पर केवल एक बार किया जा सकता है, इसलिए इसे इस तरह से लिखना गलत है, और एक त्रुटि की सूचना दी जाएगीः
a = close[1][2] // error
यहाँ, कोई कह सकता है कि ऑपरेटर[]
श्रृंखला संरचना के लिए प्रयोग किया जाता है, ऐसा लगता है कि श्रृंखला संरचना (श्रृंखला) सरणी के समान है!
आइए पाइन भाषा में श्रृंखला और सरणी के बीच अंतर को स्पष्ट करने के लिए एक उदाहरण का उपयोग करें।
strategy("test", overlay=true)
a = close
b = close[1]
c = b[1]
plot(a, title="a")
plot(b, title="b")
plot(c, title="c")
a = close[1][2]
त्रुटि की सूचना देगा, लेकिनः
b = close[1]
c = b[1]
लेकिन अगर अलग से लिखा है, यह एक त्रुटि रिपोर्ट नहीं करेगा. अगर हम इसे सामान्य सरणी के अनुसार समझते हैं, के असाइनमेंट के बादb = close [1]
, b एक मान होना चाहिए, लेकिनc = b[1]
, b का उपयोग इतिहास संचालक का उपयोग करके ऐतिहासिक मान को फिर से संदर्भित करने के लिए किया जा सकता है। यह देखा जा सकता है कि पाइन भाषा में श्रृंखला की अवधारणा एक सरणी के रूप में सरल नहीं है। इसे बंद (बी को सौंपा गया) के अंतिम पट्टी पर ऐतिहासिक मान के रूप में समझा जा सकता है, b भी एक समय श्रृंखला संरचना (समय श्रृंखला) है, और इसकी h