आविष्कारक मात्रात्मक PINE भाषा परिचय ट्यूटोरियल
वीडियो ट्यूटोरियलः
ट्रेडिंग व्यू का उपयोग करके पाइन भाषा से लेकर क्वांटम तक - पाइन भाषा की शुरुआत
आविष्कारक क्वांटिटेटिव ट्रेडिंग प्लेटफॉर्म पाइन भाषा लेखन रणनीति का समर्थन करता है, पाइन भाषा रणनीति का समर्थन करता है और पाइन भाषा के निचले संस्करणों के साथ संगतता प्रदान करता है।रणनीति स्क्वायरइस लेख में, हम पिन रणनीतियों (स्क्रिप्ट) के बारे में बात करेंगे।
FMZ केवल पाइन भाषा का समर्थन नहीं करता है, बल्कि पाइन भाषा की शक्तिशाली चित्र सुविधाओं का भी समर्थन करता है। एफएमजेड प्लेटफॉर्म पर विभिन्न सुविधाएं, समृद्ध व्यावहारिक उपकरण, कुशल और आसान प्रबंधन, पाइन रणनीति की व्यावहारिकता को और बढ़ाता है। पाइन भाषा के अनुकूलता के आधार पर एफएमजेड, पाइन भाषा के लिए कुछ हद तक विस्तार, अनुकूलन और कटौती करता है। आधिकारिक रूप से ट्यूटोरियल में प्रवेश करने से पहले, आइए देखें कि एफएमजेड पर पाइन भाषा और मूल पाइन में क्या बदलाव हुए हैं।
कुछ स्पष्ट अंतरों को संक्षेप में प्रस्तुत करने के लिएः
-
1। एफएमजेड पर पाइन नीति, कोड के प्रारंभ में संस्करण चिह्न
//@versionऔर कोड के साथ शुरूstrategy、indicatorबयानों को लिखने के लिए बाध्य नहीं किया गया है, एफएमजेड ने इसे अभी तक समर्थन नहीं दिया है।importआयात करेंlibraryसमारोह।शायद कुछ रणनीतियों को इस तरह लिखा हुआ देखा होगाः
pine//@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)या यह लिखा गया हैः
pine//@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)एफएमजेड पर संक्षिप्त रूप मेंः
pinesrc = 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)याः
pinelongCondition = 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) -
2। नीति (स्क्रिप्ट) कुछ लेनदेन से संबंधित सेटिंग्स एफएमजेड नीति इंटरफ़ेस पर "पाइन भाषा लेनदेन कक्षा भंडार" पैरामीटर द्वारा सेट की जाती हैं।
-
समापन मूल्य मॉडल और वास्तविक समय मूल्य मॉडल
ट्रेडिंग दृश्य पर, हम कर सकते हैंstrategyफ़ंक्शन काcalc_on_every_tickपैरामीटर सेट करने के लिए नीति स्क्रिप्ट वास्तविक समय में नीति तर्क निष्पादित करने के लिए हर बार जब कीमत बदलती है, इस समयcalc_on_every_tickपैरामीटर सेट किया जाना चाहिएtrueडिफ़ॉल्टcalc_on_every_tickपैरामीटर हैfalseजब रणनीति के वर्तमान K लाइन BAR पूरी तरह से समाप्त हो जाती है, तो रणनीति तर्क को निष्पादित किया जाता है।
एफएमजेड पर, यह "पाइन भाषा लेन-देन कक्षा भंडार" टेम्पलेट के पैरामीटर के माध्यम से सेट किया गया है। -
रणनीति निष्पादन के समय मूल्य, नीचे आदेश मात्रा जैसे संख्यात्मक परिशुद्धता नियंत्रण को FMZ पर निर्दिष्ट करने की आवश्यकता है
ट्रेडिंग दृश्य पर, चूंकि केवल एनालॉग परीक्षण किया जा सकता है, इसलिए वास्तविक समय पर आदेश की सटीकता का कोई सवाल नहीं है। एफएमजेड पर, पिन रणनीति को वास्तविक समय पर चलाया जा सकता है। तो रणनीति को व्यापार की किस्मों की कीमत सटीकता और आदेश मात्रा सटीकता को निर्दिष्ट करने के लिए लचीलापन की आवश्यकता होती है। इन सटीकता सेटिंग्स से संबंधित डेटा के छोटे अंकों को नियंत्रित करने की आवश्यकता होती है, जिससे डेटा एक्सचेंज रिपोर्टिंग आवश्यकताओं के अनुरूप नहीं होता है और इसलिए आदेश नहीं दिया जा सकता है। -
फ्यूचर कॉन्ट्रैक्ट कोड
एफएमजेड पर ट्रेडिंग किस्म यदि यह अनुबंध है, तो 2 गुण हैं। क्रमशः "ट्रेडिंग जोड़ी" और "अनुबंध कोड", रीयल-टाइम और रिटर्न्स पर स्पष्ट रूप से सेट करने के अलावा, ट्रेडिंग जोड़ी को "पाइन भाषा ट्रेडिंग क्लासरूम" टेम्पलेट के पैरामीटर "रेंज कोड" में सेट करने की आवश्यकता होती है। उदाहरण के लिए, स्थायी अनुबंध भरेंswap, अनुबंध कोड यह देखने के लिए कि क्या एक्सचेंजों में इस तरह के अनुबंध हैं। उदाहरण के लिए, सभी तिमाही अनुबंधों के लिए, यहां भरा जा सकता हैquarterये अनुबंध कोड FMZ के जावास्क्रिप्ट / पायथन / सी ++ भाषा एपीआई दस्तावेज पर परिभाषित वायदा अनुबंध कोड के अनुरूप हैं।
अन्य सेटिंग्स जैसे कि न्यूनतम आदेश मात्रा, डिफ़ॉल्ट आदेश मात्रा आदि के बारे में पाइन भाषा के दस्तावेज़ में देखें।"पाइन लैंग्वेज एक्सचेंज क्लासरूम"पैरामीटर का परिचय
-
-
3、
runtime.debug、runtime.log、runtime.errorFMZ एक्सटेंशन फ़ंक्शन को डिबगिंग के लिए प्रयोग किया जाता है।FMZ प्लेटफॉर्म पर डीबगिंग के लिए 3 फ़ंक्शंस जोड़े गए हैं।
-
runtime.debug: यह फ़ंक्शन आम तौर पर कंसोल पर चर जानकारी को प्रिंट करने के लिए उपयोग नहीं किया जाता है। -
runtime.log: लॉग में आउटपुट सामग्री <unk> FMZ PINE भाषा के लिए विशेष फ़ंक्शन <unk>pineruntime.log(1, 2, 3, close, high, ...),可以传多个参数。 -
runtime.error: कॉल करने पर, यह एक रनटाइम त्रुटि का कारण बनता है, और संदेश पैरामीटर में निर्दिष्ट त्रुटि संदेश के साथ।pineruntime.error(message)
-
-
4। आंशिक रूप से विस्तारित चित्र फ़ंक्शन
overlayपैरामीटरFMZ पर पिन भाषा, चित्र फ़ंक्शन
plot、plotshape、plotcharऔर अधिकoverlayपैरामीटर समर्थन, जो चित्रों को मुख्य या उप-चित्रों में निर्दिष्ट करने की अनुमति देता है.overlayस्थापित करनाtrueमुख्य चित्र में चित्रितfalseएफएमजेड पर पाइन रणनीति चलाने के लिए मुख्य और उप-चित्रों को एक साथ चित्रित किया जा सकता है। -
5、
syminfo.mintickअंतर्निहित चर के लिएsyminfo.mintickअंतर्निहित चर को वर्तमान किस्मों के न्यूनतम माप मान के रूप में परिभाषित किया गया है। FMZ मेंपक्का प्रस्ताव/बैकटेस्टिंगमूल्य निर्धारण मुद्रा की सटीकता 2 है, जो कि मूल्य निर्धारण मुद्रा की सटीकता 2 है, जो कि मूल्य निर्धारण के लिए एक छोटी संख्या के दूसरे स्थान पर सटीक है, और इस समय मूल्य में न्यूनतम परिवर्तन 0.01 है।syminfo.mintickतो यह 0.01 होगा. -
6। एफएमजेड पिन स्क्रिप्ट में औसत मूल्य प्रसंस्करण शुल्क सहित है
उदाहरण के लिएः ऑर्डर मूल्य 8000 है, बिक्री दिशा, मात्रा 1 हाथ ((एक, शीट), औसत मूल्य 8000 से कम नहीं है ((लागत में प्रसंस्करण शुल्क शामिल है)) ।
पाइन भाषा का आधार
पाइन भाषा की मूल बातें सीखना शुरू करते समय, हम शायद कुछ उदाहरणों में निर्देशों, कोड व्याकरण से परिचित नहीं होंगे। यह कोई फर्क नहीं पड़ता कि हम क्या नहीं समझते हैं, हम पहले अवधारणाओं से परिचित हो सकते हैं, परीक्षण के उद्देश्य को समझ सकते हैं, या एफएमजेड के पाइन भाषा के दस्तावेज को देख सकते हैं। फिर ट्यूटोरियल का पालन करें। विभिन्न व्याकरण, निर्देश, फ़ंक्शन, अंतर्निहित चर से परिचित होने के लिए कदम-दर-चरण कदम।
मॉडल निष्पादन
पाइन भाषा की शुरुआत में, पाइन भाषा की स्क्रिप्ट निष्पादन प्रक्रिया जैसे संबंधित अवधारणाओं को समझना बहुत आवश्यक है। पाइन भाषा की रणनीति चार्ट पर आधारित है, जिसे गणना और संचालन की एक श्रृंखला के रूप में समझा जा सकता है, जो चार्ट पर पहले से लोड किए गए डेटा से शुरू होता है। चार्ट पर प्रारंभिक लोड की गई डेटा की मात्रा सीमित है। रीयल-टाइम में आमतौर पर यह डेटा सीमा एक्सचेंज इंटरफेस पर लौटे अधिकतम डेटा की मात्रा के आधार पर निर्धारित की जाती है, और समय-सीमा डेटा सीमा को रीमेटिंग सिस्टम डेटा स्रोत द्वारा प्रदान किए गए डेटा के आधार पर निर्धारित किया जाता है। चार्ट पर सबसे बाईं ओर पहली पंक्ति के-बार, यानी चार्ट डेटासेट का एक डेटा, जिसका इंडेक्स मान 0 हो सकता है पाइन भाषा के इनपुट चर द्वाराbar_indexपिन स्क्रिप्ट के निष्पादन के समय वर्तमान K-लाइन Bar के इंडेक्स मान को संदर्भित करता है.
pine
plot(bar_index, "bar_index")
plotफ़ंक्शंस फ़ंक्शंस में से एक है जो हम भविष्य में उपयोग करेंगे. यह बहुत ही सरल है, आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं, आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं, आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं, आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं, आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं, और आप फ़ंक्शंस के लिए फ़ंक्शंस का उपयोग कर सकते हैं।bar_indexलाइन नामित किया गया थाbar_indexआप देख सकते हैं कि पहले बार पर bar_index नामक पंक्ति का मान 0 है, और बार की वृद्धि के साथ दाईं ओर 1 की वृद्धि होती है।
नीति की सेटिंग्स के आधार पर, नीति के मॉडल को निष्पादित करने के तरीके अलग-अलग होते हैं।收盘价模型और实时价模型हम पहले भी इस पर चर्चा कर चुके हैं, लेकिन हम यह भी जानते हैं कि यह कैसे काम करता है।
-
समापन मूल्य मॉडल
जब रणनीति कोड निष्पादित किया जाता है, तो वर्तमान के-लाइन बार का चक्र पूरी तरह से निष्पादित हो जाता है, और के-लाइन बंद होने पर के-लाइन चक्र समाप्त हो जाता है। इस समय, पाइन रणनीति तर्क को फिर से निष्पादित किया जाता है, और ट्रिगर किए गए ट्रेडिंग सिग्नल को अगले के-लाइन बार की शुरुआत में निष्पादित किया जाएगा।
-
वास्तविक समय मूल्य मॉडल
रणनीति कोड निष्पादित करते समय, वर्तमान K-लाइन बार, चाहे वह बंद हो या नहीं, हर बार जब स्थिति बदलती है, तो पाइन रणनीति तर्क को फिर से निष्पादित किया जाता है, और ट्रिगर किए गए व्यापार संकेत को तुरंत निष्पादित किया जाता है।
जब पाइन भाषा रणनीति चार्ट पर बाएं से दाएं से निष्पादित की जाती है, तो चार्ट पर K लाइन बार को विभाजित किया जाता है历史Barऔर实时Barके लिएः
-
इतिहास बार
जब रणनीति को "वास्तविक स्टॉक मूल्य मॉडल" के रूप में सेट किया जाता है, तो चार्ट पर सभी K-लाइनों को छोड़कर सभी K-लाइनों को सबसे दाईं ओर एक K-लाइन बार के रूप में सेट किया जाता है।
历史Bar◦ रणनीति तर्क में हर历史Barकेवल एक बार किया गया
जब रणनीति को "क्लोज-आउट प्राइस मॉडल" के रूप में सेट किया जाता है, तो चार्ट पर सभी बार历史Bar◦ रणनीति तर्क में हर历史Barकेवल एक बार किया गयाइतिहास बार के आधार पर गणनाः
नीति कोड इतिहास बार बंद होने पर एक बार निष्पादित होता है, और फिर नीति कोड अगले इतिहास बार पर निष्पादित होता रहता है, जब तक कि सभी इतिहास बार एक बार निष्पादित नहीं हो जाते। -
रीयलटाइम बार
जब रणनीति को सबसे दाईं ओर के अंतिम K-लाइन बार पर निष्पादित किया जाता है, तो यह बार वास्तविक समय का बार होता है। जब वास्तविक बार बंद हो जाता है, तो यह बार एक पारित वास्तविक बार बन जाता है ((हिस्ट्री बार में बदल जाता है)) । चार्ट के सबसे दाईं ओर एक नया वास्तविक समय बार उत्पन्न होता है।
जब रणनीति को "वास्तविक समय मूल्य मॉडल" के रूप में सेट किया जाता है, तो रणनीति तर्क को वास्तविक समय बार पर प्रत्येक व्यापार परिवर्तन के लिए निष्पादित किया जाता है।
रणनीति को "क्लोज-आउट प्राइस मॉडल" के रूप में सेट किया गया है, जब यह निष्पादित होता है, तो चार्ट पर वास्तविक बार दिखाई नहीं देता है।वास्तविक समय में Bar के आधार परः
यदि नीति को "बंद मूल्य मॉडल" के रूप में सेट किया गया है, तो वास्तविक बार नहीं दिखाया जाएगा, तो नीति कोड केवल वर्तमान बार बंद होने पर एक बार निष्पादित किया जाएगा।
यदि नीति को "वास्तविक स्टॉक मूल्य मॉडल" के रूप में सेट किया जाता है, तो वास्तविक बार पर गणना और इतिहास बार पूरी तरह से अलग हैं, प्रत्येक बार जब वास्तविक बार पर व्यवहार बदलता है, तो एक नीति कोड निष्पादित किया जाता है। जैसे कि अंतर्निहित चरhigh、low、closeइतिहास बार में निश्चित है, वास्तविक समय बार में हो सकता है कि हर बार जब स्थिति बदलती है तो ये मान बदल जाते हैं। इसलिए इन मानों के आधार पर गणना किए गए संकेतक जैसे डेटा भी वास्तविक समय में बदल जाते हैं। वास्तविक समय बार मेंcloseयह हमेशा नवीनतम कीमतों का प्रतिनिधित्व करता है।highऔरlowहमेशा वर्तमान लाइव बार की शुरुआत के बाद से प्राप्त उच्चतम और निम्नतम बिंदुओं को दर्शाता है. इन अंतर्निहित चरों को वास्तविक बार के अंतिम अद्यतन के समय के अंतिम मानों को दर्शाता है.वास्तविक समय में बार पर रणनीति निष्पादन के लिए रिवॉल्वर (वास्तविक समय मूल्य मॉडल):
वास्तविक समय में बार निष्पादन के दौरान, नीति के प्रत्येक नई आवृत्ति के लिए पूर्व-रिसेट उपयोगकर्ता-परिभाषित चर को रिवर्स कहा जाता है। हम एक उदाहरण के साथ रिवर्स तंत्र को समझते हैं, परीक्षण कोड के रूप में।सूचना:
/*backtest ... .. . */पैकेज में FMZ प्लेटफ़ॉर्म पर कोड के रूप में संग्रहीत फीडबैक कॉन्फ़िगरेशन जानकारी शामिल है।
pine/*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("n + 1之前, n:", n, " 当前bar_index:", bar_index) n := n + 1 runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index) plot(n, title="n")हम केवल वास्तविक समय बार में प्रदर्शन के दृश्यों का अध्ययन करते हैं, इसलिए हमने इसका उपयोग किया
not barstate.ishistoryअभिव्यक्ति प्रतिबंध केवल वास्तविक समय Bar में चर n के लिए संचयी है, और संचयी संचालन करने से पहले और बाद में उपयोग किया जाता हैruntime.logफ़ंक्शन नीति लॉग में जानकारी का उत्पादन करता है।plotखींची गई वक्र n को देखा जा सकता है जब रणनीति इतिहास बार में चल रही थी, तो n हमेशा 0 रहा है। वास्तविक समय बार में निष्पादित होने पर, n को 1 पर ट्रिगर किया गया था, और वास्तविक समय बार पर हर बार रणनीति निष्पादित होने पर n को 1 पर निष्पादित किया गया था। लॉग जानकारी से देखा जा सकता है कि प्रत्येक बार फिर से निष्पादित करने के लिए रणनीति कोड को पिछले बार निष्पादित करने के लिए अंतिम बार प्रस्तुत किया गया था। वास्तविक समय बार में अंतिम बार निष्पादित करने के लिए रणनीति कोड को प्रस्तुत किया गया था। इसलिए, यह देखा जा सकता है कि चार्ट वास्तविक समय बार से शुरू होता है और वक्र n को हर बार बार वक्र n को बढ़ाता है।संक्षेप में:
- जब रणनीति वास्तविक समय बार में निष्पादित की जाती है, तो नीति कोड को हर बार अपडेट किया जाता है।
- वास्तविक समय बार पर निष्पादित होने पर, नीति कोड निष्पादित होने से पहले चर को वापस रोल किया जाता है।
- वास्तविक समय बार पर निष्पादित होने पर, चर को समापन अद्यतन पर एक बार प्रस्तुत किया जाता है
क्योंकि डेटा रिवर्स होता है, इसलिए आरेख पर वक्र जैसे आरेखण संचालन भी पुनः आरेखण का कारण बन सकते हैं, उदाहरण के लिए हमने अभी परीक्षण कोड को संशोधित किया है, रीयल-डिस्क परीक्षणः
pinevar n = 0 if not barstate.ishistory runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index) n := open > close ? n + 1 : n runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index) plot(n, title="n")हमने केवल इस वाक्य को बदल दिया हैः
n := open > close ? n + 1 : nयह देखा जा सकता है कि पहले ग्राफ में, चूंकि उस समय की शुरुआती कीमत बंद कीमत से अधिक थी, इसलिए n ने 1 को जोड़ा, इसलिए ग्राफ वक्र n का मूल्य 5 दिखाया गया था। फिर स्थिति बदल गई, कीमतों को अपडेट किया गया जैसा कि दूसरे ग्राफ में दिखाया गया था। इस समय की शुरुआती कीमत बंद कीमत से कम थी, एन मूल्य वापस चला गया और इसमें कोई अतिरिक्त 1 नहीं था। ग्राफ में वक्र n को तुरंत फिर से तैयार किया गया था, इस समय वक्र पर n 4 था। इसलिए वास्तविक समय बार पर दिखाए गए कांटा, मृत कांटा और अन्य संकेत अनिश्चित हैं, परिवर्तन की संभावना है। -
फ़ंक्शन में चर का संदर्भ
नीचे हम पाइन भाषा फ़ंक्शन में चर का अध्ययन करते हैं। कुछ पाइन ट्यूटोरियल के अनुसार, फ़ंक्शन में चर और फ़ंक्शन के बाहर चर में इस तरह का अंतर हैः
Pine फ़ंक्शन में उपयोग किए जाने वाले श्रृंखला चर का इतिहास फ़ंक्शन के प्रत्येक लगातार कॉल के माध्यम से बनाया जाता है। यदि कोई फ़ंक्शन हर कॉलम पर कॉल नहीं किया जाता है, तो यह फ़ंक्शन के स्थानीय ब्लॉक के भीतर और बाहरी श्रृंखला के इतिहास मानों के बीच अंतर पैदा करेगा। इसलिए, यदि कोई फ़ंक्शन हर कॉलम पर कॉल नहीं किया जाता है, तो फ़ंक्शन के भीतर और बाहरी संदर्भों में समान अनुक्रमण मानों का उपयोग करने वाली श्रृंखलाएं समान इतिहास बिंदुओं का संदर्भ नहीं देंगी।
हम FMZ पर चलने वाले एक परीक्षण कोड के माध्यम से इस समस्या को समझते हैंः
pine/*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]。 -
f2() => close[1]सीधे अंतर्निहित चर का उपयोग करें:close, फ़ंक्शन के अंत में लौटाता हैclose[1]。
[]प्रतीक डेटा श्रृंखला चर के ऐतिहासिक मानों के संदर्भ में उपयोग किया जाता है, close[1] यह वर्तमान समापन मूल्य से पहले एक बार पर समापन मूल्य डेटा संदर्भित करता है. हमारे परीक्षण कोड चार्ट पर चार प्रकार के डेटा को चित्रित करता हैः-
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
एक अक्षर A<unk>, रंग लाल, जब oneBarInTwo सही है, तो चित्रित करें, चित्रित स्थान (वाई-अक्ष पर) हैःf(close)लौटाया गया मान -
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
एक वर्ण को B से B तक खींचें, और इसे हरे रंग में रंग दें, और जब oneBarInTwo सही हो, तो इसे खींचें, और इसे Y अक्ष पर खींचेंःf2()लौटाया गया मान -
plot(close[2], title = "close[2]", color = color.red, overlay = true)
रेखाएं लाल रंग की हैं और रेखांकित स्थान (वाई-अक्ष पर) है:close[2]यानी वर्तमान बार के पूर्व की संख्या में 2 वें स्थान पर (बाएं की संख्या में 2 वें स्थान पर) बार पर समापन मूल्य। -
plot(close[1], title = "close[1]", color = color.green, overlay = true)
रेखाएँ हरे रंग की हैं और रेखांकित स्थान (वाई-अक्ष पर) हैःclose[1]यानी वर्तमान बार के पहले नंबर 1 पर बंद होने की कीमत (बाएं नंबर 1 पर बंद)
रणनीति के माध्यम से चल रहा है अनुवर्ती स्क्रीनशॉट में देखा जा सकता है, हालांकि चित्र A में उपयोग किए गए कार्यों को चिह्नित किया गया है
f(a) => a[1]फ़ंक्शन और चित्र B के लिए उपयोग किया जाता है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] इस तरह के एक ही सूचकांक) <unk> -
-
कुछ अंतर्निहित फ़ंक्शंस को प्रत्येक बार पर गणना करने की आवश्यकता होती है ताकि उनके परिणामों को सही ढंग से गणना की जा सके
एक सरल उदाहरण के साथ, मैं इसे समझाता हूंः
pineres = 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और यह केवल भारत में ही हो रहा है।close > close[1]जब हम ta.barssince फ़ंक्शन को कॉल करते हैं।ta.barssinceफ़ंक्शन की गणना की गई हैclose < close[1]स्थापना के समय K पंक्तियों की संख्या. जब ta.barssince फ़ंक्शन को बुलाया जाता है तो close > close होता है[1], यानी वर्तमान समापन मूल्य पिछले Bar के समापन मूल्य से बड़ा है, फ़ंक्शन ta.barssince को बुलाया जाता है जब इसकी शर्त close < close[1] न तो स्थापित किया गया है और न ही हाल ही में स्थापित किया गया हैta.barssince: जब यह बुलाया जाता है, तो यह फ़ंक्शन na。 को लौटाता है यदि यह स्थिति वर्तमान K लाइन से पहले कभी भी पूरी नहीं हुई है।
जैसा कि चित्र में दिखाया गया है:
इसलिए जब हम चित्र बनाते हैं, तो हम केवल उस डेटा को चित्रित करते हैं जिसके लिए रेस वैरिएबल ((-1)) ।
और हम सिर्फ इस समस्या से बचने के लिए
ta.barssince(close < close[1])फ़ंक्शन कॉल को त्रिकोणीय ऑपरेटर से निकाला जाता है और इसे किसी भी संभावित सशर्त शाखा के बाहर लिखा जाता है। इसे प्रत्येक के-लाइन बार पर गणना करने के लिए बनाया जाता है।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)
कालक्रम
समय अनुक्रम की अवधारणा पाइन भाषा में बहुत महत्वपूर्ण है, यह एक अवधारणा है जिसे हमें पाइन भाषा सीखने के लिए समझना होगा। समय अनुक्रम एक प्रकार नहीं है, बल्कि समय के साथ चर के निरंतर मानों को संग्रहीत करने के लिए एक बुनियादी संरचना है। हम जानते हैं कि पाइन स्क्रिप्ट चार्ट पर आधारित है, और चार्ट में प्रदर्शित होने वाली सबसे बुनियादी सामग्री K रेखाचित्र है। समय अनुक्रम जिनमें से प्रत्येक मान एक K लाइन बार की समय सारणी से जुड़ा हुआ है।openएक पेन भाषा का एक अंतर्निहित चर है, जिसका निर्माण प्रत्येक के-लाइन बार के उद्घाटन मूल्य के समय अनुक्रम को संग्रहीत करने के लिए किया जाता है। इसे समझा जा सकता हैopenयह समय-क्रम संरचना वर्तमान K रेखाचित्र के सभी K रेखाचित्रों के उद्घाटन मूल्य को दर्शाता है, जो शुरू होने वाले पहले Bar से वर्तमान स्क्रिप्ट द्वारा निष्पादित Bar तक है। यदि वर्तमान K रेखाचित्र 5 मिनट की अवधि है, तो हम पिन रणनीति कोड में संदर्भित करते हैं (या उपयोग करते हैं)openयदि आप समय-क्रम में ऐतिहासिक मानों को संदर्भित करना चाहते हैं, तो उपयोग करें[]ऑपरेटर <unk> जब पिन नीति किसी K-लाइन बार पर निष्पादित होती है, तो इसका उपयोग किया जाता हैopen[1]उद्धरण दिखाएँopenसमय-क्रम पर वर्तमान स्क्रिप्ट द्वारा निष्पादित इस K-लाइन Bar के पिछले K-लाइन Bar के उद्घाटन मूल्य ((यानी पिछले 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परीक्षण कोड:
pinev1 = 1 v2 = ta.cum(v1) plot(v1, title="v1") plot(v2, title="v2") plot(bar_index+1, title="bar_index")बहुत कुछ
ta.cumइस तरह के अंतर्निहित फ़ंक्शन समय-क्रम पर डेटा को सीधे संसाधित कर सकते हैं, जैसेta.cumहम एक चार्ट का उपयोग करने के लिए समझने में मदद करने के लिए आगे बढ़ते हैं.रणनीति चलाने की प्रक्रिया
| - | - | - | - |
रणनीतियाँ चलती हैं 1 के-लाइन पर.
रणनीतियाँ चलती हैं के-लाइन 2 पर.
रणनीति चलती है तीसरे K-लाइन पर Bar ⇒ ⇒ 2 ⇒ 1 ⇒ 3 ⇒
|...|...|...|...|
रणनीति के लिए चलाता है के N + 1 रूट के लिएBarजैसा कि आप देख सकते हैं, वास्तव में v1, v2 और यहां तक कि bar_index सभी समय-क्रम संरचनाएं हैं, प्रत्येक बार पर संबंधित डेटा है। इस परीक्षण कोड को "वास्तविक मूल्य मॉडल" या "बंद मूल्य मॉडल" के बीच अंतर केवल यह है कि क्या वास्तविक बार चार्ट पर दिखाई देता है। गति को मापने के लिए हम "बंद मूल्य मॉडल" प्रतिक्रिया परीक्षण का उपयोग करते हैं।
क्योंकि v1 हर बार में 1 है.
ta.cum(v1)फ़ंक्शन को पहले K-लाइन Bar पर निष्पादित किया जाता है, क्योंकि केवल पहला Bar है, इसलिए गणना परिणाम 1 है, जो चर v2 को निर्दिष्ट करता है।
जबta.cum(v1)दूसरी K-लाइन Bar पर कार्य करते समय, पहले से ही 2 K-लाइन Bar हैं ((पहली संबंधित अंतर्निहित चर bar_index 0 है, दूसरी संबंधित अंतर्निहित चर bar_index 1) है, इसलिए गणना परिणाम 2 है, चर v2 को मान दिया गया है, और इसी तरह। वास्तव में यह देखा जा सकता है कि v2 चार्ट में K-लाइन Bar की संख्या है, क्योंकि K-लाइन का अनुक्रमणbar_indexतो यह 0 से बढ़ रहा है.bar_index + 1यह वास्तव में K लाइनों की संख्या है.v2औरbar_indexयह सच है।मैं भी उपयोग कर सकता हूँ
ta.cumइनबिल्ट फ़ंक्शन वर्तमान चार्ट पर सभी बार्स के समापन मूल्य के योग की गणना करता है, तो इसे केवल इस तरह से लिखा जा सकता हैःta.cum(close), जब रणनीति चलाने के लिए सबसे दाईं ओर लाइव बारta.cum(close)परिणाम चार्ट पर सभी बार के समापन मूल्य का योग है (जब तक कि सबसे दाईं ओर नहीं चलाया जाता है, केवल वर्तमान बार में जमा किया जाता है) ।समय-क्रम पर चर भी ऑपरेटरों का उपयोग करके गणना की जा सकती है, उदाहरण के लिए कोडः
ta.sma(high - low, 14)और आप अपने अंतर्निहित चरhigh(K लाइन Bar अधिकतम मूल्य) घटाया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)[1]उनमें सेta.highest(high, 10)फ़ंक्शन कॉल के परिणामों का भी उपयोग किया जा सकता है[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 के मान संबंधित बार के ऊपर और नीचे दिखाई देते हैं। इस आरेख कोड को सीखने के दौरान संरक्षित किया जा सकता है, क्योंकि परीक्षण और प्रयोग के दौरान अक्सर चार्ट पर जानकारी को देखने के लिए आउटपुट करने की आवश्यकता हो सकती है।
स्क्रिप्ट संरचना
सामान्य संरचना
ट्यूटोरियल के शुरुआती भाग में हमने एफएमजेड पर पाइन और ट्रेडिंग व्यू पर पाइन भाषा के उपयोग के बारे में कुछ अंतरों को संक्षेप में प्रस्तुत किया है।indicator()、strategy()और अस्थायी रूप से समर्थन नहींlibrary()बेशक, पाइन स्क्रिप्ट के पहले संस्करणों के साथ संगतता के लिए, रणनीति को लिखते समय, इस तरह के लेख लिखेंः//@version=5,indicator(),strategy()यह भी ठीक है. कुछ नीति सेटिंग्सstrategy()फ़ंक्शन में पैरामीटर सेट करना <unk>
<version>
<declaration_statement>
<code>
<version>संस्करण नियंत्रण जानकारी को छोड़ दिया जा सकता है.
टिप्पणी
पाइन भाषा//एक पंक्ति टिप्पणी के रूप में, क्योंकि पाइन भाषा में कोई बहु-पंक्ति टिप्पणी नहीं है./**/बहु-पंक्ति टिप्पणी के लिए।
कोड
स्क्रिप्ट में टिप्पणी या कंपाइलर निर्देशों की पंक्तियाँ नहीं हैं, जो कथन हैं, जो स्क्रिप्ट के एल्गोरिदम को लागू करते हैं। एक कथन इनमें से एक हो सकता है।
- चर घोषणाएँ
- चर को पुनः प्राप्त करना
- फ़ंक्शन घोषणाएँ
- अंतर्निहित फ़ंक्शन कॉल, उपयोगकर्ता द्वारा परिभाषित फ़ंक्शन कॉल
if,for,whileयाswitchइकाइयों
वाक्यों को कई तरीकों से व्यवस्थित किया जा सकता है
- कुछ वाक्यों को एक पंक्ति में व्यक्त किया जा सकता है, जैसे कि अधिकांश चर घोषणाओं में केवल एक पंक्ति होती है जिसमें फ़ंक्शन कॉल किया जाता है या एक पंक्ति फ़ंक्शन घोषणाएँ होती हैं। अन्य, संरचनाओं की तरह, हमेशा कई पंक्तियों की आवश्यकता होती है, क्योंकि उन्हें एक स्थानीय ब्लॉक की आवश्यकता होती है।
- स्क्रिप्ट के वैश्विक स्तर पर बयानों (यानी जो भाग स्थानीय ब्लॉक से संबंधित नहीं हैं) को इस प्रकार नहीं समझा जा सकता है
空格या制表符(टैब कुंजी) शुरू. उनके पहले अक्षर भी इस पंक्ति के पहले अक्षर होना चाहिए. पंक्तियों में पंक्ति के पहले स्थान पर शुरू पंक्तियों, परिभाषा के अनुसार स्क्रिप्ट के वैश्विक दायरे का हिस्सा बनने के लिए. - संरचना या बहु-पंक्ति फ़ंक्शन कथन हमेशा एक की आवश्यकता होती है
local block。 एक स्थानीय ब्लॉक को एक तालिका चिह्न या चार रिक्त स्थानों में स्केल करना होगा (अन्यथा, इसे पिछले पंक्ति के सीरियल कोड के रूप में पार्स किया जाएगा, यानी इसे पिछले पंक्ति के कोड के निरंतरता के रूप में माना जाएगा), प्रत्येक स्थानीय ब्लॉक एक अलग स्थानीय सीमा को परिभाषित करता है 。 - एक पंक्ति में कई एक पंक्ति के वाक्य को एक पंक्ति में क्रमबद्ध किया जा सकता है, जिसमें एक विराम चिह्न के रूप में (() का उपयोग किया जाता है।
- एक पंक्ति में टिप्पणी हो सकती है या केवल टिप्पणी हो सकती है।
- पंक्तियों को एक साथ लपेटा जा सकता है (बहु पंक्तियों में जारी रखें) ।
उदाहरण के लिए, तीन स्थानीय ब्लॉकों को शामिल करें, एक कस्टम फ़ंक्शन घोषणा में और दो चर घोषणाओं में if संरचना का उपयोग करते हुए, निम्न कोड के साथः
pine
indicator("", "", true) // 声明语句(全局范围),可以省略不写
barIsUp() => // 函数声明(全局范围)
close > open // 本地块(本地范围)
plotColor = if barIsUp() // 变量声明 (全局范围)
color.green // 本地块 (本地范围)
else
color.red // 本地块 (本地范围)
runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)
कोड बदलें
लंबी पंक्तियों को कई पंक्तियों में विभाजित किया जा सकता है, या उन्हें "पैक" किया जा सकता है। लपेटी गई पंक्तियों को किसी भी संख्या में रिक्त स्थान में संकुचित किया जाना चाहिए, जब तक कि यह 4 का गुणक न हो (इन सीमाओं को स्थानीय ब्लॉक में संकुचित करने के लिए उपयोग किया जाता है) ।
pine
a = open + high + low + close
इसे पैक किया जा सकता है (ध्यान दें कि प्रत्येक पंक्ति में संकुचित रिक्त स्थान की संख्या 4 के गुणक नहीं है):
pine
a = open +
high +
low +
close
एक लंबा प्लॉट ((() कॉल पैक किया जा सकता है।
pine
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100), // 一行长的plot()调用可以被包装
color = color.new(color.purple, 40),
style = plot.style_area,
trackprice = true)
उपयोगकर्ता-परिभाषित फ़ंक्शन कथन में एक कथन को भी पैक किया जा सकता है। हालांकि, चूंकि स्थानीय ब्लॉक को वाक्यविन्यास में एक संकोचन के साथ शुरू करना होगा ((4 रिक्त स्थान या 1 मेमोरी), जब इसे अगली पंक्ति में विभाजित किया जाता है, तो कथन का निरंतर भाग एक या अधिक संकोचन के साथ शुरू होना चाहिए ((जो 4 रिक्त स्थान के गुणक के बराबर नहीं है) । जैसेः
pine
test(c, o) =>
ret = c > o ?
(c > o+5000 ?
1 :
0):
(c < o-5000 ?
-1 :
0)
a = test(close, open)
plot(a, title="a")
आइडेंटिफायर और ऑपरेटर
पहचानकर्ता
चर को समझने से पहले, हमें पहले पता होना चाहिए कि क्या एक चर है। सामान्य रूप से, एक चर के रूप में एक चर के रूप में एक चर के रूप में एक चर के रूप में एक चर के रूप में एक चर का उपयोग किया जाता है।समारोहऔरचरके नाम का ((नामकरण चर, फ़ंक्शन के लिए)) ।समारोहऔर जैसा कि हम बाद के पाठों में देखेंगे, हम पहले सीखते हैं कि क्या है तिल का प्रतीक <unk>。
-
- पहचानकर्ता बड़े अक्षरों में होना चाहिए
(A-Z)या छोटा लिखें(a-z)अक्षर या रेखांकित(_)शुरुआत, पहचानकर्ता के पहले अक्षर के रूप में ▽
- पहचानकर्ता बड़े अक्षरों में होना चाहिए
-
- पहचानकर्ता के पहले अक्षर के बाद अगला अक्षर हो सकता हैअक्षर、नीचे की रेखायासंख्याएँ。
-
- पहचानकर्ता का नाम बड़े और छोटे अक्षरों में लिखा गया है।
उदाहरण के लिए, निम्न नाम वाले आइडेंटिफ़ायर:
pine
fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown // 错误的命名!使用了数字字符作为标识符的开头字符
अधिकांश प्रोग्रामिंग भाषाओं की तरह, पाइन भाषा में लेखन सुझाव भी हैं। आमतौर पर पहचानकर्ताओं के नामकरण के लिए सिफारिश की जाती हैः
- 1। सभी अक्षरों को बड़े अक्षरों में नामकरण स्थिरांक के लिए लिखा जाता है।
-
- उपयोग करेंकमलपिक नियमअन्य पहचानकर्ताओं के लिए नामित।
pine
// 命名变量、常量
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// 命名函数
zeroOne(boolValue) => boolValue ? 1 : 0
ऑपरेटर
ऑपरेटर प्रोग्रामिंग भाषाओं में अभिव्यक्ति बनाने के लिए उपयोग किए जाने वाले ऑपरेटरों के कुछ प्रतीक हैं, और अभिव्यक्ति एक प्रकार की गणना के लिए डिज़ाइन किए गए गणना नियम हैं जब हम एक रणनीति लिखते हैं। पाइन भाषा में ऑपरेटरों को कार्य के अनुसार वर्गीकृत किया गया हैः
मान संचालक, अंकगणित संचालक, तुलना संचालक, तर्क संचालक? : त्रिमूर्ति संचालक[]इतिहास संदर्भ ऑपरेटर <unk>
अंकगणित ऑपरेटर*उदाहरण के लिए, ट्रेडिंग व्यू पर पाइन भाषा ऑपरेटर द्वारा लौटाए गए परिणामों के कारण होने वाले प्रकार के प्रश्नों के विपरीत, निम्न परीक्षण कोड हैः
pine
//@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फ़ंक्शन का दूसरा पैरामीटर इस प्रकार का समर्थन नहीं करता है। लेकिन एफएमजेड पर इस तरह के सख्त प्रतिबंध नहीं हैं, उपरोक्त कोड सामान्य रूप से काम कर सकता है।
नीचे हम विभिन्न प्रकार के ऑपरेटरों के उपयोग पर एक नज़र डालते हैं:
मानगणक
दो प्रकार के मूल्य-निर्धारण संचालक हैंः=、:=और हमने इसे कुछ उदाहरणों में भी देखा है, जो इस ट्यूटोरियल के शुरुआती भाग में हैं।
=ऑपरेटर का उपयोग चर को आरंभ करने या घोषित करने के लिए किया जाता है।=प्रारंभ करने के बाद, एक चर को एक मूल्य दिया जाता है जो बाद के प्रत्येक बार पर उस मूल्य के साथ शुरू होता है। ये सभी वैध चर घोषणाएं हैंः
a = close // 使用内置变量赋值给a
b = 10000 // 使用数值赋值
c = "test" // 使用字符串赋值
d = color.green // 使用颜色值赋值
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)
सूचनाa = closeमूल्य निर्धारण कथन, प्रत्येक बार पर चर a वर्तमान बंद मूल्य है जो उस बार के लिए है ((close) । अन्य चरb、c、dएफएमजेड पर फीडबैक सिस्टम में परीक्षण किया जा सकता है, परिणाम चित्रों से देखा जा सकता है।
:=एक मौजूदा चर के लिए एक मूल्य को फिर से असाइन करने के लिए उपयोग किया जाता है, और इसे सरलता से समझा जा सकता है:=ऑपरेटरों को पहले से ही घोषित और आरंभिक चर के मानों को संशोधित करने के लिए उपयोग किया जाता है।
अगर इस्तेमाल किया:=ऑपरेटरों को एक अपरिवर्तित या घोषित चर को असाइन करने से त्रुटि उत्पन्न होती है, उदाहरण के लिएः
pine
a := 0
तो,:=एक असाइनमेंट ऑपरेटर आमतौर पर एक मौजूदा चर को पुनः असाइन करने के लिए उपयोग किया जाता है, उदाहरण के लिएः
pine
a = close > open
b = 0
if a
b := b + 1
plot(b)
निर्णय यदिclose > open(अर्थात वर्तमान BAR सूर्य रेखा है), a चर सही है ((true)) । यह if कथन के स्थानीय ब्लॉक में कोड निष्पादित करता हैb := b + 1, एस्केप ऑपरेटर का उपयोग करें:=b को फिर से मान दें, 1 जोड़ें। फिर प्लॉट फ़ंक्शन का उपयोग करें और समय-क्रम में प्रत्येक BAR पर चर b के मानों को रेखांकित करें।
क्या हम मान रहे हैं कि जब एक घातांक BAR होता है, तो b लगातार 1 जोड़ता रहता है? बेशक नहीं, यहाँ हम किसी भी कुंजी शब्द का उपयोग नहीं करते हैं जब हम चर b को 0 के रूप में आरंभ करते हैं।b=0तो आप देख सकते हैं कि इस कोड के निष्पादन का परिणाम है कि हर बार b को 0 पर रीसेट किया जाता है यदि a सही है, तोclose > openतो इस दौर के कोड को निष्पादित करते समय, b को 1 से जोड़ दिया जाता है, और प्लॉट फ़ंक्शन को 1 पर आरेखित किया जाता है, लेकिन अगले दौर के कोड को निष्पादित करते समय, b को 0 पर फिर से असाइन किया जाता है।
जब हम assignment operators के बारे में बात करते हैं, तो हमें दो keywords के बारे में विस्तार से बताना होगा:var、varip
-
var
वास्तव में, यह एक ऐसा शब्द है जिसे हमने पिछले ट्यूटोरियल में देखा और इस्तेमाल किया था, लेकिन हमने उस समय इस पर विस्तार से चर्चा नहीं की थी।
var एक कुंजी शब्द है जिसका उपयोग आवंटित और एक बार में आरंभ किए जाने वाले चर के लिए किया जाता है। आमतौर पर, बिना कुंजी शब्द var के चर-मूल्य निर्धारण सिंटैक्स के कारण डेटा को हर बार अपडेट करने पर चर के मूल्य को कवर किया जाता है। इसके विपरीत, जब कुंजी शब्द var का उपयोग किया जाता है तो आवंटित चर को डेटा अपडेट होने के बावजूद रखा जा सकता है।
हम इस उदाहरण का उपयोग करते हैं, लेकिन हम इसे b के लिए करते हैं
varकुंजी शब्दpinea = close > open var b = 0 if a b := b + 1 plot(b)varकुंजी शब्द b को केवल पहले पहले असाइनमेंट को निष्पादित करता है, और फिर हर बार जब रणनीति तर्क निष्पादित किया जाता है, तो b को फिर से 0 पर नहीं रखा जाता है, इसलिए चलती समय से खींची गई रेखा को देखा जा सकता है b यानी वर्तमान K लाइन BAR के समय पर आने वाले y लाइन BAR की संख्या को वापस मापने के लिए।var घोषणाओं के चर को न केवल वैश्विक स्तर पर लिखा जा सकता है, बल्कि कोड के ब्लॉक में भी लिखा जा सकता है, जैसे कि इस उदाहरण मेंः
pinestrategy(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")चर 'a' श्रृंखला में पहले स्तंभ रेखा के समापन मूल्य को बनाए रखता है।
चर 'b' श्रृंखला में पहले नीलमणि नीलमणि मूल्य पट्टी के समापन मूल्य को बनाए रखता है।
चर 'c' श्रृंखला में दसवें स्ट्राबेरी के समापन मूल्य को बनाए रखता है। -
varip
varipहम पहली बार इस शब्द को देख रहे हैं, और हम इस शब्द का वर्णन देख सकते हैंःvarip ((var intrabar persist) एक कीवर्ड है जिसका उपयोग आवंटन और एक बार में आरंभ करने वाले चरों के लिए किया जाता है। यह var कीवर्ड के समान है, लेकिन varip कथन का उपयोग करने वाले चर वास्तविक समय के-लाइन अपडेट के बीच अपने मानों को बरकरार रखते हैं।
क्या यह समझना मुश्किल है? कोई बात नहीं, हम इसे उदाहरणों के माध्यम से समझाते हैं, यह समझना आसान है।
strategy(overlay=true) // 测试 var varip var i = 0 varip ii = 0 // 将策略逻辑每轮改变的i、ii打印在图上 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) // 每轮逻辑执行都给i、ii递增1 i := i + 1 ii := ii + 1यह परीक्षण कोड क्लोजर प्राइस मॉडल और रीयल-टाइम प्राइस मॉडल में अलग-अलग प्रदर्शन करता हैः
वास्तविक समय मूल्य मॉडल:
याद रखें कि हमने पहले कहा था कि रणनीति के निष्पादन के समय को ऐतिहासिक BAR चरण और वास्तविक समय BAR चरण में विभाजित किया गया है?var、varipघोषित चरi、iiरणनीति कोड के प्रत्येक दौर के निष्पादन के दौरान वृद्धिशील ऑपरेशन किया जाता है। इसलिए यह देखा जा सकता है कि KBAR लाइन पर प्रदर्शित संख्याओं में से प्रत्येक में वृद्धि होती है। जब ऐतिहासिक K लाइन चरण समाप्त हो जाती है, तो वास्तविक समय K लाइन चरण शुरू होता है। var, varp घोषणाओं के चर में अलग-अलग परिवर्तन होने लगते हैं। क्योंकि यह वास्तविक समय मूल्य मॉडल है, एक K लाइन BAR के भीतर हर बार मूल्य परिवर्तन के लिए रणनीति कोड को एक बार निष्पादित किया जाता है,i := i + 1औरii := ii + 1सभी को एक बार निष्पादित किया जाएगा。 अंतर यह है कि ii हर बार संशोधित किया जाएगा。 i हालांकि हर बार संशोधित किया जाएगा, लेकिन अगले दौर के निष्पादन रणनीति तर्क के दौरान पिछले मूल्य को बहाल किया जाएगा ((याद पिछले "मॉडल निष्पादन" अध्याय में हम समझाया गया है कि वापस रोल तंत्र?), जब तक कि वर्तमान KBAR लाइन खत्म हो जाता है i के मूल्य को अद्यतन करने के लिए निर्धारित किया गया है (यानी, अगले दौर के निष्पादन रणनीति तर्क के दौरान पहले मूल्य को बहाल नहीं किया जाएगा) ।) तो आप देख सकते हैं कि चर i अभी भी हर बार 1 की वृद्धि है。 लेकिन चर ii हर बार कई बार जोड़ा गया है。समापन मूल्य मॉडल:
चूंकि समापन मूल्य मॉडल प्रत्येक K लाइन BAR के लिए एक रणनीति तर्क निष्पादित करता है। इसलिए, समापन मूल्य मॉडल में, ऐतिहासिक K लाइन चरण और वास्तविक समय K लाइन चरण, var, varp के बयानों के चर उपरोक्त उदाहरणों में पूरी तरह से एक समान प्रदर्शन करते हैं, प्रत्येक K लाइन BAR में वृद्धि होती है।
अंकगणित ऑपरेटर
| ऑपरेटर | उदाहरण देकर स्पष्ट करना |
|---|---|
| + | गफा |
| - | घटाव |
| * | गुणन |
| / | उन्मूलन |
| % | आदर्शों की तलाश |
+、-ऑपरेटरों को द्विआधारी ऑपरेटरों के रूप में इस्तेमाल किया जा सकता है, लेकिन वे एक-आयामी ऑपरेटरों के रूप में भी इस्तेमाल किया जा सकता है। अन्य अंकगणित ऑपरेटरों को केवल द्विआधारी ऑपरेटरों के रूप में इस्तेमाल किया जा सकता है, यदि वे एक-आयामी ऑपरेटरों के रूप में उपयोग किए जाते हैं तो त्रुटि होती है।
1, अंकगणित ऑपरेटर दोनों पक्षों में संख्यात्मक प्रकार हैं, परिणाम संख्यात्मक प्रकार, पूर्णांक या फ्लोटिंग पॉइंट संख्या है जो ऑपरेशन के परिणामों पर निर्भर करता है।
2. यदि कोई ऑपरेशन संख्या एक स्ट्रिंग है, तो ऑपरेटर है+, को एक स्ट्रिंग के रूप में गणना की जाती है, संख्यात्मक मान को स्ट्रिंग के रूप में परिवर्तित किया जाता है, और फिर स्ट्रिंग को एक साथ जोड़ा जाता है। यदि यह अन्य अंकगणित ऑपरेटर है, तो स्ट्रिंग को संख्यात्मक मान में परिवर्तित करने का प्रयास किया जाता है, और फिर ऑपरेशन किया जाता है।
3। यदि कोई ऑपरेशन संख्या na है, तो गणना परिणाम शून्य n है, और एफएमजेड पर मुद्रित होने पर NaN दिखाई देगा।
pine
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
एफएमजेड पर पाइन भाषा यहाँ और ट्रेडिंग व्यू पर पाइन भाषा में थोड़ा अंतर है, एफएमजेड पर पाइन भाषा चर प्रकार के लिए बहुत कठोर नहीं है। उदाहरण के लिएः
pine
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
एफएमजेड पर यह चल सकता है, लेकिन ट्रेडिंग दृश्य पर यह टाइप एरर रिपोर्ट करता है। जब अंकगणित ऑपरेटर के दोनों ओर ऑपरेशन स्ट्रिंग होते हैं, तो सिस्टम स्ट्रिंग को संख्यात्मक मान में परिवर्तित कर देता है। यदि गैर-संख्यात्मक स्ट्रिंग की गणना नहीं की जा सकती है, तो सिस्टम ऑपरेशन परिणाम शून्य होगा।
तुलना ऑपरेटर
तुलना ऑपरेटर द्विआधारी ऑपरेटर हैं.
| ऑपरेटर | उदाहरण देकर स्पष्ट करना |
|---|---|
| < | से कम |
| > | से बड़ा |
| <= | से कम बराबर है |
| >= | अधिक से अधिक |
| == | समकक्ष |
| != | असमानता |
परीक्षण उदाहरण:
pine
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इंतज़ार।
एफएमजेड पर ट्रेडिंग व्यू के पाइन से भिन्नता है, जैसा कि ऑपरेटिंग ऑपरेटरों के साथ होता है, एफएमजेड में विशेष रूप से सख्त आवश्यकता प्रकार नहीं होते हैं, इसलिए इस तरह के बयानd = "1" >= 2 एफएमजेड पर कोई त्रुटि नहीं है, निष्पादन में स्ट्रिंग को पहले संख्यात्मक मान में परिवर्तित किया जाता है, और फिर तुलनात्मक संचालन किया जाता है। ट्रेडिंग व्यू पर, त्रुटि रिपोर्ट की जाती है।
लॉजिक ऑपरेटर
| ऑपरेटर | संकेतक | उदाहरण देकर स्पष्ट करना |
|---|---|---|
| नहीं | not | ऑपरेटर नहीं |
| और | and | द्विआधारी ऑपरेटर |
| या | or | द्विआधारी ऑपरेटर, या ऑपरेटिंग |
तर्क ऑपरेटरों के बारे में बात करते हुए, हम वास्तविक मान तालिकाओं के बारे में भी बात करते हैं। जैसा कि हमने हाई स्कूल में सीखा था, केवल यहां हम परीक्षण और सीखने के लिए प्रतिक्रिया प्रणाली का उपयोग करते हैंः
pine
a = 1 == 1 // 使用比较运算符构成的表达式,结果为布尔值
b = 1 != 1
c = not b // 逻辑非操作符
d = not a // 逻辑非操作符
runtime.log("测试逻辑操作符: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("测试逻辑操作符: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。
हालांकि इसका कोई व्यावहारिक उपयोग नहीं है, लेकिन इसे दिखाने के लिए कुछ आसान उदाहरण हैंः
pine
a = close > open
b = a ? "阳线" : "阴线"
c = not a ? "阴线" : "阳线"
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)
यदि आप एक क्रॉसस्टार को देखते हैं, तो कोई फर्क नहीं पड़ता! त्रिकोणात्मक अभिव्यक्ति को भी एम्बेडेड किया जा सकता है, जैसा कि हमने पिछले ट्यूटोरियल में किया था।
pine
a = close > open
b = a ? math.abs(close-open) > 30 ? "阳线" : "十字星" : math.abs(close-open) > 30 ? "阴线" : "十字星"
c = not a ? math.abs(close-open) > 30 ? "阴线" : "十字星" : math.abs(close-open) > 30 ? "阳线" : "十字星"
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)
वास्तव में, यहcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseमेंvalueWhenConditionIsTrue、valueWhenConditionIsFalse, इसके बजाय अन्य त्रिमूर्ति अभिव्यक्ति का उपयोग करें।
इतिहास ऑपरेटर
इतिहास ऑपरेटर का उपयोग करें[], संदर्भ समय अनुक्रम पर इतिहास मूल्यों <unk> ये इतिहास मूल्यों चर के रूप में वर्तमान K लाइन BAR से पहले K लाइन BAR पर स्क्रिप्ट चल रहा है <unk>[]चर, अभिव्यक्ति, फ़ंक्शन कॉल के बाद ऑपरेटरों का उपयोग करें।[]इस वर्ग के कोष्ठक में मूल्य है कि हम संदर्भित करने के लिए ऐतिहासिक डेटा की दूरी वर्तमान K लाइन BAR की विस्थापन की मात्रा है. उदाहरण के लिए, मैं पिछले K लाइन BAR के समापन मूल्य का हवाला देते हैं, तो यह लिखा हैःclose[1]。
हमने पिछले पाठों में इस तरह के लेखन को देखा हैः
pine
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
[]ऑपरेटर को एक ही मान पर एक बार ही इस्तेमाल किया जा सकता है, इसलिए यह गलत है, यह त्रुटि देगाः
pine
a = close[1][2] // 错误
आप देख सकते हैं यहाँ, कुछ छात्रों ने कहा कि ऑपरेटर[]यह एक श्रृंखला संरचना के लिए है, यह एक श्रृंखला संरचना के समान है, और यह एक सरणी के समान है!
नीचे हम एक उदाहरण के माध्यम से पिन भाषा में श्रृंखला और सरणी के बीच अंतर को समझाते हैं।
pine
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]यह गलत हो सकता है, लेकिनः
pine
b = close[1]
c = b[1]
और यह अलग-अलग लिखने में कोई गलती नहीं है, अगर हम इसे सामान्य सरणी के अनुसार समझते हैं, तो हम इसे अलग-अलग कर सकते हैं।b = close[1]तो b एक संख्या होना चाहिए.c = b[1], b फिर से इतिहास ऑपरेटर का उपयोग करके इतिहास मानों को संदर्भित किया जा सकता है। पाइन भाषा में श्रृंखला की अवधारणा सरणी के रूप में सरल नहीं है। इसे क्लोज़ के पिछले बार पर इतिहास मान के रूप में समझा जा सकता है। यह b को एक समय अनुक्रम संरचना के रूप में भी समझा जा सकता है। और इसके इतिहास मानों को संदर्भित करना जारी रख सकता है। इसलिए हम तीन रेखाओं a, b, c में देखते हैं, b एक BAR से धीमी है, b एक BAR से धीमी है।
हम चार्ट को सबसे बाईं ओर खींच सकते हैं और देख सकते हैं कि पहली K लाइन पर, b और c के मान शून्य हैं ((na) । ऐसा इसलिए है क्योंकि जब स्क्रिप्ट पहली K लाइन BAR पर निष्पादित होती है, तो एक या दो चक्रों के इतिहास का कोई संदर्भ नहीं होता है, यह मौजूद नहीं है। इसलिए हमें लेखन रणनीति में अक्सर ध्यान देने की आवश्यकता होती है कि क्या हम ऐतिहासिक डेटा का हवाला देते समय शून्य को संदर्भित करते हैं, यदि हम सावधानी से शून्य का उपयोग नहीं करते हैं तो गणना में कई अंतर पैदा हो सकते हैं, और यह वास्तविक समय को भी प्रभावित कर सकता है। आमतौर पर हम कोड में BAR का उपयोग करते हैंna、nzतो हम पहले से ही इस तरह के एक फंक्शन के बारे में बात कर रहे हैं।nz、naफ़ंक्शंस, क्या आपको याद है कि किस अध्याय में?
pine
close > nz(close[1], open) // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量
यह एक प्रकार का व्यवहार है जो शून्य मानों को संदर्भित कर सकता है।
ऑपरेटर प्राथमिकता
हम पाइन भाषा के कई ऑपरेटरों को सीख चुके हैं, जो विभिन्न प्रकार के संयोजनों और ऑपरेशनों के माध्यम से अभिव्यक्तियों का निर्माण करते हैं। तो अभिव्यक्ति में गणना करते समय, इन ऑपरेशनों की प्राथमिकता क्या है? जैसे कि हम स्कूल में सीखे थे, चार नियम ऑपरेशन, गुणांकन को प्राथमिकता देने के लिए गुणांकन, और फिर जोड़ और घटाव की गणना करने के लिए। पाइन भाषा में अभिव्यक्ति समान है।
| प्राथमिकता | ऑपरेटर |
|---|---|
| 9 | [] |
| 8 | ``` + 、- 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 |
| 7 | *、/、% |
| 6 | द्विआधारी ऑपरेटरों के लिए +, - |
| 5 | >、<、>=、<= |
| 4 | ==、!= |
| 3 | and |
| 2 | or |
| 1 | ?: |
उच्च प्राथमिकता वाले अभिव्यक्तियों के कुछ हिस्सों को पहले संचालित किया जाता है, यदि प्राथमिकता समान है तो बाएं से दाएं संचालित किया जाता है। यदि आप किसी भाग को पहले संचालित करने के लिए मजबूर करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं()इस भाग को पहले परिचालन के लिए बाध्य करने वाले अभिव्यक्तियों को कवर करें.
चर
चर घोषणाएँ
हम पहले से ही सीख चुके हैं कि वेरिएबल्स को वेरिएबल के नाम के रूप में नामित किया जाता है। तो वेरिएबल्स को वेरिएबल्स के नाम के रूप में नामित किया जाता है। तो वेरिएबल्स को वेरिएबल्स के रूप में कैसे घोषित किया जाता है? वेरिएबल्स को कैसे घोषित किया जाता है?
-
बयान मोडः
जब हम किसी चर की घोषणा करते हैं तो सबसे पहले हम "घोषणा मोड" लिखते हैं।- कीवर्ड का उपयोग करें
var。 - खोजशब्दों का उपयोग करें
varip。 - कुछ भी नहीं लिखना।
var、varipकीवर्ड वास्तव में हम पिछले "अभिव्यक्ति ऑपरेटर" अध्याय में सीखा है, यहाँ और अधिक चर्चा नहीं की गई है. यदि चर की घोषणा मोड कुछ भी नहीं लिखते हैं, उदाहरण के लिएःi = 1, जैसा कि हमने पहले भी कहा है, इस तरह के कथन के चर और वे मूल्य हैं जो प्रत्येक K लाइन BAR पर निष्पादित किए जाते हैं. - कीवर्ड का उपयोग करें
-
प्रकार
एफएमजेड पर पाइन भाषा प्रकार की आवश्यकताओं के लिए सख्त नहीं है, और आमतौर पर इसे छोड़ दिया जा सकता है। हालांकि, ट्रेडिंग व्यू पर स्क्रिप्ट की रणनीति के अनुकूल होने के लिए, चर को घोषित करते समय प्रकार के साथ भी किया जा सकता है। उदाहरण के लिएःint i = 0 float f = 1.1ट्रेडिंग व्यू पर प्रकार की आवश्यकताएं अधिक कठोर होती हैं, यदि ट्रेडिंग व्यू पर निम्न कोड का उपयोग किया जाता है तो यह त्रुटि उत्पन्न करता हैः
baseLine0 = na // compile time error! -
पहचानकर्ता
पहचानकर्ता चर नाम है, पहचानकर्ता का नाम पिछले अध्याय में बताया गया है, इसे वापस देख सकते हैंः https://www.fmz.com/bbs-topic/9390#标识符
संक्षेप में, एक चर को घोषित करने के लिए यह लिखा जा सकता हैः
// [<declaration_mode>] [<type>] <identifier> = value
声明模式 类型 标识符 = 值
यहाँ एक असाइनमेंट ऑपरेटर का उपयोग किया गया है:=जब कोई चर घोषित किया जाता है, तो उसे एक मान दिया जाता है। मानों को स्ट्रिंग, मान, अभिव्यक्ति, फ़ंक्शन कॉल, या किसी अन्य प्रकार के रूप में दिया जाता है।if、 for、whileयाswitchआदि संरचना ((ये संरचनात्मक कुंजी शब्द, वाक्य प्रयोग हम बाद के पाठों में विस्तार से बताएंगे, वास्तव में हमने पिछले पाठों में सरल if कथन आवंटन सीखा है, इसे वापस देख सकते हैं) ।
यहाँ हम इनपुट फ़ंक्शन पर ध्यान केंद्रित करते हैं, जो एक फ़ंक्शन है जिसका उपयोग हम बहुत बार करते हैं जब हम रणनीति बनाते हैं। यह एक बहुत ही महत्वपूर्ण फ़ंक्शन है जब हम रणनीति बनाते हैं।
इनपुट फ़ंक्शन:
input函数,参数defval、title、tooltip、inline、group
एफएमजेड पर इनपुट फ़ंक्शन और ट्रेडिंग व्यू पर थोड़ा अलग है, लेकिन यह फ़ंक्शन रणनीति पैरामीटर के लिए आवंटित इनपुट के रूप में उपयोग किया जाता है। नीचे हम एक उदाहरण के माध्यम से एफएमजेड पर इनपुट फ़ंक्शन का उपयोग करने के बारे में विस्तार से बताते हैंः
pine
param1 = input(10, title="参数1名称", tooltip="参数1的描述信息", group="分组名称A")
param2 = input("close", title="参数2名称", tooltip="参数2的描述信息", group="分组名称A")
param3 = input(color.red, title="参数3名称", tooltip="参数3的描述信息", group="分组名称B")
param4 = input(close, title="参数4名称", tooltip="参数4的描述信息", group="分组名称B")
param5 = input(true, title="参数5名称", tooltip="参数5的描述信息", group="分组名称C")
ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)
एक चर को एक मूल्य देने के लिए एक चर को घोषित करते समय, अक्सर इनपुट फ़ंक्शन का उपयोग किया जाता है, जो एफएमजेड पर इनपुट फ़ंक्शन स्वचालित रूप से एफएमजेड नीति इंटरफ़ेस में एक नियंत्रण खींचता है जिसका उपयोग नीति पैरामीटर को सेट करने के लिए किया जाता है। एफएमजेड पर समर्थित नियंत्रणों में वर्तमान में संख्यात्मक इनपुट बॉक्स, पाठ इनपुट बॉक्स, ड्रॉपडाउन बॉक्स, और बुल मान चिह्न हैं। और नीति पैरामीटर समूह को सेट करने और पैरामीटर सेट करने के लिए संकेत पाठ जानकारी जैसे कार्य कर सकते हैं।
हम इनपुट फ़ंक्शन के कुछ मुख्य पैरामीटर के बारे में बात करते हैंः
- defval: इनपुट फ़ंक्शन के लिए नीति पैरामीटर विकल्प का डिफ़ॉल्ट मान, जो पाइन भाषा के अंतर्निहित चर, मान और स्ट्रिंग का समर्थन करता है
- title: नीति का नाम जो नीति इंटरफ़ेस पर प्रदर्शित होता है।
- टूलटिपः नीति पैरामीटर के लिए संकेत, जब माउस को नीति पैरामीटर पर लटका दिया जाता है, तो यह पैरामीटर सेट की टेक्स्ट जानकारी प्रदर्शित करता है।
- group: नीति पैरामीटर समूह का नाम, जिसे आप पैरामीटर समूहों को दे सकते हैं
व्यक्तिगत चर घोषणाओं के अलावा, पाइन भाषा में चरों के एक समूह को घोषित करने और उन्हें मूल्य देने के लिए एक और तरीका हैः
[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构
सबसे आम है कि हम उपयोग करते हैंta.macdफ़ंक्शन MACD सूचकांक की गणना करता है, क्योंकि MACD सूचकांक एक बहु-पंक्ति सूचकांक है, डेटा के तीन सेटों की गणना करता है। इसलिए इसे लिखा जा सकता हैः
pine
[dif,dea,column] = ta.macd(close, 12, 26, 9)
plot(dif, title="dif")
plot(dea, title="dea")
plot(column, title="column", style=plot.style_histogram)
हम ऊपर दिए गए कोड का उपयोग करके MACD ग्राफ को आसानी से तैयार कर सकते हैं, न केवल अंतर्निहित फ़ंक्शन कई चर वापस कर सकते हैं, बल्कि कस्टम फ़ंक्शन भी कई डेटा वापस कर सकते हैं।
pine
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)
if जैसी संरचनाओं को कई चर के रूप में लिखने का तरीका ऊपर दिए गए कस्टम फ़ंक्शन के समान है, और यदि आप रुचि रखते हैं, तो आप कोशिश कर सकते हैं।
[ema10, ema20] = if true
fast = ta.ema(close, 10)
slow = ta.ema(close, 20)
[fast, slow]
plot(ema10, title="ema10", color=color.fuchsia, overlay=true)
plot(ema20, title="ema20", color=color.aqua, overlay=true)
सशर्त संरचना
कुछ फ़ंक्शंस को सशर्त शाखाओं के स्थानीय कोड ब्लॉक में नहीं लिखा जा सकता है, मुख्यतः निम्नलिखित फ़ंक्शंसः
barcolor(), fill(), hline(), indicator(), plot(), plotcandle(), plotchar(), plotshape()
ट्रेडिंग व्यू पर त्रुटि रिपोर्ट संकलित करता है। एफएमजेड पर प्रतिबंध उतना सख्त नहीं है, लेकिन ट्रेडिंग व्यू पर नियमों का पालन करने की भी सलाह दी जाती है। उदाहरण के लिए, एफएमजेड पर त्रुटि रिपोर्ट नहीं है, लेकिन यह अनुशंसित नहीं है।
pine
strategy("test", overlay=true)
if close > open
plot(close, title="close")
else
plot(open, title="open")
if कथन
उदाहरण के लिएः
pine
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)
महत्वपूर्णः निर्णय करने के लिए अभिव्यक्ति, बूल मान लौटाएँ <unk> ध्यान दें कि स्क्रॉल <unk> अधिकतम केवल एक अन्य शाखा हो सकती है <unk> सभी शाखाओं के लिए अभिव्यक्ति सत्य नहीं है, और यदि कोई अन्य शाखा नहीं है, तो यह na <unk> लौटाता है <unk>
pine
x = if close > open
close
plot(x, title="x")
क्योंकि जब K लाइन BAR शून्य रेखा होती है, अर्थात जब close < open, if कथन के बाद अभिव्यक्ति false है, तो if का स्थानीय कोड ब्लॉक निष्पादित नहीं किया जाता है। इस समय कोई अन्य शाखा नहीं है, if कथन वापस आ जाता है। x को na के रूप में सौंपा गया है। यह बिंदु चित्र पर नहीं खींचा जा सकता है, हम इसे चित्र चित्र के माध्यम से भी देख सकते हैं।
स्विच कथन
स्विच स्टेटमेंट भी एक शाखा संरचना वाले स्टेटमेंट हैं, जिन्हें कुछ शर्तों के अनुसार विभिन्न रास्तों को निष्पादित करने के लिए डिज़ाइन किया गया है। स्विच स्टेटमेंट में आम तौर पर निम्नलिखित महत्वपूर्ण ज्ञान बिंदु होते हैंः
1। स्विच कथन एक if कथन की तरह ही मान देता है।
2. अन्य भाषाओं के स्विच कथन के विपरीत, स्विच संरचना को निष्पादित करते समय, केवल इसके कोड में एक स्थानीय ब्लॉक निष्पादित किया जाता है, इसलिए ब्रेक घोषणा की आवश्यकता नहीं है (यानी, ब्रेक जैसे कीवर्ड लिखने की आवश्यकता नहीं है) ।
3. switch की प्रत्येक शाखा में एक स्थानीय कोड ब्लॉक लिखा जा सकता है, और इस स्थानीय कोड ब्लॉक की अंतिम पंक्ति को मान के रूप में लौटाया जा सकता है (यह मान का एक उपसमूह हो सकता है) । यदि कोई भी शाखा नहीं है तो स्थानीय कोड ब्लॉक निष्पादित किया जाता है।
4. स्विच संरचना में अभिव्यक्ति निर्णय स्थान, स्ट्रिंग, चर, अभिव्यक्ति या फ़ंक्शन कॉल लिख सकते हैं <unk>
5। स्विच एक रिटर्न मान निर्दिष्ट करने की अनुमति देता है, जो संरचना में कोई अन्य स्थिति नहीं होने पर डिफ़ॉल्ट मान के रूप में उपयोग किया जाता है।
स्विच दो प्रकार के होते हैं, आइए एक-एक करके उदाहरण देखें और जानें कि वे कैसे काम करते हैं।
- एक अभिव्यक्ति के साथ
switchउदाहरण के लिएः
pine
// 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](ध्यान दें कि एक स्ट्रिंग प्रकार है, और एक संख्यात्मक प्रकार है) । इस तरह से, नीति इंटरफ़ेस पर नियंत्रण को विशिष्ट संख्यात्मक मान दर्ज करने की आवश्यकता नहीं है, लेकिन नियंत्रण नीचे ड्रॉबॉक्स में बदल जाता है, विकल्प विकल्पों में दिए गए विकल्पों का चयन करता है।
एक चर फ़ंक्शन का मान एक स्ट्रिंग है, फ़ंक्शन फ़ंक्शन स्विच के रूप में एक अभिव्यक्ति के रूप में है, यह निर्धारित करने के लिए कि स्विच में कौन सी शाखा निष्पादित की जाएगी। यदि फ़ंक्शन फ़ंक्शन स्विच में किसी भी शाखा पर अभिव्यक्ति के साथ मेल नहीं खा सकता है, तो डिफ़ॉल्ट शाखा कोड ब्लॉक निष्पादित किया जाएगा।runtime.error("error")फ़ंक्शंस के कारण नीति को असामान्य छोड़ना बंद कर दिया गया
हमारे ऊपर परीक्षण कोड में स्विच के डिफ़ॉल्ट शाखा कोड ब्लॉक के अंतिम पंक्ति runtime.error के बाद, हम शामिल नहीं है[na, na] इस तरह के कोड के लिए संगत वापसी मूल्य, ट्रेडिंग दृश्य पर इस समस्या पर विचार करने की आवश्यकता है, यदि प्रकार असंगत है तो त्रुटि का भुगतान करेगा। लेकिन एफएमजेड पर कोई सख्त आवश्यकता प्रकार नहीं है, इसलिए इस तरह के संगत कोड को छोड़ दिया जा सकता है। इसलिए एफएमजेड पर if, switch शाखा वापसी मूल्य के प्रकार संगतता पर विचार करने की आवश्यकता नहीं है।
pine
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 शाखाओं का प्रकार असंगत है।
- बिना किसी अभिव्यक्ति के
switch
हम देखेंगेswitchएक अन्य उपयोग, बिना अभिव्यक्ति के लेखन।
pine
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 टिप्पणी में परिवर्तित करें, और परिणामों को देखने के लिए वापस जाएं। आपको पता चलेगा कि स्विच शाखा केवल पहली शाखा को निष्पादित कर सकती है। इसके अलावा, यह ध्यान देने की आवश्यकता है कि स्विच शाखा में फ़ंक्शन को कॉल न करें। प्रत्येक BAR पर फ़ंक्शन को कॉल नहीं किया जा सकता है, जो कुछ डेटा गणना समस्याओं का कारण बन सकता है।switchउदाहरण में, निष्पादन शाखा निश्चित है और रणनीति के संचालन में इसे बदला नहीं जा सकता है) ।
चक्रीय संरचना
for वाक्य
返回值 = for 计数 = 起始计数 to 最终计数 by 步长
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
for कथन का उपयोग करना बहुत सरल है, for loop अंततः एक मान वापस कर सकता है ((या कई मान वापस कर सकता है,[a, b, c] के रूप में) ∙ जैसे कि उपरोक्त फ़ॉक्स कोड में "रिटर्न वैल्यू" स्थिति को असाइन किया गया चर ∙ for कथन के बाद एक "काउंट" चर का पालन किया जाता है, जिसका उपयोग चक्र की संख्या को नियंत्रित करने, अन्य मानों को संदर्भित करने आदि के लिए किया जाता है ∙ "काउंट" चर को चक्र शुरू होने से पहले "प्रारंभिक गणना" के रूप में असाइन किया जाता है, फिर "गति" सेटिंग के अनुसार वृद्धि होती है, और जब "काउंट" चर "अंतिम गणना" से बड़ा होता है, तो चक्र बंद हो जाता है ∙
for चक्र में प्रयुक्तbreakकीवर्डः जब यह किया जाता हैbreakऔर फिर चक्र बंद हो जाता है।
for चक्र में प्रयुक्तcontinueकीवर्डः जब यह किया जाता हैcontinueवाक्य के बाद, चक्र को अनदेखा करेंcontinueइसके बाद, कोड सीधे अगले चक्र को निष्पादित करता है। for कथन अंतिम चक्र निष्पादन के लिए लौटाया गया मान देता है। यदि कोई कोड निष्पादित नहीं किया गया है, तो शून्य लौटाता है।
नीचे हम एक सरल उदाहरण के साथ दिखाएंगेः
pine
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वाक्य दो प्रकार के होते हैं, और निम्न काल्पनिक कोड इसे स्पष्ट करता है:
返回值 = for 数组元素 in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
जैसा कि आप देख सकते हैं, दो रूपों के बीच मुख्य अंतर यह है कि for कीवर्ड के बाद क्या होता है, एक है कि एक चर का उपयोग सरणी तत्वों के संदर्भ के रूप में किया जाता है। एक है कि एक सूचकांक चर, सरणी तत्वों के चर के एक उपसमूह की संरचना का उपयोग किया जाता है। दूसरे में, वापसी मान नियम, ब्रेक, जारी रखने जैसे नियम और for चक्र के अनुरूप हैं। हम एक सरल उदाहरण के साथ उपयोग की व्याख्या करते हैं।
pine
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। औसत गणना
चक्रवाचक संरचना डिजाइन का उपयोग करते समयः
pine
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 पुनरावर्ती योग का उपयोग किया गया है, और फिर औसत की गणना की गई है।
इनपुट फ़ंक्शन का उपयोग करके औसत रेखा की गणना करेंः
pine
plot(ta.sma(close, length), title="ta.sma", overlay=true)
सीधे अंतर्निहित फ़ंक्शन का उपयोग करेंta.sma, औसत रेखा सूचक की गणना, स्पष्ट रूप से औसत रेखा की गणना करने के लिए अंतर्निहित फ़ंक्शन का उपयोग करना आसान है.
- योग
या ऊपर दिए गए उदाहरणों का उपयोग करें।
चक्रवाचक संरचना डिजाइन का उपयोग करते समयः
pine
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क्या आप जानते हैं?
एक अंतर्निहित फ़ंक्शन का उपयोग करके सीधे जोड़ की गणना करेंः
pine
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. पिन भाषा के अंतर्निहित फ़ंक्शंस द्वारा पिछले BAR की गणना नहीं की जा सकती है।
while वाक्य
whileकथन जो कोड को लूप के हिस्से के रूप में निष्पादित करता है जब तक कि while संरचना में निर्णय की शर्त झूठी (false) न हो जाए।
返回值 = while 判断条件
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
while के अन्य नियम for loop के समान हैं, loopbody के स्थानीय कोड ब्लॉक की अंतिम पंक्ति एक रिटर्न मान है, जो कई मानों को वापस कर सकता है। loop को तब निष्पादित किया जाता है जब "loop condition" सही है, और जब यह false है तो loop को रोक दिया जाता है। loopbody में break, continue वाक्य का भी उपयोग किया जा सकता है।
मैं इसे एक उदाहरण के साथ दिखाऊंगाः
pine
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)
जैसा कि आप देख सकते हैं, while loop का उपयोग करना भी बहुत आसान है, और कुछ गणना तर्क को डिज़ाइन किया जा सकता है जिन्हें अंतर्निहित फ़ंक्शन द्वारा प्रतिस्थापित नहीं किया जा सकता है, उदाहरण के लिए चरण गुणा गणनाः
pine
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
समूह
पाइन भाषा में सरणी और अन्य प्रोग्रामिंग भाषाओं में सरणी की परिभाषा के समान, पाइन की सरणी एक आयामी सरणी है। यह आमतौर पर लगातार डेटा की एक श्रृंखला को संग्रहीत करने के लिए उपयोग किया जाता है। सरणी जिसमें संग्रहीत एकल डेटा को सरणी के तत्व कहा जाता है, इन तत्वों के प्रकार हो सकते हैंः पूर्णांक, फ्लोट प्रकार, स्ट्रिंग, रंग मान, बुल मान। एफएमजेड पर पाइन भाषा में प्रकार की बहुत सख्त आवश्यकता नहीं है, और यहां तक कि एक सरणी में स्ट्रिंग और संख्या मान भी संग्रहीत किया जा सकता है। चूंकि संख्याओं की सरणी का आधार भी एक श्रृंखला संरचना है, यदि इतिहास ऑपरेटर का उपयोग किया जाता है तो पिछले बार पर सरणी की स्थिति का हवाला दिया जाता है। इसलिए किसी तत्व को संदर्भित करते समय इतिहास ऑपरेटर का उपयोग नहीं किया जाता है[]लेकिन उपयोग करने की आवश्यकता हैarray.get()औरarray.set()फ़ंक्शन 。 सरणी में तत्वों का अनुक्रमण क्रम है, जो सरणी के पहले तत्व का अनुक्रमण 0 है और अगले तत्व का अनुक्रमण 1 बढ़ता है 。
हम इसे एक सरल कोड में समझाते हैंः
pine
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एक सरणी को केवल एक चर के रूप में घोषित किया जा सकता है, जैसे किः
pine
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फ़ंक्शंस <unk> पिन भाषा में और भी बहुत सारे प्रकार से संबंधित फ़ंक्शंस हैं जो array.new के समान हैंःarray.new_int()、array.new_bool()、array.new_color()、array.new_string()इंतज़ार।
var कुंजी शब्द भी एक सरणी के घोषणा मोड के साथ काम कर सकता है, जो कि var कुंजी शब्द का उपयोग करता है और केवल पहले BAR पर आरंभ किया जाता है। हम एक उदाहरण के माध्यम से देखते हैंः
pine
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")
यह देखा जा सकता है कि a सरणी के परिवर्तनों को लगातार निर्धारित किया जाता है, और उन्हें पुनर्स्थापित नहीं किया जाता है। b सरणी को प्रत्येक BAR पर आरंभ किया जाता है। अंततःbarstate.islastवास्तविक समय में प्रिंट करने के लिए केवल एक तत्व है, 0 <unk>.
सरणी में तत्वों को पढ़ना और लिखना
array.get का उपयोग array में निर्दिष्ट अनुक्रमण स्थान के तत्वों को प्राप्त करने के लिए करें और array.set का उपयोग array में निर्दिष्ट अनुक्रमण स्थान के तत्वों को संशोधित करने के लिए करें।
array.get का पहला पैरामीटर संसाधित की जाने वाली सरणी है, दूसरा पैरामीटर निर्दिष्ट सूचकांक है।
array.set का पहला पैरामीटर संसाधित करने के लिए सरणी है, दूसरा पैरामीटर निर्दिष्ट सूचकांक है, और तीसरा पैरामीटर लिखने के लिए तत्व है।
एक सरल उदाहरण का उपयोग करेंः
pine
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 वाक्यों का उपयोग कर सकते हैं जिन्हें हमने पहले सीखा था।
pine
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")
pine
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")
pine
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")
इन तीनों में भी एक ही परिणाम मिलता है।
सरणी को स्क्रिप्ट के वैश्विक दायरे में घोषित किया जा सकता है या फ़ंक्शन या if शाखा के स्थानीय दायरे में घोषित किया जा सकता है
ऐतिहासिक डेटा
सरणी में तत्वों के उपयोग के लिए, निम्नलिखित तरीका समतुल्य है, हम निम्नलिखित उदाहरण के माध्यम से देख सकते हैं कि हम चार्ट पर दो समूहों को रेखांकित करते हैं, प्रत्येक समूह में दो, प्रत्येक समूह में दो पंक्तियों का मान बिल्कुल समान है।
pine
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()。
हम निम्नलिखित उदाहरणों का उपयोग करके इन सरणियों के जोड़ और घटाव कार्यों का परीक्षण करते हैं:
pine
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")
जोड़ें, हटाएं अनुप्रयोगोंः सरणी के रूप में कतार
सरणी का उपयोग करके, और सरणी के कुछ जोड़ और हटाने के कार्यों का उपयोग करके, हम एक "टेक" डेटा संरचना का निर्माण कर सकते हैं। एक टीक मूल्य के लिए एक चलती औसत की गणना करने के लिए एक टीक का उपयोग किया जा सकता है, और कुछ छात्र पूछ सकते हैं, "क्यों हम एक टीक संरचना का निर्माण करते हैं? क्या हम पहले सरणी का उपयोग नहीं कर सकते थे? क्या हम औसत गणना कर सकते हैं? "
एक कतार एक संरचना है जो अक्सर प्रोग्रामिंग में उपयोग की जाती है।
पहले कतार में प्रवेश करने वाले तत्व, पहले कतार से बाहर निकलें <unk
इस प्रकार यह सुनिश्चित किया जा सकता है कि कतार में मौजूद डेटा नवीनतम डेटा है और कतार की लंबाई असीम रूप से विस्तारित नहीं होगी (असीम रूप से विस्तारित कोड केवल दोपहर के समय लिखा जा सकता है, क्योंकि सुबह-शाम और शाम-शाम में समस्याएं हो सकती हैं) ।
निम्नलिखित उदाहरण में हम एक कतारबद्ध संरचना का उपयोग करते हैं जो प्रत्येक टिक की कीमतों को रिकॉर्ड करता है, टिक स्तर पर एक चलती औसत की गणना करता है, और फिर इसे 1 मिनट के लाइन स्तर पर एक चलती औसत के साथ तुलना करता है।
pine
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 सरणी हम घोषणा मोड निर्दिष्ट करते हैं, हम कुंजी शब्द का उपयोग करते हैंvaripइस प्रकार, प्रत्येक मूल्य परिवर्तन को एक सरणी में दर्ज किया जाता है।
सामान्य रूप से उपयोग किए जाने वाले सरणी गणना, संचालन फ़ंक्शन
संबंधित फ़ंक्शंस की गणना करेंः
array.avg()सभी तत्वों का औसत ज्ञात कीजिएarray.min()और फिर हम सबसे छोटे तत्व को खोजते हैं.array.max()अब हम array में सबसे बड़ा element ढूंढते हैं.array.stdev()सभी तत्वों के लिए मानक अंतर ज्ञात कीजिएarray.sum()सरणी में सभी तत्वों का योग ज्ञात कीजिए.
संचालित करने के लिए संबंधित फ़ंक्शनः
array.concat()दो सरणियों को जोड़ना या जोड़ना।
array.copy()array को डुप्लिकेट करें
array.joinसभी तत्वों को एक स्ट्रिंग में जोड़ें
array.sort()क्रमशः क्रम में वृद्धि या गिरावट
array.reverse()उलटा सरणी
array.slice()सरणी को काटें
array.includes()निर्णय तत्व
array.indexof()लौटाता है कि पैरामीटर के लिए दर्ज किया गया मान पहली बार दिखाई देता है। यदि यह नहीं मिला है, तो -1 लौटाएं।
array.lastindexof()अंतिम बार दिखाई देने वाला मान ढूंढें
एरे के लिए संबंधित फ़ंक्शंस का परीक्षण उदाहरणः
pine
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")
ये सभी अधिक प्रचलित सरणीगणित फलन हैं।
ऑपरेटिंग फ़ंक्शंस के उदाहरण:
pine
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")
समारोह
कस्टम फ़ंक्शन
पाइन भाषा में कस्टम फ़ंक्शंस को डिज़ाइन किया जा सकता है, और आम तौर पर पाइन भाषा में कस्टम फ़ंक्शंस के लिए निम्नलिखित नियम होते हैंः
- सभी फ़ंक्शंस को स्क्रिप्ट के वैश्विक दायरे में परिभाषित किया गया है। एक फ़ंक्शन को किसी अन्य फ़ंक्शन में घोषित नहीं किया जा सकता है।
- फ़ंक्शन को अपने स्वयं के कोड में अपने आप को कॉल करने की अनुमति नहीं है ((रिवर्स)) ।
- सिद्धांत रूप में सभी PINE भाषाओं में अंतर्निहित चित्र फ़ंक्शन ((
barcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()) को कस्टम फ़ंक्शन के भीतर नहीं बुलाया जा सकता. - फ़ंक्शंस को एक पंक्ति या कई पंक्तियों में लिखा जा सकता है। अंतिम वाक्य का रिटर्न मान वर्तमान फ़ंक्शन रिटर्न मान है, और रिटर्न मान एटॉमिक रूप में वापस किया जा सकता है।
पिछले ट्यूटोरियल में हमने कई बार कस्टम फ़ंक्शंस का उपयोग किया है, जैसे कि कस्टम फ़ंक्शंस को एक पंक्ति में डिज़ाइन करनाः
pine
barIsUp() => close > open
यह फ़ंक्शन बताता है कि क्या वर्तमान BAR सूर्य का है.
बहु-पंक्ति कस्टम फ़ंक्शन के रूप में डिज़ाइन किया गयाः
pine
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)
हम अपने स्वयं के कस्टम फ़ंक्शन के साथ लागू एक sma औसत रेखा परिकलन फ़ंक्शन <unk>
इसके अलावा, हम दो चर के लिए एक कस्टम फ़ंक्शन उदाहरण लौटा सकते हैंः
pine
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 स्क्रिप्टपूछताछ
Pine भाषा में निर्मित फ़ंक्शन वर्गीकरणः
- स्ट्रिंग प्रोसेसिंग फ़ंक्शन
str.श्रृंखला - रंग मान संसाधित करें
color.श्रृंखला
3। पैरामीटर इनपुट फ़ंक्शनinput.श्रृंखला - सूचकांक गणना कार्य
ta.श्रृंखला
5। रेखाचित्र फ़ंक्शनplot.श्रृंखला
6। सरणी प्रसंस्करण फलनarray.श्रृंखला
7 लेनदेन से संबंधित कार्यstrategy.श्रृंखला
8। गणितीय संचालन से संबंधित फ़ंक्शनmath.श्रृंखला
9, अन्य फ़ंक्शंस ((समय प्रसंस्करण, गैर-प्लॉट श्रृंखला रेखाचित्र फ़ंक्शंस,request.श्रृंखला फ़ंक्शंस, प्रकार प्रसंस्करण फ़ंक्शंस आदि) <unk>
लेन-देन फ़ंक्शन
strategy.श्रृंखला फ़ंक्शंस फ़ंक्शंस हैं जो हम अक्सर डिजाइन रणनीतियों में उपयोग करते हैं, जो फ़ंक्शंस और रणनीतियों से संबंधित हैं जब वे चलती हैं तो लेनदेन संचालन करते हैं।
1、strategy.entry
strategy.entryफ़ंक्शंस एक ऑर्डर फ़ंक्शंस है जो हमारे लिए महत्वपूर्ण है जब हम एक रणनीति लिखते हैं। फ़ंक्शंस के कुछ महत्वपूर्ण पैरामीटर हैंःid, direction, qty, whenइंतज़ार।
पैरामीटर:
id: किसी ट्रेडिंग पोजीशन को एक नाम देने के लिए संदर्भ के रूप में समझा जा सकता है। इस आईडी को ऑर्डर को रद्द करने, संशोधित करने, और स्थिति को स्पष्ट करने के लिए संदर्भित किया जा सकता है।direction: यदि आदेश दिशा अधिक करने के लिए है ((खरीद) इस पैरामीटर को पारितstrategy.longइस अंतर्निहित चर, अगर यह खाली करने के लिए है (बिक्री)strategy.shortयह चर:qty: आदेश की मात्रा निर्दिष्ट करें, यदि यह पैरामीटर पास नहीं किया जाता है तो डिफ़ॉल्ट आदेश की मात्रा का उपयोग किया जाता हैwhen: निष्पादन की शर्तें, आप इस पैरामीटर को यह नियंत्रित करने के लिए निर्दिष्ट कर सकते हैं कि वर्तमान आदेश कार्रवाई ट्रिगर की गई है या नहीं।limitआदेश सीमा मूल्य निर्दिष्ट करें:stopस्टॉप-लॉस प्राइस
strategy.entryफ़ंक्शन के विशिष्ट निष्पादन विवरणstrategyफ़ंक्शन कॉल पर पैरामीटर सेटिंग नियंत्रण, या"Pine भाषा विनिमय वर्ग पुस्तकालय मॉड्यूल पैरामीटर"विन्यास नियंत्रण, पाइन भाषा लेन-देन वर्ग पुस्तकालय मॉड्यूल पैरामीटर नियंत्रण के लेन-देन के बारे में अधिक जानकारी के लिए, आप इस लिंक पर दिए गए दस्तावेज़ को देख सकते हैं।
मैं आपको बताता हूं कि यह कैसे किया जाता है।strategyफ़ंक्शन में,pyramiding、default_qty_valueपैरामीटर: निम्नलिखित कोड का उपयोग करके परीक्षण करेंः
pine
/*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 बार से अधिक सेट नहीं किया है। तो हम उदाहरण में चार बारstrategy.entryनीचे दिए गए ऑपरेशन में से एक को निष्पादित नहीं किया गया है.default_qty_valueपैरामीटर 0.1 है, तो आईडी के रूप में चिह्नित किया गया हैstrategy.entryनिम्न आदेश ऑपरेशन के लिए निम्न आदेश डिफ़ॉल्ट रूप से 0.1 <unk> है.strategy.entryफ़ंक्शन कॉल के दौरान हम निर्दिष्ट करते हैंdirectionके बराबरstrategy.longतो, जब आप एक परीक्षण करते हैं, तो आप भुगतान करते हैं।
कोड में ध्यान देंstrategy.entry("long3", ...निम्न आदेश दो बार बुलाया गया था, एक ही आईडी के लिएः <unk>long3<unk>strategy.entryआदेश विफल, दूसरा कॉलstrategy.entryफ़ंक्शन इस आईडी के ऑर्डर को संशोधित करने के लिए है ((रिवाइंडिंग टेस्ट के दौरान दिखाए गए डेटा को भी देखा जा सकता है कि इस सीमा आदेश के तहत ऑर्डर की मात्रा को 0.3 के लिए संशोधित किया गया है) । एक अन्य स्थिति, उदाहरण के लिए यदि पहली बार आईडी के लिए ऑर्डर किया गया था, तो इस लेनदेन के अनुसार आईडी का उपयोग करना जारी रखें।strategy.entryफ़ंक्शन ऑर्डर करता है, तो ऑर्डर पोजीशन ID<unk>long3<unk> पर जमा होती है <unk>
2、strategy.close
strategy.closeफ़ंक्शन का उपयोग प्रवेश के लिए किया जाता है, जो ID को निर्दिष्ट करता है। इसके मुख्य पैरामीटर हैंःid,when,qty,qty_percent。
पैरामीटर:
idहम अपने ग्राहकों के साथ बातचीत कर रहे हैं, और हम उनके साथ बातचीत कर रहे हैं, और हम उनके साथ बातचीत कर रहे हैं।strategy.entryप्रवेश के लिए आदेश फ़ंक्शन को खोलने के समय निर्दिष्ट आईडी <unk>whenकार्यवाही की शर्तें:qty: बकाया राशिqty_percent: बराबरी का प्रतिशत.
इस फ़ंक्शन का उपयोग करने के विवरण के लिए एक उदाहरण देखेंः
कोड में/*backtest ... */FMZ.COM इंटरनेशनल स्टेशन रिट्रेसमेंट के समय की कॉन्फ़िगरेशन जानकारी है, जिसे हटाया जा सकता है, अपने द्वारा परीक्षण किए जाने वाले बाजार, किस्म, समय सीमा आदि की जानकारी सेट करें।
pine
/*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
परीक्षण रणनीति में दिखाया गया है कि तीन बार लगातार कई प्रविष्टियां शुरू की गईं, जिनमें से प्रत्येक में प्रविष्टि आईडी <unk>long1<unk> थी, और फिर उपयोग किया गयाstrategy.closeफ़ंक्शन के अलग-अलग पैरामीटर को समतल स्थिति में सेट करते समय वापस मापा गया अलग-अलग परिणामों की खोज की जा सकती है।strategy.closeइस फंक्शन में कोई पैरामीटर नहीं है जो ब्लीचिंग के लिए नीचे की कीमत निर्दिष्ट करता है, यह फंक्शन मुख्य रूप से तत्काल ब्लीचिंग के लिए वर्तमान बाजार मूल्य पर उपयोग किया जाता है।
3、strategy.close_all
strategy.close_allफ़ंक्शन का उपयोग सभी वर्तमान होल्डिंग्स को समतल करने के लिए किया जाता है, क्योंकि पाइन भाषा स्क्रिप्ट केवल एक दिशा में होल्डिंग्स रख सकती है, यानी यदि वर्तमान होल्डिंग्स की दिशा के विपरीत संकेत ट्रिगर किया जाता है तो वर्तमान होल्डिंग्स को समतल कर दिया जाएगा और सिग्नल के अनुसार स्थिति को ट्रिगर किया जाएगा। इसलिए।strategy.close_allजब यह बुलाया जाता है, तो यह वर्तमान दिशा में सभी पदों को खाली कर देता है।strategy.close_allफ़ंक्शन के मुख्य पैरामीटर हैंःwhen。
पैरामीटर:
whenकार्यवाही की शर्तें:
हम एक उदाहरण का उपयोग करते हुए देखेंगेः
pine
/*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_size0 से बड़ा है, तो आईडी के लिए shorted के लिए प्रवेश फ़ंक्शन को निष्पादित किया जा सकता है, क्योंकि वर्तमान में बहुहेड पदों की स्थिति है, इस समय दिखाई देने वाला कमोडिटी रिवर्स सिग्नल बहुहेड पदों को खाली करने के बाद रिवर्स को खाली करने का कारण बनता है। फिर हम लिखते हैं कि यदि स्थिति में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 <unk>profit: लाभ लक्ष्य, अंक में दर्शाया गया <unk>loss: रोकना लक्ष्य, अंक में दर्शाया गया <unk>limit: मुनाफा लक्ष्य, कीमत के साथ निर्दिष्ट <unk>stop: स्टॉप लॉस लक्ष्य, मूल्य निर्दिष्ट करें <unk>whenकार्यवाही की शर्तें:
प्रत्येक पैरामीटर के उपयोग को समझने के लिए एक परीक्षण रणनीति का उपयोग करें।
pine
/*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语言模板参数上「定价货币精度」参数设置有关
वास्तविक समय मूल्य मॉडल के साथ एक प्रतिक्रिया परीक्षण, इस परीक्षण रणनीति के साथ शुरू किया गया था 3 प्रवेश संचालन (strategy.entryफ़ंक्शन), <unk>long1 <unk>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कार्यवाही की शर्तें:
यह फ़ंक्शन बहुत अच्छी तरह से समझा जाता है कि यह बिना किसी लेनदेन के प्रवेश आदेश को रद्द करने के लिए है।
pine
/*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फ़ंक्शंस की तरह <unk> सभी पूर्व-अस्थायी आदेशों को रद्द / निष्क्रिय करना <unk> निर्दिष्ट किया जा सकता हैwhenपैरामीटर
पैरामीटर:
whenकार्यवाही की शर्तें:
pine
/*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सशर्त आउटफील्ड फ़ंक्शन. एक स्क्रिप्ट जो एक ग्रिड-जैसे लेनदेन का निर्माण करता है. उदाहरण बहुत सरल है, केवल सीखने के लिएः
pine
/*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)
रणनीति के उदाहरण
इस ट्यूटोरियल में रणनीति के उदाहरण केवल शिक्षण रणनीति, मार्गदर्शन रणनीति डिजाइन विचार के लिए उपयोग किया जाता है, किसी भी व्यापार मार्गदर्शन, सलाह नहीं है। शिक्षण रणनीति का उपयोग न करें।
सुपर ट्रेंड सूचक रणनीति
pine
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समारोह
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
inputफ़ंक्शन कॉल सीधे के रूप में प्रयोग किया जाता हैta.supertrendसूचक फ़ंक्शन के पैरामीटर सुपरट्रेंड सूचक की गणना करने के लिए उपयोग किए जाते हैं। इनमें सेः
- input(5, "factor")
- input.int(10, "atrPeriod")
फ़ंक्शन डिफ़ॉल्ट रूप से पाइन भाषा नीति इंटरफ़ेस पर दो पैरामीटर नियंत्रण सेट करता है, जैसा कि चित्र में दिखाया गया हैः
आप देख सकते हैं कि डिफ़ॉल्ट नियंत्रण हैinputकार्य औरinputश्रृंखला फ़ंक्शन हैinput.int) का पहला पैरामीटर है, जो पिछले अध्यायों में भी बताया गया है. इन दोनों फंक्शन्स के माध्यम से हम नीति इंटरफ़ेस पर सेट कर सकते हैंta.supertrendफ़ंक्शन के लिए पैरामीटर है. सुपर ट्रेंड सूचक फ़ंक्शन एक मूल्य डेटा की गणना करता हैsupertrendऔर एक दिशा डेटाdirectionऔर फिर उपयोग करेंplotफ़ंक्शनल आरेख, ध्यान दें कि आरेख को सुपरट्रेंड सूचकांक की दिशा के आधार पर आरेखित किया जाए, केवल वर्तमान दिशा को आरेखित करें।directionयदि वर्तमान प्रवृत्ति ऊपर की ओर है, तो वर्तमान प्रवृत्ति नीचे की ओर है।directionतो हम देख सकते हैं कि यह एक घंटे के लिए नीचे की ओर है।plotफ़ंक्शन को चित्रित करते समय निर्णय लेंdirection0 से बड़ा, 0 से छोटा
अगलाif ... else ifतर्क एक व्यापारिक संकेत का निर्णय है, जब अभिव्यक्तिdirection < 0वास्तविक समय के लिए वर्तमान स्थिति को ऊपर की ओर इंगित करता है, जब सुपरट्रेंड सूचक में मूल्य डेटाsupertrendसुपर ट्रेंड सूचक मूल्य से ऊपर 2 बार की ओर (यानीsupertrend[2],还记得历史操作符引用某个变量历史数据吧) इसे अधिक प्रवेश संकेत के रूप में लें <unk> याद है? यदि वर्तमान में कोई स्थिति है, तो इस समय रिवर्स ऑर्डर फंक्शन कॉल पहले पहले की स्थिति को खत्म कर देगा, और फिर वर्तमान व्यापार दिशा के अनुसार स्थिति खोलेगा <unk>supertrend > supertrend[2]शर्तों को पूरा नहीं किया गया है,strategy.position_size < 0और यह भी कि एक खाली पद के साथ, यह भी ट्रिगर हो सकता हैstrategy.close_all()फ़ंक्शन निष्पादन, पूरी तरह से ब्लीच करने के लिए <unk>
direction > 0जब हम एक गिरावट की स्थिति में होते हैं, तो यह भी एक ही बात है, अगर हमारे पास कई हैं, तो हम सभी को खाली कर देंगे और फिर हम पात्र होंगेsupertrend < supertrend[3]तो यहाँ क्यों यह सेट है[3]क्या सुपरट्रेंड सूचकांक की कीमतों के आंकड़ों का उल्लेख करने के लिए पिछले तीसरे BAR पर? यह रणनीति के लेखक का इरादा हो सकता है, क्योंकि कुछ बाजारों में, जैसे कि अनुबंध व्यापार बाजार में, जोखिम को कम करने का जोखिम अधिक जोखिम लेने से थोड़ा अधिक है।
के लिएta.supertrendक्या कुछ छात्रों को इस बात में दिलचस्पी है कि यह कैसे पता चलता है कि वर्तमान रुझान ऊपर जा रहा है या नीचे?
वास्तव में, यह सूचक पाइन भाषा के एक कस्टम फ़ंक्शन के रूप में भी लागू किया जा सकता हैः
pine
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 से विभाजित करें, जो कि उच्चतम मूल्य के निम्नतम मूल्य का औसत है), फिर एक निश्चित अवधि के लिए एटीआर संकेतक की गणना करें, जो कि पैरामीटरatrPeriod के आधार पर है ((वेव आयाम)) । फिर hl2 और एटीआर का उपयोग करके अपट्रेल, डाउनट्रेल का निर्माण करें ।
कोड में त्रिकोण अभिव्यक्ति के आधार पर अद्यतनlowerBandऔरupperBand。
pine
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: नीचे की पट्टी, यह निर्धारित करने के लिए कि क्या ऊपर की ओर रुझान बदल रहा है. upperBand: ऊपर की पट्टी, यह निर्धारित करने के लिए कि क्या नीचे की ओर रुझान बदल रहा है. lowerBand और upperBand हमेशा गणना की जाती है, केवल इस कस्टम फ़ंक्शन में वर्तमान रुझान की दिशा का अंतिम निर्णय।
pine
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जब सिग्नल की स्थिति ट्रिगर हो जाती है, तो खाली कर दें।
pine
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
अंत में, दिशा के अनुसार चयनित विशिष्ट सुपरट्रेंड सूचक मूल्य डेटा और दिशा डेटा लौटाएं।
गतिशील संतुलन रणनीति
pine
/*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(यानी BaseCurrency संपत्ति की संख्या) संतुलन जानकारी <unk> हम खाते में वास्तविक संपत्ति की संख्या को पढ़ने के लिए नहीं जा रहे हैं, हम केवल अनुकरण राशि का उपयोग करने के लिए उपयुक्त खरीद और बेचने की गणना <unk> और फिर इस गतिशील संतुलन रणनीति पर प्रभाव डालने के लिए जाली खींचने के लिए महत्वपूर्ण पैरामीटर हैmaxDiffValue, यह पैरामीटर संतुलन के लिए एक निर्णय है. वर्तमान कीमतों पर, केवल जबBaseCurrencyऔरQuoteCurrencyविचलन से अधिकmaxDiffValueऔर जब हम अपने पास मौजूद सभी संपत्तियों को बेचते हैं, तो हम उन्हें संतुलित करते हैं, हम उन्हें बेचते हैं, हम उन्हें खरीदते हैं, हम उन्हें संतुलित करते हैं।
रणनीति ट्रेडिंग सिग्नल ट्रिगर करना वास्तविक समय BAR चरण में सार्थक होना चाहिए, इसलिए रणनीति ट्रेडिंग शर्तें if निर्णय में सेट की जाती हैंnot barstate.ishistory◦ वर्तमान कीमतों के आधार परbalanceमूल्य से अधिकstocksमूल्य के समय खरीदना ∙ इसके विपरीत, बिक्री करना ∙ लेन-देन के बाद अद्यतन करनाbalanceऔरstocksचर, फिर अगले संतुलन ट्रिगर के लिए प्रतीक्षा करें।
उपरोक्त नीतिगत प्रतिक्रिया में नीतिगत प्रतिक्रिया के प्रारंभ के समय की किस्म की कीमत है, मूल्य 1458 है, इसलिए मैंने विशेष रूप से पैरामीटर सेट किए हैंbalance४३७४ १४५८*3), पैरामीटर सेट करेंstocks3 के लिए: ◦ आरंभ में परिसंपत्ति को संतुलन में रखें ◦
सुपरट्रेंड्स को ट्रैक करने के लिए स्टॉपलॉस रणनीति
पिछले पाठ में हमने सीखा हैstrategy.exitपोजीशन आउटफील्ड फ़ंक्शन, जिसमें ट्रैकिंग स्टॉप लॉस स्टॉप फ़ंक्शन हम उदाहरण के लिए नहीं हैं। इस खंड में रणनीति डिजाइन उदाहरण हम उपयोग करते हैंstrategy.exitएक सुपरट्रेंड रणनीति को अनुकूलित करने के लिए फ़ंक्शंस का ट्रैक स्टॉप-लॉस-स्टॉप फ़ंक्शन
पहले हम देखते हैंstrategy.exitफ़ंक्शन का ट्रैक स्टॉप लॉस स्टॉप पैरामीटरः
1、trail_priceपैरामीटरः ट्रिगर स्थान ट्रैक स्टॉप स्टॉप लॉजिस्टिक्स को ट्रैक करने के लिए
2、trail_offsetपैरामीटरः ट्रैक स्टॉप लॉस स्टॉप कार्रवाई के बाद, सबसे अधिक मूल्य (जब बहुत) या सबसे कम मूल्य (जब खाली) से दूरी पर रखा गया है।
3、trail_pointsपैरामीटरः जैसा किtrail_priceपैरामीटर, केवल स्थान के रूप में निर्दिष्ट किया गया है।
यदि यह समझना मुश्किल है, तो कोई बात नहीं! हम एक रणनीति के माध्यम से सीखने को समझते हैं, जो कि वास्तव में बहुत सरल है।
pine
/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("test", overlay = true)
varip a = na
varip highPrice = na
varip isTrade = false
varip offset = 30
if not barstate.ishistory and not isTrade
strategy.entry("test 1", strategy.long, 1)
strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
a := close + offset
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close)
isTrade := true
if close > a and not barstate.ishistory
highPrice := na(highPrice) ? close : highPrice
highPrice := close > highPrice ? close : highPrice
plot(a, "trail_price 触发线")
plot(strategy.position_size>0 ? highPrice : na, "当前最高价")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "移动止损触发线")
रणनीति के निष्पादन के तुरंत बाद बहु-प्रवेश शुरू होता है, और तुरंत बाद मेंstrategy.exitबाहर निकलने का आदेश ((निर्दिष्ट ट्रैक स्टॉप लॉस स्टॉप पैरामीटर), जब कीमत में वृद्धि ट्रेल_प्राइस ट्रिगर लाइन से अधिक है, तो ट्रैक स्टॉप लॉजिक को निष्पादित करना शुरू करें, स्टॉप लॉस स्टॉप लाइन ((नीला) सबसे अधिक मूल्य गतिशीलता को समायोजित करना शुरू करें, नीली रेखा का स्थान वह मूल्य है जहां स्टॉप लॉस स्टॉप पीस स्थिति को ट्रिगर करता है, और अंत में जब कीमत में परिवर्तन नीली रेखा से नीचे गिरता है तो पीस स्थिति को ट्रिगर करता है। इस तरह से चार्ट पर खींची गई रेखा को समझना आसान है।
तो हम इस सुविधा का उपयोग करने के लिए एक सुपर रुझान रणनीति अनुकूलित करने के लिए, हम सिर्फ एक प्रविष्टि आदेश के लिए रणनीति निर्दिष्टstrategy.exitइस प्रकार के ट्रैकिंग और रोकथाम के लिए एक अतिरिक्त फ़ंक्शन है।
pine
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
संपूर्ण रणनीति कोड:
pine
/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0
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
if strategy.position_size == 0
trail_price := na
state := 0
[superTrendPrice, dir] = ta.supertrend(input(2, "atr系数"), input(20, "atr周期"))
if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.long, 1)
state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.short, 1)
state := 1
// 反向信号,全平
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,多头全平")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,空头全平")
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)
- 1




















