संसाधन लोड हो रहा है... लोड करना...

एफएमजेड क्वांट का पाइन भाषा परिचयात्मक ट्यूटोरियल

लेखक:FMZ~Lydia, बनाया गयाः 2022-09-23 15:23:34, अद्यतनः 2024-02-27 16:47:41

[TOC]

img

एफएमजेड क्वांट का पाइन भाषा परिचयात्मक ट्यूटोरियल

समर्थन वीडियो ट्यूटोरियलःhttps://www.youtube.com/watch?v=CA3SwJQb_1g

एफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म पाइन भाषा रणनीति लेखन, बैकटेस्टिंग और पाइन भाषा रणनीतियों के लाइव ट्रेडिंग का समर्थन करता है, और यह पाइन भाषा के निचले संस्करणों के साथ संगत है।रणनीति वर्गएफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म पर (FMZ.COM).

एफएमजेड न केवल पाइन भाषा का समर्थन करता है, बल्कि पाइन भाषा के शक्तिशाली ड्राइंग फ़ंक्शन का भी समर्थन करता है। एफएमजेड प्लेटफॉर्म पर विभिन्न कार्य, समृद्ध और व्यावहारिक उपकरण, कुशल और सुविधाजनक प्रबंधन पाइन रणनीति (स्क्रिप्ट) की व्यावहारिकता को और बढ़ाता है। पाइन भाषा के साथ संगतता के आधार पर, एफएमजेड भी पाइन भाषा का विस्तार, अनुकूलन और एक निश्चित हद तक ट्रिम करता है। आधिकारिक तौर पर ट्यूटोरियल में प्रवेश करने से पहले, आइए देखें कि मूल संस्करण की तुलना में एफएमजेड पर पाइन भाषा में क्या बदलाव किए गए हैं।

कुछ स्पष्ट मतभेदों का संक्षिप्त अवलोकन:

    1. एफएमजेड पर पाइन रणनीति, कोड की शुरुआत में संस्करण पहचानकर्ता//@versionऔरstrategy, indicatorकोड की शुरुआत में बयान लिखने के लिए अनिवार्य नहीं हैं, FMZ समर्थन नहीं करताimportआयात करनाlibraryअभी के लिए काम करता है।

    यह देखा जा सकता है कि कुछ रणनीतियाँ इस तरह लिखी गई हैंः

    //@version=5
    indicator("My Script", overlay = true)
    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue)
    plot(b, color = color.black)
    plotshape(c, color = color.red)
    

    या इसे इस तरह लिखें:

    //@version=5
    strategy("My Strategy", overlay=true)
    
    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    

    एफएमजेड पर इसे सरल किया जा सकता हैः

    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue, overlay=true)
    plot(b, color = color.black, overlay=true)
    plotshape(c, color = color.red, overlay=true)
    

    या:

    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    
    1. रणनीति (स्क्रिप्ट) की कुछ ट्रेडिंग से संबंधित सेटिंग्स FMZ रणनीति इंटरफ़ेस पर Pine Language Trading Class Library पैरामीटर द्वारा सेट की जाती हैं।
    • समापन मूल्य मॉडल और वास्तविक समय मूल्य मॉडल व्यापारिक दृश्य पर, हम उपयोग कर सकते हैंcalc_on_every_tickपैरामीटरstrategyसमारोह रणनीति स्क्रिप्ट सेट करने के लिए वास्तविक समय में रणनीति तर्क निष्पादित करने के लिए जब कीमत हर बार बदल जाता है। इस समय,calc_on_every_tickपैरामीटर को सेट किया जाना चाहिएtrue.calc_on_every_tickडिफ़ॉल्ट पैरामीटर हैfalse, यानी रणनीति तर्क तभी निष्पादित होता है जब रणनीति का वर्तमान K-लाइन BAR पूरी तरह पूरा हो जाता है। एफएमजेड पर, यह पाइन लैंग्वेज ट्रेडिंग क्लास लाइब्रेरी टेम्पलेट के मापदंडों द्वारा निर्धारित किया जाता है।

      img

    • संख्यात्मक सटीक नियंत्रण, जैसे कि मूल्य और आदेश राशि जब रणनीति निष्पादित की जाती है FMZ पर निर्दिष्ट किया जाना चाहिए ट्रेडिंग व्यू में, वास्तविक ट्रेडिंग ऑर्डर रखने पर सटीकता की कोई समस्या नहीं होती है, क्योंकि इसका केवल सिमुलेशन में परीक्षण किया जा सकता है। एफएमजेड पर, वास्तविक ट्रेडिंग में पाइन रणनीति चलाना संभव है। फिर रणनीति को ट्रेडिंग किस्म की मूल्य सटीकता और ऑर्डर राशि सटीकता को लचीले ढंग से निर्दिष्ट करने में सक्षम होना चाहिए। सटीकता सेटिंग्स प्रासंगिक डेटा में दशमलव स्थानों की संख्या को नियंत्रित करती हैं ताकि डेटा को एक्सचेंज की ऑर्डर आवश्यकताओं को पूरा नहीं करने से रोका जा सके और इस प्रकार ऑर्डर करने में विफल रहे।

    • वायदा अनुबंध कोड यदि एफएमजेड पर ट्रेडिंग उत्पाद एक अनुबंध है, तो इसमें दो विशेषताएं हैं, वे क्रमशः ट्रेडिंग जोड़ी और अनुबंध कोड हैं। ट्रेडिंग जोड़ी को स्पष्ट रूप से सेट करने के अलावा, वास्तविक ट्रेडिंग और बैकटेस्टिंग के दौरान पाइन लैंग्वेज ट्रेडिंग क्लास लाइब्रेरी टेम्पलेट के पैरामीटर वैराइटी कोड में विशिष्ट अनुबंध कोड सेट करना भी आवश्यक है। उदाहरण के लिए, एक स्थायी अनुबंध के लिए, में भरेंswapउदाहरण के लिए, कुछ एक्सचेंजों में त्रैमासिक अनुबंध होते हैं, आप भर सकते हैंquarterये अनुबंध कोड एफएमजेड के जावास्क्रिप्ट/पायथन/सी++ भाषा एपीआई दस्तावेज़ में परिभाषित वायदा अनुबंध कोड के अनुरूप हैं।

    अन्य सेटिंग्स के लिए, जैसे कि न्यूनतम ऑर्डर राशि, डिफ़ॉल्ट ऑर्डर राशि, आदि, कृपया पैरामीटर परिचय देखें।पाइन भाषा ट्रेड क्लास लाइब्रेरी के टेम्पलेट तर्कपाइन भाषा दस्तावेज में।

    1. एफएमजेड विस्तार के लिए कार्यःruntime.debug , runtime.log, runtime.errorडिबगिंग के लिए प्रयोग किया जाता है.

    डीबगिंग के लिए एफएमजेड प्लेटफॉर्म में 3 फ़ंक्शन जोड़े गए हैं।

    • runtime.debug: कंसोल पर चर सूचना मुद्रित करें, जिसका सामान्यतः इस कार्य के साथ उपयोग नहीं किया जाता है।

    • runtime.log: लॉग में आउटपुट। FMZ पर PINE भाषा-विशिष्ट कार्य।

      runtime.log(1, 2, 3, close, high, ...), Multiple parameters can be passed.
      
    • runtime.error: यह संदेश पैरामीटर में निर्दिष्ट त्रुटि संदेश के साथ एक रनटाइम त्रुटि का परिणाम होगा जब बुलाया जाता है.

      runtime.error(message)
      
    1. ..overlayपैरामीटर ड्राइंग कार्यों में से कुछ में विस्तारित है

    FMZ पर पाइन भाषा में, ड्राइंग कार्योंplot, plotshape, plotchar, आदि ने जोड़ा हैoverlayपैरामीटर समर्थन, जो मुख्य चार्ट या उप-चार्ट पर ड्राइंग को निर्दिष्ट करने की अनुमति देता है।overlayपर सेट हैtrueमुख्य चार्ट पर आकर्षित करने के लिए, औरfalseउप-चार्ट पर आकर्षित करने के लिए सेट किया गया है, जो एफएमजेड पर पाइन रणनीति को एक ही समय में मुख्य चार्ट और उप-चार्ट को आकर्षित करने में सक्षम बनाता है।

    1. मूल्यsyminfo.mintickअंतर्निहित चर

    के अंतर्निहित चरsyminfo.mintickवर्तमान प्रतीक के लिए न्यूनतम टिक मान के रूप में परिभाषित किया गया है। इस मूल्य को FMZ पर Pine Language Trading Class Library में टेम्पलेट पैरामीटर मूल्य निर्धारण मुद्रा परिशुद्धता द्वारा नियंत्रित किया जा सकता हैबॉट/बैकटेस्टमूल्य निर्धारण मुद्रा सटीकता सेटिंग 2 का अर्थ है कि मूल्य व्यापार के दौरान दूसरे दशमलव स्थान पर सटीक है, और न्यूनतम मूल्य परिवर्तन इकाई 0.01 है।syminfo.mintick0.01 है।

    1. एफएमजेड पाइन स्क्रिप्ट में औसत मूल्य सभी कमीशन सहित हैं

    उदाहरण के लिए: ऑर्डर की कीमत 8000 है, बिक्री की दिशा, मात्रा 1 लॉट (टुकड़ा, शीट) है, लेनदेन के बाद औसत कीमत 8000 नहीं है, लेकिन 8000 से कम है (लागत में हैंडलिंग शुल्क शामिल है) ।

पाइन भाषा की मूल बातें

जब आप पाइन भाषा की मूल बातें सीखना शुरू करते हैं, तो निर्देशों और कोड व्याकरण के कुछ उदाहरण हो सकते हैं जिनसे हम परिचित नहीं हैं। इससे कोई फर्क नहीं पड़ता कि आप इसे नहीं समझते हैं, हम पहले अवधारणाओं से परिचित हो सकते हैं और परीक्षण के उद्देश्य को समझ सकते हैं, या आप निर्देशों के लिए एफएमजेड पर पाइन भाषा प्रलेखन की जांच कर सकते हैं। फिर विभिन्न व्याकरणों, निर्देशों, कार्यों और अंतर्निहित चरों से परिचित होने के लिए ट्यूटोरियल चरण-दर-चरण का पालन करें।

मॉडल निष्पादन

पाइन भाषा सीखने की शुरुआत करते समय, पाइन भाषा स्क्रिप्ट प्रोग्राम की निष्पादन प्रक्रिया जैसी संबंधित अवधारणाओं को समझना बहुत आवश्यक है। पाइन भाषा रणनीति चार्ट के आधार पर चलती है। यह समझा जा सकता है कि पाइन भाषा रणनीति गणनाओं और संचालन की एक श्रृंखला है, जो चार्ट पर लोड किए गए सबसे शुरुआती डेटा से समय श्रृंखला के क्रम में चार्ट पर निष्पादित की जाती है। डेटा की मात्रा जो चार्ट शुरू में लोड करता है वह सीमित है। वास्तविक व्यापार में, अधिकतम डेटा की मात्रा आमतौर पर एक्सचेंज इंटरफ़ेस द्वारा लौटाए गए अधिकतम डेटा वॉल्यूम के आधार पर निर्धारित की जाती है, और बैकटेस्टिंग के दौरान डेटा की अधिकतम मात्रा बैकटेस्टिंग सिस्टम के डेटा स्रोत द्वारा प्रदान किए गए डेटा के आधार पर निर्धारित की जाती है। चार्ट पर सबसे बाईं ओर के-लाइन बार, यानी चार्ट के पहले डेटा सेट का सूचकांक मान 0 है।bar_indexपाइन भाषा में।

plot(bar_index, "bar_index")

img

..plotसमारोह हम भविष्य में अधिक उपयोग करेंगे कार्यों में से एक है. उपयोग बहुत सरल है, यह इनपुट मापदंडों के अनुसार चार्ट पर एक रेखा खींचने के लिए है, इनपुट डेटा हैbar_index, और लाइन का नाम हैbar_index. यह देखा जा सकता है कि पहले बार पर bar_index नामक पंक्ति का मान 0 है, और यह बार बढ़ने के साथ 1 से दाईं ओर बढ़ता है।

क्योंकि रणनीति की सेटिंग अलग है, रणनीति के मॉडल निष्पादन के तरीके अलग हैं, उन्हें विभाजित किया जा सकता हैclosing price modelऔरreal-time price modelहमने पहले भी संक्षेप में इनकी अवधारणाओं का परिचय दिया है।

  • समापन मूल्य मॉडल

    जब रणनीति कोड निष्पादित किया जाता है, तो वर्तमान K-लाइन बार की अवधि पूरी तरह से निष्पादित की जाती है, और जब K-लाइन बंद हो जाती है, तो K-लाइन अवधि पूरी हो जाती है। इस बिंदु पर, पाइन रणनीति तर्क एक बार निष्पादित किया जाता है, और ट्रिगर किए गए ट्रेडिंग सिग्नल को अगले K-लाइन बार की शुरुआत में निष्पादित किया जाएगा।

  • वास्तविक समय मूल्य मॉडल

    जब रणनीति कोड निष्पादित किया जाता है, भले ही वर्तमान के-लाइन बार बंद हो या नहीं, पाइन रणनीति तर्क निष्पादित किया जाएगा जब बाजार हर बार बदलता है, और ट्रिगर ट्रेडिंग सिग्नल तुरंत निष्पादित किया जाएगा।

जब पाइन भाषा रणनीति चार्ट पर बाएं से दाएं निष्पादित की जाती है, तो चार्ट पर के-लाइन बार में विभाजित होते हैंHistorical BarsऔरReal-time Bars:

  • ऐतिहासिक बार

    जब रणनीति Tick Model पर सेट है और निष्पादन शुरू होता है, चार्ट पर सभी के-लाइन बार के अलावा सबसे दाईं ओर एक कर रहे हैंHistorical Bars. रणनीति तर्क प्रत्येक पर केवल एक बार निष्पादित किया जाता हैhistorical bar.. जब रणनीति को Bar Model पर सेट किया जाता है और निष्पादन शुरू होता है, चार्ट पर सभी सलाखों हैंhistorical bars. रणनीति तर्क प्रत्येक पर केवल एक बार निष्पादित किया जाता हैhistorical bar.

    ऐतिहासिक बारों के आधार पर गणनाः रणनीति कोड ऐतिहासिक पट्टी के बंद होने की स्थिति में एक बार निष्पादित किया जाता है, और फिर रणनीति कोड अगले ऐतिहासिक पट्टी में निष्पादित किया जाता है जब तक कि सभी ऐतिहासिक पट्टी एक बार निष्पादित नहीं हो जाती हैं।

  • वास्तविक समय बार

    जब रणनीति को अंतिम K-लाइन बार पर निष्पादित किया जाता है, तो बार एक वास्तविक समय बार है। वास्तविक समय बार बंद होने के बाद, बार एक पारित वास्तविक समय बार (ऐतिहासिक बार बन जाता है) बन जाता है। चार्ट के सबसे दाईं ओर एक नया वास्तविक समय बार उत्पन्न होगा।

    जब रणनीति को Tick Model पर सेट किया जाता है और निष्पादन शुरू होता है, तो रणनीति तर्क वास्तविक समय पट्टी पर प्रत्येक बाजार परिवर्तन के लिए एक बार निष्पादित किया जाएगा। जब रणनीति को Bar Model पर सेट किया जाता है और निष्पादन शुरू होता है, तो वास्तविक समय पट्टी चार्ट पर प्रदर्शित नहीं होगी.

    वास्तविक समय बार पर आधारित गणनाः यदि रणनीति को Bar Model पर सेट किया गया है और चार्ट में वास्तविक समय के बार नहीं दिखाई देते हैं, तो रणनीति कोड केवल एक बार निष्पादित किया जाएगा जब वर्तमान बार बंद हो जाएगा। यदि रणनीति Tick Model पर सेट है, तो वास्तविक समय पट्टी पर गणना ऐतिहासिक पट्टी से पूरी तरह से अलग है, और रणनीति कोड लाइव ट्रेडिंग बार पर प्रत्येक बाजार परिवर्तन के लिए एक बार निष्पादित किया जाएगा। उदाहरण के लिए, अंतर्निहित चरhigh, low, closeऐतिहासिक बार पर निर्धारित होते हैं, और ये मूल्य हर बार बदल सकते हैं जब बाजार वास्तविक समय के बार पर बदलता है। इसलिए, इन मूल्यों के आधार पर गणना किए गए संकेतकों जैसे डेटा भी वास्तविक समय में बदलेंगे। वास्तविक समय के बार पर,closeहमेशा वर्तमान नवीनतम मूल्य को दर्शाता है, औरhighऔरlowहमेशा वर्तमान वास्तविक समय पट्टी की शुरुआत के बाद से प्राप्त उच्चतम बिंदु और निम्नतम बिंदु का प्रतिनिधित्व करते हैं। ये अंतर्निहित चर वास्तविक समय पट्टी के अंतिम मूल्य का प्रतिनिधित्व करते हैं जब इसे अंतिम बार अपडेट किया गया था।

    रीयल-टाइम बार (रीयल-टाइम प्राइस मॉडल) पर रणनीतियों को निष्पादित करते समय रोलबैक तंत्रः वास्तविक समय बार निष्पादन के दौरान, रणनीति के प्रत्येक नए पुनरावृत्ति से पहले उपयोगकर्ता-परिभाषित चर को रीसेट करना रोलबैक कहा जाता है। आइए निम्नलिखित परीक्षण कोड के उदाहरण के साथ रोलबैक तंत्र को समझें।

    ध्यान दें:

    /*backtest 
    ...
    ..
    .
    */
    

    पैकेज की सामग्री बैकटेस्ट कॉन्फ़िगरेशन जानकारी है जो एफएमजेड प्लेटफॉर्म पर कोड के रूप में सहेजी गई है।

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    
    var n = 0
    if not barstate.ishistory
        runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
        n := n + 1
        runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
      
    plot(n, title="n")
    

    img

हम केवल वास्तविक समय के दौरान निष्पादित दृश्य की जांच बार, तो हम का उपयोगnot barstate.ishistoryकेवल वास्तविक समय बार में चर n के संचय को सीमित करने के लिए अभिव्यक्ति, और उपयोगruntime.logसंचयन क्रिया से पहले और बाद में रणनीति लॉग में जानकारी आउटपुट करने के लिए कार्य। ड्राइंग फ़ंक्शन का उपयोग करके खींची गई वक्र n सेplot, यह देखा जा सकता है कि n हमेशा 0 होता है जब रणनीति ऐतिहासिक बारों में चल रही होती है। जब वास्तविक समय बार निष्पादित होता है, तो 1 को n में जोड़ने का ऑपरेशन ट्रिगर किया जाता है, और 1 को n में जोड़ने का ऑपरेशन वास्तविक समय बार के प्रत्येक दौर में रणनीति निष्पादित होने पर निष्पादित होता है। यह लॉग संदेश से देखा जा सकता है कि n को पिछले बार निष्पादन रणनीति द्वारा अंतिम रूप से प्रस्तुत मूल्य पर रीसेट किया जाएगा जब रणनीति कोड प्रत्येक दौर में फिर से निष्पादित किया जाता है। n मान अद्यतन तब प्रस्तुत किया जाएगा जब रणनीति कोड वास्तविक समय बार पर अंतिम बार निष्पादित किया जाता है, इसलिए आप देख सकते हैं कि आरेख पर वास्तविक समय बार से शुरू होने वाले बार की प्रत्येक वृद्धि के साथ वक्र n का मूल्य 1 बढ़ता है।

सारांश:

  1. रणनीति कोड प्रत्येक बार निष्पादित किया जाता है जब बाजार अद्यतन किया जाता है जब रणनीति वास्तविक समय बार में निष्पादित होने लगती है।
  2. जब वास्तविक समय में बार में निष्पादित किया जाता है, तो रणनीति कोड निष्पादित होने से पहले प्रत्येक बार चर वापस रोल किए जाते हैं।
  3. जब वास्तविक समय में बार में निष्पादित किया जाता है, तो चर एक बार जब बंद अद्यतन किया जाता है, प्रस्तुत किए जाते हैं।

डेटा रोलबैक के कारण, चार्ट पर वक्र जैसे ड्राइंग ऑपरेशन भी पुनः ड्राइंग का कारण बन सकते हैं। उदाहरण के लिए, लाइव ट्रेडिंग के लिए अभी परीक्षण कोड को संशोधित करेंः

var n = 0
if not barstate.ishistory
    runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
    n := open > close ? n + 1 : n
    runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
  
plot(n, title="n")

समय A का स्क्रीनशॉटimg

समय B का स्क्रीनशॉटimg

हमने केवल वाक्य को संशोधित किया:n := open > close ? n + 1 : n, केवल 1 को n में जोड़ें जब वर्तमान वास्तविक समय पट्टी एक नकारात्मक रेखा है (यानी, उद्घाटन मूल्य समापन मूल्य से अधिक है) । यह देखा जा सकता है कि पहले चार्ट (समय ए) में, क्योंकि उद्घाटन मूल्य उस समय समापन मूल्य (नकारात्मक रेखा) से अधिक था, n को 1 द्वारा संचित किया गया था, और चार्ट वक्र पर प्रदर्शित n का मूल्य 5 था। फिर बाजार बदल गया और मूल्य दूसरे चार्ट (समय बी) में दिखाए गए अनुसार अद्यतन किया गया। इस समय, उद्घाटन मूल्य समापन मूल्य (सकारात्मक रेखा) से कम है, और n मूल्य 1 द्वारा वृद्धि के बिना वापस रोल करता है। चार्ट में n की वक्र भी तुरंत फिर से तैयार की जाती है, और वक्र पर n का मूल्य 4 है। इसलिए, क्रॉसअप और वास्तविक समय पट्टी पर प्रदर्शित क्रॉसडाउन जैसे संकेत अनिश्चित हैं और बदल सकते हैं।

  • कार्यों में परिवर्तनीय संदर्भ

    आइए पाइन भाषा फ़ंक्शन में चरों का एक साथ अध्ययन करें। पाइन ट्यूटोरियल पर कुछ विवरणों के अनुसार, फ़ंक्शन में चरों में फ़ंक्शन के बाहर के चरों से निम्नलिखित अंतर हैंः

    पाइन फ़ंक्शन में उपयोग किए जाने वाले श्रृंखला चरों का इतिहास फ़ंक्शन के प्रत्येक क्रमिक कॉल के साथ बनाया जाता है। यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है जिस पर स्क्रिप्ट चलती है, तो इसका परिणाम फ़ंक्शन के स्थानीय ब्लॉक के अंदर और बाहर श्रृंखला के ऐतिहासिक मूल्यों के बीच विसंगति होगा। इसलिए, यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है, तो फ़ंक्शन के अंदर और बाहर संदर्भित श्रृंखला एक ही सूचकांक मूल्य के साथ एक ही ऐतिहासिक बिंदु को संदर्भित नहीं करेगी।

    यह समझ में थोड़ा मुश्किल है? परवाह नहीं, हम यह एक परीक्षण कोड FMZ पर चल रहा के साथ पता चल जाएगाः

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
      
    f(a) => a[1]
    f2() => close[1]  
    
    oneBarInTwo = bar_index % 2 == 0
    plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")   
    plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")   
    plot(close[2], title = "close[2]", color = color.red, overlay = true)
    plot(close[1], title = "close[1]", color = color.green, overlay = true)
    

    बैकटेस्ट चलाने का स्क्रीनशॉट

    img

    परीक्षण कोड अपेक्षाकृत सरल है, मुख्य रूप से दो विधियों द्वारा संदर्भित डेटा की जांच करने के लिए, अर्थात्ःf(a) => a[1]औरf2() => close[1].

    • f(a) => a[1]: पैरामीटर पास करने की विधि का उपयोग करें, फ़ंक्शन को लौटाता हैa[1] finally.

    • f2() => close[1]: अंतर्निहित चर का प्रयोग करेंcloseसीधे, और फ़ंक्शन लौटता है करने के लिएclose[1] finally.

..[]प्रतीक का उपयोग डेटा श्रृंखला चर के ऐतिहासिक मूल्य को संदर्भित करने के लिए किया जाता है, और बंद[1] वर्तमान समापन मूल्य से पहले बार पर समापन मूल्य डेटा को संदर्भित करता है। हमारा परीक्षण कोड चार्ट पर कुल 4 प्रकार के डेटा खींचता हैः

  • plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")एक वर्ण A खींचें, रंग लाल है, यह तब खींचा जाता है जब oneBarInTwo सच है, और खींचा गया स्थान (वाई अक्ष पर): द्वारा लौटाया गया मानf(close).

  • plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")एक वर्ण B खींचें, रंग हरा है, यह केवल तब खींचा जाता है जब oneBarInTwo सच है, और खींची गई स्थिति (वाई अक्ष पर): द्वारा लौटाया गया मानf2().

  • plot(close[2], title = "close[2]", color = color.red, overlay = true)एक रेखा खींचें, रंग लाल है, और खींची गई स्थिति (वाई-अक्ष पर) हैःclose[2], जो वर्तमान पट्टी (बाईं ओर 2 पट्टी गिनती) से पहले दूसरे पट्टी का समापन मूल्य है।

  • plot(close[1], title = "close[1]", color = color.green, overlay = true)एक रेखा खींचें, रंग हरा है, और खींची गई स्थिति (वाई-अक्ष पर) हैःclose[1], जो वर्तमान पट्टी से पहले पहले पट्टी की समापन कीमत है (बाईं ओर 1 पट्टी गिनती) ।

यह रणनीति बैकटेस्टिंग के स्क्रीनशॉट से देखा जा सकता है कि हालांकि दोनों समारोहf(a) => a[1]ए मार्कर और समारोह आकर्षित करने के लिए इस्तेमाल कियाf2() => close[1]डेटा श्रृंखला पर ऐतिहासिक डेटा को संदर्भित करने के लिए बी मार्कर का उपयोग [1] करने के लिए उपयोग किया जाता है, चार्ट पर A और B के मार्कर पद पूरी तरह से अलग हैं। A मार्कर की स्थिति हमेशा लाल रेखा पर पड़ती है, जो रणनीति में कोड द्वारा खींची गई रेखा है।plot(close[2], title = "close[2]", color = color.red, overlay = true), रेखा खींचने के लिए उपयोग किए जाने वाले डेटा हैclose[2].

img

इसका कारण यह गणना करना है कि क्या K-लाइन बार के सूचकांक के माध्यम से A और B मार्कर को आकर्षित करना है, अर्थात अंतर्निहित चरbar_indexA और B मार्कर प्रत्येक K-लाइन बार पर नहीं खींचे जाते हैं (चित्रण करते समय फ़ंक्शन गणना को बुलाया जाता है) । फ़ंक्शन द्वारा संदर्भित मानf(a) => a[1]फ़ंक्शन द्वारा संदर्भित मान के समान नहीं होगाf2() => close[1]यदि फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जाता है (भले ही वे दोनों एक ही सूचकांक जैसे [1] का उपयोग करें) ।

  • कुछ अंतर्निहित कार्यों को उनके परिणामों को सही ढंग से गणना करने के लिए प्रत्येक बार पर गणना की जानी चाहिए

    इस स्थिति को एक सरल उदाहरण से स्पष्ट करने के लिए:

    res = close > close[1] ? ta.barssince(close < close[1]) : -1
    plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
    

    हम फ़ंक्शन कॉल कोड लिखते हैंta.barssince(close < close[1])तृतीयक संचालक मेंcondition ? value1 : value2. यह ta.barssince फ़ंक्शन को केवल तब बुलाया जाता है जबclose > close[1]. लेकिनta.barssinceसमारोह पिछली बार के बाद से के लाइनों की संख्या की गणना करने के लिए हैclose < close[1]जब ta.barssince फ़ंक्शन को बुलाया जाता है, तो यह हमेशा बंद > बंद होता है[1], अर्थात, वर्तमान समापन मूल्य पिछले बार के समापन मूल्य से अधिक होता है। जब ta.barssince फ़ंक्शन को बुलाया जाता है, तो बंद < बंद [1] की स्थिति स्थापित नहीं होती है, और कोई हालिया स्थिति नहीं होती है जहां यह पकड़ती है।

    ta.barssince: जब बुलाया जाता है, तो फ़ंक्शन na लौटाता है यदि वर्तमान K-लाइन से पहले शर्त कभी पूरी नहीं हुई है.

जैसा कि चार्ट में दिखाया गया हैः

img

तो जब चार्ट तैयार किया जाता है, केवल डेटा के लिए एक मूल्य के साथ res चर (-1) तैयार किया जाता है।

इस समस्या से बचने के लिए, हम बस लेta.barssince(close < close[1])फ़ंक्शन टर्नरी ऑपरेटर से बाहर कॉल करता है और इसे किसी भी संभव सशर्त शाखाओं के बाहर लिखता है, जिससे यह प्रत्येक K-लाइन बार पर गणना करता है।

a = ta.barssince(close < close[1])
res = close > close[1] ? a : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)

कालक्रम

पाइन भाषा में समय श्रृंखला की अवधारणा बहुत महत्वपूर्ण है, और यह एक अवधारणा है जिसे हमें पाइन भाषा सीखने पर समझना चाहिए। समय श्रृंखला एक प्रकार नहीं है बल्कि समय के साथ चर के निरंतर मानों को संग्रहीत करने के लिए एक बुनियादी संरचना है। हम जानते हैं कि पाइन स्क्रिप्ट चार्ट पर आधारित हैं, और चार्ट में प्रदर्शित सबसे बुनियादी सामग्री के-लाइन चार्ट है। समय श्रृंखला जहां प्रत्येक मूल्य के-लाइन बार के टाइमस्टैम्प से जुड़ा हुआ है।openपाइन भाषा का एक अंतर्निहित चर है, और इसकी संरचना प्रत्येक के-लाइन बार के उद्घाटन मूल्य की समय श्रृंखला को संग्रहीत करना है। यह समझा जा सकता है कि पाइन भाषा का समय श्रृंखला संरचनाopenवर्तमान K-लाइन चार्ट की शुरुआत में पहले बार से वर्तमान K-लाइन चार्ट के लिए जहां वर्तमान स्क्रिप्ट निष्पादित किया जाता है बार के लिए सभी K-लाइन बार के उद्घाटन कीमतों का प्रतिनिधित्व करता है। यदि वर्तमान K-लाइन चार्ट एक 5 मिनट की अवधि है, जब हम बोली (या उपयोग)openपाइन रणनीति कोड में, यह K-लाइन बार की शुरुआती कीमत है जब रणनीति कोड वर्तमान में निष्पादित किया जाता है। यदि आप एक समय श्रृंखला में ऐतिहासिक मूल्यों का उल्लेख करना चाहते हैं, तो आपको[]ऑपरेटर. जब पाइन रणनीति एक निश्चित K-लाइन बार पर निष्पादित किया जाता है, का उपयोगopen[1]पिछले के-लाइन बार (यानी, पिछले के-लाइन अवधि की शुरुआती कीमत) के शुरुआती मूल्य का संदर्भ देने के लिए जो संदर्भित करता हैopenसमय श्रृंखला जिस पर इस K-लाइन बार वर्तमान में स्क्रिप्ट द्वारा निष्पादित किया जा रहा है.

  • समय श्रृंखला पर चर कंप्यूटिंग के लिए बहुत सुविधाजनक हैं चलो अंतर्निहित फ़ंक्शन लेते हैंta.cumउदाहरण के तौर परः

    ta.cum
    
    Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
    ta.cum(source) → series float
    RETURNS
    Total sum series.
    ARGUMENTS
    source (series int/float)
    SEE ALSO
    math.sum
    

    परीक्षण कोडः

    v1 = 1
    v2 = ta.cum(v1)
    plot(v1, title="v1")
    plot(v2, title="v2")
    plot(bar_index+1, title="bar_index")
    

    कई अंतर्निहित कार्य हैं जैसे किta.cumजो समय श्रृंखलाओं पर डेटा को सीधे संसाधित कर सकते हैं. उदाहरण के लिए,ta.cumप्रत्येक K-लाइन बार पर पारित चर के अनुरूप मूल्यों का संचय है, और अगले हम इसे समझने के लिए आसान बनाने के लिए एक चार्ट का उपयोग करें।

    रणनीति संचालन प्रक्रिया अंतर्निहित चर bar_index v1 v2
    रणनीति पहले के-लाइन बार पर चलता है 0 1 1
    रणनीति दूसरे के-लाइन बार पर चलता है 1 1 2
    रणनीति तीसरे के-लाइन बार पर चलता है 2 1 3
    रणनीति N + 1 वीं K-लाइन बार पर चलता है एन 1 एन+1

    यह देखा जा सकता है कि v1, v2 और यहां तक कि bar_index सभी समय श्रृंखला संरचनाएं हैं, और प्रत्येक बार पर संबंधित डेटा है। चाहे परीक्षण कोड Bar मॉडल या Tick मॉडल का उपयोग करता है, एकमात्र अंतर यह है कि क्या वास्तविक समय बार चार्ट पर प्रदर्शित होता है। त्वरित बैकटेस्ट के लिए, हम परीक्षण के लिए Tick मॉडल का उपयोग करते हैं।

    img

    चूंकि चर v1 प्रत्येक बार पर 1 है, जबta.cum(v1)फ़ंक्शन पहले K-लाइन बार पर निष्पादित किया जाता है, वहाँ केवल पहले बार है, तो गणना परिणाम 1 है और चर v2 के लिए सौंपा जाता है। कबta.cum(v1)दूसरे के-लाइन बार पर निष्पादित किया जाता है, पहले से ही 2 के-लाइन बार हैं (पहले के अनुरूप अंतर्निहित चर bar_index 0, और अंतर्निहित चर bar_index के अनुरूप दूसरा 1 है), इसलिए गणना परिणाम 2 है, जो चर v2 को सौंपा गया है, और इसी तरह। वास्तव में यह देखा जा सकता है कि v2 चार्ट में K-लाइन बार की संख्या है, क्योंकि K-लाइन का सूचकांकbar_index0 से बढ़ाया जाता है, तोbar_index + 1वास्तव में के लाइन बार की संख्या है। चार्ट पर, हम यह भी देख सकते हैं कि लाइनोंv2औरbar_indexवास्तव में ओवरलैप करते हैं।

    img

    इसी प्रकार, मैं भी उपयोग कर सकते हैंta.cumवर्तमान चार्ट पर सभी बार्स के लिए समापन कीमतों के योग की गणना करने के लिए अंतर्निहित समारोह. सब मुझे क्या करने की जरूरत है इस तरह लिखने के लिए हैःta.cum(close), जब रणनीति वास्तविक समय पट्टी पर सबसे दाईं ओर चलाता है, परिणाम द्वारा गणना की जाती हैta.cum(close)चार्ट पर सभी बार्स के समापन मूल्य का योग है (यदि यह सबसे दाईं ओर नहीं चलता है, तो यह केवल वर्तमान बार तक जमा होता है) ।

    समय श्रृंखला पर चरों की गणना ऑपरेटरों का उपयोग करके भी की जा सकती है, जैसे कि कोडःta.sma(high - low, 14), अंतर्निहित चर घटाएंhigh(के-लाइन बार का उच्चतम मूल्य) सेlow(के-लाइन बार का सबसे कम मूल्य), और अंत में उपयोग करेंta.smaऔसत मूल्य की गणना करने के लिए कार्य।

  • फ़ंक्शन कॉल का परिणाम भी समय श्रृंखला में मानों के निशान छोड़ देगा.

    v1 = ta.highest(high, 10)[1]
    v2 = ta.highest(high[1], 10)
    plot(v1, title="v1", overlay=true)
    plot(v2, title="v2", overlay=true)
    

    परीक्षण कोड बैकटेस्टिंग के दौरान चलाया जाता है, और यह देखा जा सकता है किv1औरv2फ़ंक्शन कॉल द्वारा गणना किया गया परिणाम समय श्रृंखला में मान के निशान छोड़ देगा, जैसे किta.highest(high, 10)कोड मेंta.highest(high, 10)[1]. फ़ंक्शन कॉल द्वारा गणना परिणाम भी उपयोग कर सकते हैं [1] अपने ऐतिहासिक मूल्य को संदर्भित करने के लिए.ta.highest(high, 10)वर्तमान पट्टी के पिछले पट्टी के अनुरूप, गणना का परिणाम हैta.highest(high[1], 10)तो.ta.highest(high[1], 10)औरta.highest(high, 10)[1]बिल्कुल समान हैं।

    किसी अन्य ड्राइंग फ़ंक्शन का उपयोग करके जानकारी सत्यापन आउटपुट करें:

    a = ta.highest(close, 10)[1]
    b = ta.highest(close[1], 10)
    plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true)
    plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
    

    हम देख सकते हैं कि समय श्रृंखला में चर a और चर b के मान संबंधित Bars के ऊपर और नीचे प्रदर्शित होते हैं। हम सीखने की प्रक्रिया के दौरान इस ड्राइंग कोड को रख सकते हैं, क्योंकि हमें अक्सर बैकटेस्टिंग और प्रयोग के दौरान अवलोकन के लिए चार्ट पर जानकारी आउटपुट करने की आवश्यकता हो सकती है।

    img

स्क्रिप्ट संरचना

सामान्य संरचना

ट्यूटोरियल के आरंभिक भाग में, हमने एफएमजेड और ट्रेडिंग व्यू पर पाइन भाषा का उपयोग करने में कुछ अंतरों का सारांश दिया है। जब आप एफएमजेड पर पाइन कोड लिखते हैं, तो आप संस्करण संख्या को छोड़ सकते हैं,indicator(), strategy(), औरlibrary()वर्तमान में समर्थित नहीं है। बेशक, पाइन स्क्रिप्ट के पुराने संस्करणों के साथ संगत होने के लिए, रणनीतियाँ जैसेः//@version=5, indicator(), strategy()कुछ रणनीति सेटिंग्स भी में पैरामीटर पारित करके सेट किया जा सकता हैstrategy() function.

<version>
<declaration_statement>
<code>

..<version>संस्करण नियंत्रण जानकारी को छोड़ दिया जा सकता है।

टिप्पणियाँ

पाइन भाषा का प्रयोग करता है//एक पंक्ति के टिप्पणी प्रतीक के रूप में, क्योंकि पाइन भाषा में एक बहु-पंक्ति टिप्पणी प्रतीक नहीं है। एफएमजेड टिप्पणी प्रतीक का विस्तार करता है/**/बहु-पंक्ति टिप्पणियों के लिए।

कोड

स्क्रिप्ट में जो पंक्तियाँ टिप्पणी या संकलक निर्देश नहीं हैं, वे कथन हैं, जो स्क्रिप्ट के एल्गोरिथ्म को लागू करते हैं। एक कथन इनमें से एक सामग्री हो सकती है।

  • परिवर्तनीय घोषणा
  • चरों का पुनर्वितरण
  • कार्य घोषणा
  • अंतर्निहित फ़ंक्शन कॉल, उपयोगकर्ता-परिभाषित फ़ंक्शन कॉल
  • if, for, whileयाswitchसंरचना

बयानों को विभिन्न तरीकों से व्यवस्थित किया जा सकता है

  • कुछ कथन एक पंक्ति में व्यक्त किए जा सकते हैं, जैसे कि अधिकांश चर घोषणाएं, केवल एक फ़ंक्शन कॉल वाली लाइनें, या एकल-पंक्ति फ़ंक्शन घोषणाएं। अन्य, संरचनाओं की तरह, हमेशा कई पंक्तियों की आवश्यकता होती है, क्योंकि उन्हें स्थानीय ब्लॉक की आवश्यकता होती है।
  • एक स्क्रिप्ट के वैश्विक दायरे में कथन (यानी भाग जो स्थानीय ब्लॉक का हिस्सा नहीं हैं) एक के साथ शुरू नहीं कर सकते हैंspaceया ```tab` (टैब कुंजी). उनका पहला वर्ण भी पंक्ति का पहला वर्ण होना चाहिए। पहली स्थिति से शुरू होने वाली पंक्तियाँ, परिभाषा के अनुसार, स्क्रिप्ट के वैश्विक दायरे का हिस्सा बन जाती हैं।
  • संरचना या बहु-पंक्ति फ़ंक्शन घोषणा के लिए हमेशा एकlocal blockएक स्थानीय ब्लॉक को एक टैब या चार रिक्त स्थानों से इंडेंट किया जाना चाहिए (अन्यथा, इसे पिछली पंक्ति के संबद्ध कोड के रूप में पार्स किया जाएगा, अर्थात, कोड की पिछली पंक्ति की निरंतर सामग्री माना जाएगा), और प्रत्येक स्थानीय ब्लॉक एक अलग स्थानीय दायरे को परिभाषित करता है।
  • एकाधिक एकल-पंक्ति के कथन को एक पंक्ति में कॉमा (,) का उपयोग करके विभाजक के रूप में संबद्ध किया जा सकता है।
  • एक पंक्ति में टिप्पणियां हो सकती हैं या केवल टिप्पणियां हो सकती हैं।
  • रेखाओं को भी लपेटा जा सकता है (कई रेखाओं पर जारी रखा जा सकता है) ।

उदाहरण के लिए, इसमें तीन स्थानीय ब्लॉक शामिल हैं, एक कस्टम फ़ंक्शन घोषणा में, और दो चर घोषणा में यदि संरचना का उपयोग करके, निम्नानुसारः

indicator("", "", true)             // declaration statement (global scope), can be omitted

barIsUp() =>                        // function declaration (global scope)
    close > open                    // local block (local scope)

plotColor = if barIsUp()            // variable declaration (global scope)
    color.green                     // local block (local scope)
else
    color.red                       // local block (local scope)

runtime.log("color", color = plotColor)  // Call a built-in function to output the log (global scope)

लाइन ब्रेक कोड

लंबी रेखाओं को कई रेखाओं पर विभाजित किया जा सकता है, या wrapped up। एक लपेटी हुई रेखा को किसी भी संख्या में रिक्त स्थानों द्वारा इंडेंट किया जाना चाहिए, जब तक कि यह 4 का गुणक न हो (इन सीमाओं का उपयोग स्थानीय ब्लॉकों को इंडेंट करने के लिए किया जाता है) ।

a = open + high + low + close

इसे इस प्रकार से पैक किया जा सकता है (ध्यान दें कि प्रति पंक्ति में इंद्रधनुष वाले रिक्त स्थानों की संख्या 4 का गुणक नहीं हो सकती):

a = open +
      high +
          low +
             close

एक लंबा प्लॉट ((() कॉल को इस तरह से लपेटा जा सकता हैः

close1 = request.security(syminfo.tickerid, "D", close)      // syminfo.tickerid daily level closing price data series for the current trading pair
close2 = request.security(syminfo.tickerid, "240", close)    // syminfo.tickerid 240-minute level closing price data series for the current trading pair
plot(ta.correlation(close, open, 100),                       // line-long plot() calls can be wrapped
   color = color.new(color.purple, 40),
   style = plot.style_area,
   trackprice = true)

उपयोगकर्ता-परिभाषित फ़ंक्शन घोषणाओं में कथन भी लपेटा जा सकता है। हालांकि, चूंकि एक स्थानीय ब्लॉक को व्याकरण में एक इंडेंट से शुरू होना चाहिए (4 रिक्त स्थान या 1 टैब), जब इसे अगली पंक्ति पर विभाजित किया जाता है, तो कथन की निरंतरता एक से अधिक इंडेंट से शुरू होनी चाहिए (अंतर के 4 गुणकों के बराबर नहीं) । उदाहरण के लिएः

test(c, o) =>
    ret = c > o ?
       (c > o+5000 ? 
          1 :
              0):
       (c < o-5000 ? 
          -1 : 
              0)
           
                   
a = test(close, open)
plot(a, title="a")

मार्कर और ऑपरेटर

मार्कर

चरों को पहचानने से पहले, हमें पहले मार्कर की अवधारणा को समझना चाहिए। आम आदमी के शब्दों में, मार्कर का उपयोग चर के नाम के रूप में किया जाता हैकार्यऔरचर(परिवर्तनों और कार्यों का नाम देने के लिए प्रयोग किया जाता है) ।कार्यहमारे बाद के ट्यूटोरियल में देखा जाएगा, चलो पहले मार्कर के बारे में जानें.

    1. मार्कर एक बड़े अक्षर के साथ शुरू करना चाहिए(A-Z)या छोटा अक्षर(a-z)अक्षर या रेखांकित(_)मार्कर के पहले अक्षर के रूप में।
    1. मार्कर के पहले अक्षर के बाद अगला वर्ण एक हो सकता हैपत्र, रेखांकन करना, या एकसंख्या.
    1. मार्करों का नामकरण केस-सेंसिटिव होता है।

जैसे कि निम्नलिखित नामित मार्कर:

fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown  // Wrong naming! It used a numeric character as the leading character of the marker

अधिकांश प्रोग्रामिंग भाषाओं की तरह, पाइन भाषा में लेखन सुझाव भी हैं। पहचानकर्ताओं का नामकरण करते समय आम तौर पर यह अनुशंसा की जाती हैः

    1. सभी बड़े अक्षरों का प्रयोग स्थिरांकों के नामकरण के लिए किया जाता है।
    1. उपयोग करेंकमल केसअन्य मार्कर नामों के लिए।
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7

// name functions
zeroOne(boolValue) => boolValue ? 1 : 0

ऑपरेटर

ऑपरेटर कुछ ऑपरेशन प्रतीक हैं जो प्रोग्रामिंग भाषाओं में अभिव्यक्ति बनाने के लिए उपयोग किए जाते हैं, और अभिव्यक्ति कुछ कंप्यूटेशनल उद्देश्यों के लिए डिज़ाइन किए गए कंप्यूटेशनल नियम हैं जब हम रणनीतियाँ लिखते हैं। पाइन भाषा में ऑपरेटरों को फ़ंक्शन के अनुसार वर्गीकृत किया जाता हैः

असाइनमेंट ऑपरेटर, अंकगणितीय ऑपरेटर, तुलना ऑपरेटर, तार्किक ऑपरेटर,? :तृतीयक संचालक,[]ऐतिहासिक संदर्भ संचालक।

अंकगणितीय संचालक लेना*उदाहरण के रूप में, यह ट्रेडिंग व्यू पर पाइन भाषा ऑपरेटर के रिटर्न परिणाम के कारण होने वाली प्रकार समस्या से अलग है। निम्नलिखित परीक्षण कोड प्रदान किया गया हैः

//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength)  // Compilation error!
plot(ma)

ट्रेडिंग दृश्य पर इस स्क्रिप्ट को निष्पादित करते समय, एक संकलन त्रुटि होगी। कारण यह है कि गुणा करने के बादadjustedLength = lenInput * factor, परिणाम हैseries intप्रकार (श्रृंखला), लेकिन समारोह के दूसरे पैरामीटरta.emaलेकिन एफएमजेड पर ऐसे कोई सख्त प्रतिबंध नहीं हैं, उपरोक्त कोड सामान्य रूप से चलाया जा सकता है।

आइए विभिन्न ऑपरेटरों के उपयोग को एक साथ देखें।

असाइनमेंट ऑपरेटर

असाइनमेंट ऑपरेटर के 2 प्रकार हैंः=, :=, जो हम ट्यूटोरियल के शुरुआती भाग में कई उदाहरणों में देखा है.

..=ऑपरेटर का उपयोग एक चर को एक मान सौंपने के लिए किया जाता है जब यह आरंभिक या घोषित किया जाता है। चर जो आरंभिक, घोषित और आरंभिक के साथ असाइन किए जाते हैं=प्रत्येक बाद के बार पर उस मूल्य के साथ शुरू होगा. ये वैध चर घोषणाएं हैंः

a = close           // Use built-in variables to assign values to a
b = 10000           // Use numerical assignment
c = "test"          // Use string assignment
d = color.green     // Use color value assignment
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)

ध्यान दें कि असाइनमेंट स्टेटमेंटa = close, प्रत्येक बार पर चर a बार का वर्तमान समापन मूल्य (बंद) है। अन्य चरb, c, dअपरिवर्तित हैं और एफएमजेड पर बैकटेस्ट सिस्टम में परीक्षण किया जा सकता है, और परिणाम चार्ट पर देखे जा सकते हैं।

:=इसका प्रयोग मौजूदा चरों के लिए मूल्यों को फिर से असाइन करने के लिए किया जाता है।:=ऑपरेटर का उपयोग घोषित और आरंभिकरण किए गए चर के मानों को संशोधित करने के लिए किया जाता है। यदि हम:=ऑपरेटर एक अनइनिशियल या घोषित चर के लिए एक मान असाइन करने के लिए, यह एक त्रुटि का कारण होगा, उदाहरण के लिएः

a := 0

इसलिए,:=असाइनमेंट ऑपरेटर का उपयोग आमतौर पर मौजूदा चर को फिर से असाइन करने के लिए किया जाता है, उदाहरण के लिएः

a = close > open 
b = 0 
if a
    b := b + 1

plot(b)

यह देखते हुए किclose > open(यानी वर्तमान BAR एक सकारात्मक रेखा है), चर एक सच है। यदि कथन के स्थानीय ब्लॉक में कोडb := b + 1निष्पादित किया जाता है, और असाइनमेंट ऑपरेटर:=b को फिर से आवंटित करने के लिए प्रयोग किया जाता है, और 1 जोड़ा जाता है। फिर हम चार्ट पर समय श्रृंखला के प्रत्येक BAR पर चर b का मूल्य आकर्षित करने के लिए प्लॉट फ़ंक्शन का उपयोग करते हैं, और उन्हें एक रेखा में जोड़ते हैं।

क्या हमें लगता है कि जब एक सकारात्मक रेखा BAR दिखाई देती है, तो b 1 से जमा होता रहेगा? निश्चित रूप से नहीं, यहां हम किसी भी कीवर्ड पदनाम का उपयोग किए बिना चर b को 0 के रूप में घोषित और आरंभ करते हैं। यह वाक्यb=0प्रत्येक बार पर निष्पादित किया जाता है, तो हम देख सकते हैं कि इस कोड का परिणाम 0 के लिए b चर को रीसेट करने के लिए हर बार है, यदि चर एक सच है, कि है, के साथ लाइन में हैclose > open, तो b को 1 से बढ़ाया जाएगा जब कोड इस दौर में निष्पादित किया जाता है, और b 1 है जब प्लॉट फ़ंक्शन ड्रॉ करता है, लेकिन b को अगले दौर में कोड निष्पादित होने पर 0 में फिर से असाइन किया जाता है। यह वह जगह भी है जहां पाइन भाषा के शुरुआती फंसने के लिए प्रवण होते हैं।

जब यह असाइनमेंट ऑपरेटरों की बात आती है, तो हमें दो कीवर्ड पर विस्तार करना चाहिएःvar, varip

  • विर

    वास्तव में, हमने इस कीवर्ड को पिछले ट्यूटोरियल में देखा और इस्तेमाल किया है, लेकिन हमने उस समय विस्तार से चर्चा नहीं की। आइए पहले इस कीवर्ड के विवरण को देखेंः

    var एक कीवर्ड है जिसका उपयोग चर को आवंटित करने और एक बार आरंभ करने के लिए किया जाता है। सामान्य तौर पर, चर असाइनमेंट व्याकरण जिसमें कीवर्ड var नहीं होता है, प्रत्येक बार डेटा अपडेट होने पर चरs मान को अधिलेखित कर देता है। इसके विपरीत, जब चर को कीवर्ड var का उपयोग करके असाइन किया जाता है, तो वे डेटा अपडेट के बावजूद राज्य बनाए रख सकते हैं।

    हम अभी भी इस उदाहरण का उपयोग करते हैं, लेकिन हम का उपयोगvarयहाँ b को मान निर्दिष्ट करते समय कीवर्ड।

    a = close > open 
    var b = 0 
    if a
        b := b + 1
    
    plot(b)
    

    ..varकीवर्ड चर b को केवल प्रारंभिक असाइनमेंट करने की अनुमति देता है, और फिर यह हर बार रणनीति तर्क निष्पादित होने पर b को 0 पर रीसेट नहीं करेगा, इसलिए यह रनटाइम पर खींची गई रेखा से देखा जा सकता है कि b सकारात्मक रेखा BARs की संख्या है जो तब दिखाई दी है जब वर्तमान K रेखा BAR बैकटेस्ट किया गया था।

    var द्वारा घोषित चर न केवल वैश्विक दायरे में, बल्कि कोड ब्लॉक में भी लिखे जा सकते हैं, जैसे कि यह उदाहरणः

    strategy(overlay=true)
    var a = close
    var b = 0.0
    var c = 0.0
    var green_bars_count = 0
    if close > open
        var x = close
        b := x
        green_bars_count := green_bars_count + 1
        if green_bars_count >= 10
            var y = close
            c := y
    plot(a, title = "a")
    plot(b, title = "b")
    plot(c, title = "c")
    

    चर a श्रृंखला के पहले पट्टी के समापन मूल्य को रखता है। चर b श्रृंखला के पहले green मूल्य पट्टी के समापन मूल्य को रखता है। चर c श्रृंखला में दसवें green बार का समापन मूल्य रखता है।

  • विविधता

    हम खोजशब्द देखते हैंvaripपहली बार, हम इस कीवर्ड के विवरण को देख सकते हैंः

    varp (var intrabar persist) चर को असाइन करने और एक बार आरंभ करने के लिए एक कीवर्ड है। यह var कीवर्ड के समान है, लेकिन वास्तविक समय के-लाइन अपडेट के दौरान varip के साथ घोषित चर अपने मानों को बनाए रखते हैं।

    क्या यह समझना मुश्किल है? इससे कोई फर्क नहीं पड़ता, हम इसे एक उदाहरण के माध्यम से समझाते हैं, यह समझना आसान है।

    strategy(overlay=true)
    
    // test var varip
    var i = 0
    varip ii = 0  
    
    // Print the i and ii changed in each round of the strategy logic on the chart
    plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
    plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)  
    
    // Increment i and ii by 1 for each round of logic execution
    i := i + 1
    ii := ii + 1
    

    इस परीक्षण कोड में बार मॉडल और टिक मॉडल पर अलग-अलग प्रदर्शन हैंः

    पट्टी मॉडलः क्या आपको याद है कि रणनीति निष्पादन हम पहले समझाया ऐतिहासिक बार चरण और वास्तविक समय बार चरण में विभाजित है? बार मॉडल में, ऐतिहासिक के लाइन चरण, चरi, iiमें घोषितvar, varipरणनीति कोड के निष्पादन के प्रत्येक दौर में वृद्धिशील संचालन करें। इसलिए यह देखा जा सकता है कि बैकटेस्ट परिणाम के के-लाइन बार पर प्रदर्शित संख्याओं को एक-एक करके बढ़ाया जाता है। जब ऐतिहासिक के-लाइन चरण समाप्त होता है, तो वास्तविक समय के-लाइन चरण शुरू होता है। var और varip द्वारा घोषित चर अलग-अलग परिवर्तनों से गुजरना शुरू करते हैं। क्योंकि यह बार मॉडल है, इसलिए रणनीति कोड एक बार निष्पादित किया जाएगा।i := i + 1औरii := ii + 1एक बार निष्पादित किया जाएगा। अंतर यह है कि ii हर बार संशोधित किया जाता है। हालांकि i हर बार संशोधित किया जाता है, पिछले मूल्य को बहाल किया जाएगा जब रणनीति तर्क अगले दौर में निष्पादित किया जाता है (रोलबैक तंत्र याद रखें जिसे हमने पिछले अध्याय में समझाया था?), और वर्तमान के-लाइन BAR पूरा होने तक i का मूल्य अपडेट नहीं किया जाएगा (यानी, पिछले मूल्य को बहाल नहीं किया जाएगा जब रणनीति तर्क अगले दौर में निष्पादित किया जाता है) । इसलिए यह देखा जा सकता है कि चर i अभी भी प्रत्येक BAR के लिए 1 से बढ़ाया जाता है। लेकिन चर ii प्रत्येक BAR के लिए कई बार जमा होता है।

    टिक मॉडलः चूंकि टिक मॉडल प्रति K-लाइन BAR में केवल एक बार रणनीति तर्क निष्पादित करता है। इसलिए समापन मूल्य मॉडल में, var और varip द्वारा घोषित चर ऐतिहासिक K-लाइन चरण और वास्तविक समय K-लाइन चरण के दौरान प्रत्येक K-लाइन BAR के लिए 1 से बढ़ते हुए उपरोक्त उदाहरण में बिल्कुल समान व्यवहार करते हैं।

अंकगणितीय संचालक
ऑपरेटर विवरण
+ जोड़ना
- घटाव
* गुणन
/ डिवीजन
% मॉड्यूल

..+और-अन्य अंकगणितीय संचालकों का उपयोग केवल द्विआधारी संचालकों के रूप में किया जा सकता है और यह एक त्रुटि रिपोर्ट करेगा यदि इसका उपयोग युनरी संचालकों के रूप में किया गया था।

  1. अंकगणितीय संचालक के दोनों पक्ष संख्यात्मक प्रकार के होते हैं, परिणाम संख्यात्मक प्रकार, पूर्णांक या फ्लोटिंग पॉइंट होता है जो ऑपरेशन के परिणाम के आधार पर होता है।
  2. यदि एक ऑपरेन्ड स्ट्रिंग है और ऑपरेटर है+, गणना का परिणाम एक स्ट्रिंग है, मान स्ट्रिंग रूप में परिवर्तित किया जाएगा, और फिर स्ट्रिंग एक साथ सिलाई कर रहे हैं। यदि यह अन्य अंकगणितीय संचालक है, यह स्ट्रिंग को मान में परिवर्तित करने का प्रयास करेगा और फिर ऑपरेशन पर ले जाएगा।
  3. यदि किसी एक ऑपरेंड की संख्या na है, तो गणना का परिणाम शून्य मानna है, और यह FMZ पर मुद्रित होने पर NaN दिखाएगा।
a = 1 + 1 
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na 

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)   
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN

एफएमजेड पर पाइन भाषा ट्रेडिंग व्यू पर पाइन भाषा से थोड़ा अलग है, एफएमजेड पर पाइन भाषा चर प्रकारों के बारे में बहुत सख्त नहीं है। उदाहरण के लिएः

a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A" 

plot(a)
plot(b)
plot(c)

यह FMZ पर काम करता है, लेकिन यह ट्रेडिंग व्यू पर एक प्रकार की त्रुटि की रिपोर्ट करता है। यदि अंकगणितीय ऑपरेटर के दोनों ऑपरेड स्ट्रिंग हैं, तो सिस्टम स्ट्रिंग को संख्यात्मक मानों में परिवर्तित करता है और फिर उन्हें गणना करता है। यदि एक गैर-संख्यात्मक स्ट्रिंग की गणना नहीं की जा सकती है, तो सिस्टम ऑपरेशन का परिणाम शून्य मान है।

तुलना ऑपरेटर

तुलना ऑपरेटर सभी बाइनरी ऑपरेटर हैं।

ऑपरेटर विवरण
< <
> >
<= <=
>= >=
== ==
!= !=

परीक्षण उदाहरणः

a = 1 > 2 
b = 1 < 2 
c = "1" <= 2 
d = "1" >= 2 
e = 1 == 1 
f = 2 != 1 
g = open > close 
h = na > 1 
i = 1 > na

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)   
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false

जैसा कि हम देख सकते हैं, तुलना संचालक का उपयोग करने के लिए बहुत आसान है, लेकिन यह भी संचालक हम सबसे अधिक उपयोग करते हैं जब रणनीतियों लिखने के लिए है। दोनों संख्यात्मक मान और अंतर्निहित चर तुलना की जा सकती है, जैसे किclose, openआदि। ऑपरेटर के साथ के रूप में, FMZ और ट्रेडिंग व्यू के बीच पाइन भाषा के बारे में एक अंतर है। FMZ प्रकार के लिए विशेष रूप से सख्त आवश्यकताओं नहीं है, इसलिए, इस तरह के बयानd = "1" >= 2एफएमजेड पर कोई त्रुटि रिपोर्ट नहीं करेगा, और इसे पहले स्ट्रिंग को मान में परिवर्तित करके और फिर ऑपरेशन की तुलना करके निष्पादित किया जाएगा। ट्रेडिंग व्यू पर, यह त्रुटि रिपोर्ट करेगा।

तार्किक संचालक
ऑपरेटर कोड चिह्न विवरण
नहीं नहीं यूनरी ऑपरेटर, ऑपरेशन नहीं
और और द्विआधारी संचालक और संचालन
या या बाइनरी ऑपरेटर या ऑपरेशन

जब यह तार्किक संचालकों के लिए आता है, तो हम सही मूल्य तालिकाओं के बारे में बात करनी चाहिए. वही हम हाई स्कूल में सीखा है, यहाँ हम सिर्फ परीक्षण और हमारे बैकटेस्टिंग प्रणाली में सीखनेः

a = 1 == 1  // An expression formed by using comparison operators, the result is a Boolean value
b = 1 != 1
c = not b   // Logical not operators
d = not a   // Logical not operators

runtime.log("test the logical operator:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)

runtime.log("test the logical operator:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)

runtime.error("stop")

संदेशों को ओवरप्रिंट नहीं करने के लिए, हम एक त्रुटि फेंक के साथruntime.error("stop")और इसे एक बार प्रिंट करने के बाद रोक दें। उसके बाद, हम आउटपुट जानकारी का निरीक्षण कर सकते हैं, और हम पा सकते हैं कि मुद्रित सामग्री वास्तव में वास्तविक मूल्य तालिका के समान है।

तृतीयक संचालक

तृतीयक संचालक का प्रयोग करने वाले तृतीयक अभिव्यक्ति? :संचालकों के साथ संयुक्तcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseहमने उन्हें पिछले पाठों में भी इस्तेमाल किया है। तथाकथित तृतीयक अभिव्यक्ति, तृतीयक ऑपरेटर का अर्थ है कि इसमें तीन ऑपरेड हैं।

मेंcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse, conditionयदि यह सच है, तो अभिव्यक्ति का मान हैःvalueWhenConditionIsTrueयदिconditionगलत है, तो अभिव्यक्ति का मूल्य हैvalueWhenConditionIsFalse.

एक सुविधाजनक प्रदर्शन का उदाहरण, हालांकि व्यावहारिक उपयोग का बहुत कमः

a = close > open
b = a ? "positive line" : "negative line"
c = not a ? "negative line" : "positive line"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

अगर हम एक डोजी का सामना करते हैं तो क्या करें? इससे कोई फर्क नहीं पड़ता! टर्नरी एक्सप्रेशंस को भी नेस्टेड किया जा सकता है, जैसा कि हमने पिछले ट्यूटोरियल में किया था।

a = close > open
b = a ? math.abs(close-open) > 30 ? "positive line" : "doji" : math.abs(close-open) > 30 ? "negative line" : "doji"
c = not a ? math.abs(close-open) > 30 ? "negative line" : "doji" : math.abs(close-open) > 30 ? "positive line" : "doji"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

दरअसल, यह प्रतिस्थापन के बराबर है।valueWhenConditionIsTrueऔरvalueWhenConditionIsFalseमेंcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseएक और तृतीयक अभिव्यक्ति के साथ।

ऐतिहासिक संचालक

इतिहास संचालक का प्रयोग करें[]एक समय श्रृंखला पर ऐतिहासिक मूल्यों का संदर्भ देने के लिए. इन ऐतिहासिक मूल्यों वर्तमान K-लाइन पट्टी से पहले K-लाइन पट्टी पर चर के मूल्य हैं जब स्क्रिप्ट चल रहा था.[]ऑपरेटर का प्रयोग चर, अभिव्यक्ति और फ़ंक्शन कॉल के बाद किया जाता है.[]वर्ग कोष्ठक वर्तमान K-लाइन BAR से संदर्भित करने के लिए हम चाहते हैं ऐतिहासिक डेटा के ऑफसेट है. उदाहरण के लिए अगर मैं पिछले K-लाइन BAR के समापन मूल्य उद्धृत करना चाहते हैं, हम इसे के रूप में लिखते हैंःclose[1].

हमने पिछले पाठों में कुछ इस तरह देखा हैः

high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)

..[]ऑपरेटर का उपयोग एक ही मान पर केवल एक बार किया जा सकता है, इसलिए इसे इस तरह से लिखना गलत है, और एक त्रुटि की सूचना दी जाएगीः

a = close[1][2]   // error

यहाँ, कोई कह सकता है कि ऑपरेटर[]श्रृंखला संरचना के लिए प्रयोग किया जाता है, ऐसा लगता है कि श्रृंखला संरचना (श्रृंखला) सरणी के समान है! आइए पाइन भाषा में श्रृंखला और सरणी के बीच अंतर को स्पष्ट करने के लिए एक उदाहरण का उपयोग करें।

strategy("test", overlay=true)

a = close
b = close[1]
c = b[1]

plot(a, title="a")
plot(b, title="b")
plot(c, title="c")

a = close[1][2]त्रुटि की सूचना देगा, लेकिनः

b = close[1]
c = b[1]

लेकिन अगर अलग से लिखा है, यह एक त्रुटि रिपोर्ट नहीं करेगा. अगर हम इसे सामान्य सरणी के अनुसार समझते हैं, के असाइनमेंट के बादb = close [1], b एक मान होना चाहिए, लेकिनc = b[1], b का उपयोग इतिहास संचालक का उपयोग करके ऐतिहासिक मान को फिर से संदर्भित करने के लिए किया जा सकता है। यह देखा जा सकता है कि पाइन भाषा में श्रृंखला की अवधारणा एक सरणी के रूप में सरल नहीं है। इसे बंद (बी को सौंपा गया) के अंतिम पट्टी पर ऐतिहासिक मान के रूप में समझा जा सकता है, b भी एक समय श्रृंखला संरचना (समय श्रृंखला) है, और इसकी h


अधिक