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

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

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

तो हम देखते हैं कि रेखांकित तीन लाइनों में ए, बी, और सी, लाइन बी लाइन ए की तुलना में एक बार धीमी है, और लाइन सी लाइन बी की तुलना में एक बार धीमी है। लाइन सी लाइन ए की तुलना में 2-बार धीमी है।

हम चार्ट को सबसे बाईं ओर खींच सकते हैं और देख सकते हैं कि पहली K-लाइन पर, b और c दोनों के मान शून्य (na) हैं। ऐसा इसलिए है क्योंकि जब स्क्रिप्ट को पहली K-लाइन BAR पर निष्पादित किया जाता है, तो यह मौजूद नहीं होता है जब एक या दो अवधियों के ऐतिहासिक मूल्य का संदर्भ दिया जाता है, जो मौजूद नहीं है। इसलिए, हमें यह जांचने के लिए रणनीतियों को लिखने के लिए सावधान रहने की आवश्यकता है कि ऐतिहासिक डेटा का संदर्भ शून्य मानों का परिणाम देगा या नहीं। यदि शून्य मूल्य का लापरवाही से उपयोग किया जाता है, तो यह गणना अंतर की एक श्रृंखला का कारण बन जाएगा, और वास्तविक समय BAR को भी प्रभावित कर सकता है। आमतौर पर हम अंतर्निहित कार्यों का उपयोग करेंगेna, nzकोड में न्याय करने के लिए (वास्तव में, हम भी सामना किया हैnz, ```na`` हमारे पिछले वीडियो में, क्या आपको याद है कि यह कौन सा अध्याय है?

close > nz(close[1], open)    // When referencing the historical value of the previous BAR of the close built-in variable, if it does not exist, the open built-in variable is used

यह शून्य मानों (na) के संभावित संदर्भों को संभालने का एक तरीका है।

ऑपरेटर प्राथमिकता

हमने पाइन भाषा में बहुत सारे ऑपरेटर सीखे हैं। ये ऑपरेटर ऑपरेंड के साथ विभिन्न संयोजनों के माध्यम से अभिव्यक्ति बनाते हैं। तो अभिव्यक्ति में मूल्यांकन करते समय इन कार्यों की प्राथमिकता क्या है? स्कूल में सीखे गए अंकगणित की तरह, गुणन और विभाजन की गणना पहले की जाती है, इसके बाद जोड़ और घटाव होता है। पाइन भाषा में अभिव्यक्ति के लिए भी ऐसा ही होता है।

प्राथमिकता ऑपरेटर
9 []
8 +-औरnotएकात्मक संचालक में
7 */%
6 +-बाइनरी ऑपरेटर में
5 ><>=<=
4 ==!=
3 and
2 or
1 ?:

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

चर

परिवर्तनीय घोषणा

हमने पहले ही marker की अवधारणा का अध्ययन किया है, जिसका उपयोग एक चर के नाम के रूप में किया जाता है, अर्थात, एक चर एक मार्कर है जो एक मूल्य रखता है। तो हम एक चर कैसे घोषित करते हैं? चर घोषित करने के नियम क्या हैं?

  • घोषणा मोडः एक चर घोषित करते समय लिखने के लिए पहली बात declaration mode है। चर के लिए तीन घोषणा मोड हैंः

    1. खोजशब्द का प्रयोग करेंvar.
    2. खोजशब्द का प्रयोग करेंvarip.
    3. कुछ भी मत लिखो।

    ..varऔरvaripकीवर्ड वास्तव में हमारे पिछले अध्याय में अध्ययन किया गया हैAssignment Operators, तो हम यहाँ विवरण में नहीं जाना होगा. यदि कुछ भी चर घोषणा मोड के लिए लिखा नहीं है, जैसे कि कथन के रूप मेंःi = 1, जैसा कि हम पहले भी उल्लेख किया है, इस तरह के एक चर घोषित और सौंपा हर K-लाइन BAR पर निष्पादित किया जाता है।

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

    int i = 0 
    float f = 1.1
    

    ट्रेडिंग व्यू पर प्रकार की आवश्यकताएं काफी सख्त हैं और यदि ट्रेडिंग व्यू पर निम्न कोड का उपयोग किया जाता है तो त्रुटि की सूचना दी जाएगी:

    baseLine0 = na          // compile time error!
    
  • मार्कर मार्कर चर नाम हैं। मार्करों के नामकरण का उल्लेख पिछले अध्यायों में किया गया है, इसलिए आप इसे यहाँ समीक्षा कर सकते हैंःhttps://www.fmz.com/bbs-topic/9637#markers

संक्षेप में, एक चर घोषित करने के रूप में लिखा जा सकता हैः

// [<declaration_mode>] [<type>] <marker> = value 
   declaration mode             type     marker      = value

असाइनमेंट ऑपरेटर का प्रयोग यहाँ किया जाता हैः=जब यह घोषित किया जाता है एक चर के लिए एक मूल्य असाइन करता है. असाइन करते समय मूल्य एक स्ट्रिंग, संख्या, अभिव्यक्ति, फ़ंक्शन कॉल हो सकता है,if, for, while, याswitchऔर अन्य संरचनाओं (इन संरचनात्मक कुंजी शब्दों और कथन उपयोग के बाद के पाठ्यक्रमों में विस्तार से समझाया जाएगा. वास्तव में, हम सरल सीखा है अगर कथन पिछले पाठ्यक्रमों में असाइनमेंट और आप उन्हें समीक्षा कर सकते हैं).

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

इनपुट फ़ंक्शन:

input function, parameters: defval、title、tooltip、inline、group

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

param1 = input(10, title="name of param1", tooltip="description for param1", group="group name A")
param2 = input("close", title="name of param2", tooltip="description for param2", group="group name A")
param3 = input(color.red, title="name of param3", tooltip="description for param3", group="group name B")
param4 = input(close, title="name of param4", tooltip="description for param4", group="group name B")
param5 = input(true, title="name of param5", tooltip="description for param5", group="group name C")

ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)

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

img

हम इनपुट फंक्शन के कई मुख्य मापदंडों का परिचय देते हैंः

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

व्यक्तिगत चर घोषणा और असाइनमेंट के अलावा, चर के एक समूह को घोषित करने और उन्हें पाइन भाषा में असाइन करने का एक तरीका भी हैः

[Variable A, Variable B, Variable C] = function or structure, such as ```if```, ```for```, ```while``` or ```switch```

सबसे आम है जब हम उपयोग करते हैंta.macdMACD संकेतक की गणना करने के लिए कार्य, क्योंकि MACD संकेतक एक बहु-लाइन संकेतक है, डेटा के तीन सेट की गणना की जाती है। तो यह लिखा जा सकता हैः

[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 चार्ट आसानी से बना सकते हैं। न केवल अंतर्निहित फ़ंक्शन कई चरों को वापस कर सकते हैं, बल्कि लिखित कस्टम फ़ंक्शन भी कई डेटा को वापस कर सकते हैं।

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)

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

[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)

स्थिति संरचना

कुछ फ़ंक्शनों को सशर्त शाखा के स्थानीय कोड ब्लॉक में नहीं लिखा जा सकता है, मुख्य रूप से निम्नलिखित फ़ंक्शन शामिल हैंः

बारकलर (), भराव (), लाइन (), संकेतक (), प्लॉट (), प्लॉटकैंडल (), प्लॉटचर (), प्लॉटशेप (), प्लॉटशेप ())

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

strategy("test", overlay=true)
if close > open 
    plot(close, title="close")
else 
    plot(open, title="open")

if कथन

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

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)

मुख्य बिंदु: बुलियन मानों को वापस करने वाले निर्णयों के लिए प्रयुक्त अभिव्यक्ति. इंडेंटशन पर ध्यान दें. अधिकतम एक और शाखा हो सकती है. यदि सभी शाखा अभिव्यक्ति सही नहीं हैं और कोई अन्य शाखा नहीं है, तो n लौटाएं.

x = if close > open
    close
plot(x, title="x")

स्विच स्टेटमेंट

स्विच कथन एक शाखा-संरचित कथन भी है, जिसका उपयोग कुछ शर्तों के अनुसार निष्पादित किए जाने वाले विभिन्न पथों को डिजाइन करने के लिए किया जाता है। आम तौर पर, स्विच कथन में निम्नलिखित प्रमुख ज्ञान बिंदु होते हैं।

  1. स्विच कथन, यदि कथन की तरह, एक मान भी लौटा सकता है।
  2. अन्य भाषाओं में स्विच स्टेटमेंट के विपरीत, जब एक स्विच कंस्ट्रक्ट निष्पादित किया जाता है, तो इसके कोड का केवल एक स्थानीय ब्लॉक निष्पादित किया जाता है, इसलिए ब्रेक स्टेटमेंट अनावश्यक है (यानी, ब्रेक जैसे कीवर्ड लिखने की आवश्यकता नहीं है) ।
  3. स्विच की प्रत्येक शाखा एक स्थानीय कोड ब्लॉक लिख सकती है, इस स्थानीय कोड ब्लॉक की अंतिम पंक्ति रिटर्न मान है (यह मूल्यों का एक टपल हो सकता है). यदि किसी भी शाखाबद्ध स्थानीय कोड ब्लॉक को निष्पादित नहीं किया गया था तो na लौटाता है।
  4. स्विच संरचना में अभिव्यक्ति स्थिति निर्धारित करती है एक स्ट्रिंग, चर, अभिव्यक्ति या फ़ंक्शन कॉल लिख सकते हैं।
  5. स्विच एक रिटर्न मान निर्दिष्ट करने की अनुमति देता है जो डिफ़ॉल्ट मान के रूप में कार्य करता है जब संरचना में निष्पादित करने के लिए कोई अन्य मामला नहीं है।

स्विच के दो रूप हैं, आइए उनके उपयोग को समझने के लिए उदाहरणों को एक-एक करके देखें।

  1. switchअभिव्यक्ति के साथ - उदाहरण स्पष्टीकरणः
// input.string: defval, title, options, tooltip
func = input.string("EMA", title="indicator name", tooltip="select the name of the indicator function to be used", options=["EMA", "SMA", "RMA", "WMA"])

// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="period parameter")
fastPeriod = input.int(10, title="fastPeriod parameter", options=[5, 10, 20])
slowPeriod = input.int(20, title="slowPeriod parameter", options=[20, 25, 30])

data = input(close, title="data", tooltip="select the closing price, opening price, highest price...")
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 functions. input.stringएक स्ट्रिंग वापस करने के लिए प्रयोग किया जाता है, औरinput.intफ़ंक्शन का उपयोग पूर्णांक मान वापस करने के लिए किया जाता है. उदाहरण में, वहाँ एक नया उपयोग हैoptionsपैरामीटर।optionsपैरामीटर वैकल्पिक मानों की एक सरणी पारित किया जा सकता है, जैसे किoptions=["EMA", "SMA", "RMA", "WMA"]औरoptions=[5, 10, 20]उदाहरण में (ध्यान दें कि एक स्ट्रिंग प्रकार है, दूसरा एक संख्यात्मक प्रकार है). इस तरह, रणनीति इंटरफ़ेस पर नियंत्रणों को विशिष्ट मानों को इनपुट करने की आवश्यकता नहीं है, लेकिन नियंत्रण विकल्प पैरामीटर में प्रदान किए गए इन विकल्पों का चयन करने के लिए ड्रॉप-डाउन बॉक्स बन जाते हैं।

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

ऊपर हमारे परीक्षण कोड में, स्विच के डिफ़ॉल्ट शाखा कोड ब्लॉक में runtime.error की अंतिम पंक्ति के बाद, हमने [na, na] जैसे कोड को रिटर्न मान के साथ संगत होने के लिए नहीं जोड़ा। इस समस्या को ट्रेडिंग व्यू पर विचार करने की आवश्यकता है। यदि प्रकार असंगत है, तो एक त्रुटि की सूचना दी जाएगी। लेकिन एफएमजेड पर, क्योंकि प्रकार सख्ती से आवश्यक नहीं है, इस संगतता कोड को छोड़ दिया जा सकता है। इसलिए, एफएमजेड पर यदि और स्विच शाखाओं के रिटर्न मान की प्रकार संगतता पर विचार करने की आवश्यकता नहीं है।

strategy("test", overlay=true)
x = if close > open
    close
else
    "open"
plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)

एफएमजेड पर कोई त्रुटि रिपोर्ट नहीं की जाएगी, लेकिन ट्रेडिंग दृश्य पर एक त्रुटि रिपोर्ट की जाएगी। क्योंकि यदि शाखा द्वारा लौटाया गया प्रकार असंगत है।

  1. switchबिना भावों के

अगला, चलो उपयोग करने के लिए एक और तरीका देखते हैंswitch, यानी बिना भावों के।

up = close > open     // up = close < open 
down = close < open 
var upOfCount = 0 
var downOfCount = 0 

msgColor = switch
    up  => 
        upOfCount += 1 
        color.green 
    down => 
        downOfCount += 1
        color.red

plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true)
plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)

जैसा कि हम परीक्षण कोड उदाहरण से देख सकते हैं, स्विच स्थानीय कोड ब्लॉक के निष्पादन से मेल खाएगा जो शाखा शर्त पर सच है। सामान्य तौर पर, स्विच कथन के बाद शाखा शर्तों को परस्पर अनन्य होना चाहिए। यानी, उदाहरण में ऊपर और नीचे एक ही समय में सच नहीं हो सकते। क्योंकि स्विच केवल एक शाखा के स्थानीय कोड ब्लॉक को निष्पादित कर सकता है, यदि आप रुचि रखते हैं, तो आप कोड में इस पंक्ति को बदल सकते हैंःup = close > open // up = close < openटिप्पणी में सामग्री के लिए, और परिणाम का निरीक्षण करने के लिए बैकटेस्ट. आप पाएंगे कि स्विच शाखा केवल पहली शाखा को निष्पादित कर सकती है. इसके अलावा, जितना संभव हो उतना स्विच की शाखा में फ़ंक्शन कॉल न लिखने के लिए ध्यान देना आवश्यक है, फ़ंक्शन को प्रत्येक बार पर नहीं बुलाया जा सकता है, जिससे कुछ डेटा गणना समस्याएं हो सकती हैं (जब तक कि उदाहरण में "switchअभिव्यक्ति के साथ", निष्पादन शाखा निर्धारक है और रणनीति संचालन के दौरान नहीं बदला जाएगा) ।

लूप संरचना

बयान के लिए

return value = for count = start count to final count by step length
    statement                                            // Note: There can be break and continue in the statement
    statement                                            // Note: The last statement is the return value

for कथन का उपयोग करना बहुत सरल है, for लूप अंततः एक मान (या कई मान, [a, b, c] के रूप में) वापस कर सकता है। उपरोक्त छद्मकोड में return value स्थिति को सौंपे गए चर की तरह। for कथन के बाद एक count चर होता है जिसका उपयोग लूपों की संख्या को नियंत्रित करने, अन्य मानों का उल्लेख करने, आदि के लिए किया जाता है। count चर को लूप शुरू होने से पहले प्रारंभिक गणना सौंपा जाता है, फिर step लंबाई सेटिंग के अनुसार वृद्धि होती है, और जब count चर final count से बड़ा होता है तो लूप बंद हो जाता है।

..breakfor लूप में इस्तेमाल किया गया कीवर्डः लूप बंद हो जाता है जबbreakकथन निष्पादित किया जाता है. दcontinuefor लूप में इस्तेमाल किया गया कीवर्डः जबcontinueकथन निष्पादित किया जाता है, पाश कोड के बाद अनदेखा करेगाcontinueऔर लूप के अगले दौर को सीधे निष्पादित करें. for कथन लूप के अंतिम निष्पादन से लौटाता है. और यदि कोई कोड निष्पादित नहीं किया जाता है तो यह शून्य लौटाता है.

फिर हम एक सरल उदाहरण के साथ प्रदर्शित करते हैंः

ret = for i = 0 to 10       // We can increase the keyword by to modify the step length, FMZ does not support reverse loops such as i = 10 to 0 for now
    // We can add condition settings, use continue to skip, use break to jump out
    runtime.log("i:", i)
    i                       // If this line is not written, it will return null because there is no variable to return
    
runtime.log("ret:", ret)
runtime.error("stop")

के लिए... बयान में

..for ... inकथन के दो रूप हैं, हम उन्हें निम्नलिखित छद्म कोड में दर्शाएंगे।

return value = for array element in array 
    statement                        // Note: There can be break and continue in the statement
    statement                        // Note: The last statement is the return value
Return value = for [index variable, array element corresponding to index variable] in array
    statement                        // Note: There can be break and continue in the statement
    statement                        // Note: The last statement is the return value 

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

testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray            // Modify it to the form of [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.

लूप के लिए आवेदन

हम पाइन भाषा में दिए गए अंतर्निहित कार्यों का उपयोग कुछ लूप लॉजिक गणनाओं को पूरा करने के लिए कर सकते हैं, या तो सीधे लूप संरचना का उपयोग करके लिखा जा सकता है या अंतर्निहित कार्यों का उपयोग करके संसाधित किया जा सकता है। आइए दो उदाहरण लेते हैंः

  1. औसत मूल्य की गणना करें

एक लूप संरचना के साथ डिजाइन करते समयः

length = 5
var a = array.new(length)
array.push(a, close)

if array.size(a) >= length
	array.remove(a, 0)
	
sum = 0 	
for ele in a
    sum += ele 

avg = sum / length
plot(avg, title="avg", overlay=true)

उदाहरण में योग की गणना करने के लिए एक फोर लूप का उपयोग किया गया है और फिर औसत मान की गणना की गई है।

अंतर्निहित फ़ंक्शन का उपयोग करके सीधे चलती औसत की गणना करें:

plot(ta.sma(close, length), title="ta.sma", overlay=true)

अंतर्निहित फ़ंक्शन का प्रयोग करेंta.smaसीधे चलती औसत सूचक की गणना करने के लिए। जाहिर है, चलती औसत की गणना के लिए अंतर्निहित फ़ंक्शन का उपयोग करना सरल है। चार्ट पर तुलना करके, यह देखा जा सकता है कि गणना किए गए परिणाम बिल्कुल समान हैं।

  1. सारांश

हम अभी भी उपरोक्त उदाहरण का प्रयोग करते हैं।

एक लूप संरचना के साथ डिजाइन करते समयः

length = 5
var a = array.new(length)
array.push(a, close)

if array.size(a) >= length
	array.remove(a, 0)
	
sum = 0 	
for ele in a
    sum += ele 

avg = sum / length
plot(avg, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)

एक सरणी में सभी तत्वों के योग की गणना के लिए, हम इसे संसाधित करने के लिए एक लूप का उपयोग कर सकते हैं, या अंतर्निहित समारोह का उपयोगarray.sumगणना करने के लिए। अंतर्निहित फ़ंक्शन का उपयोग करके सीधे राशि की गणना करेंः

length = 5
var a = array.new(length)
array.push(a, close)

if array.size(a) >= length
	array.remove(a, 0)
	
plot(array.sum(a) / length, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)

हम देख सकते हैं कि गणना की गई डेटा ग्राफ का उपयोग कर चार्ट पर प्रदर्शित के रूप में बिल्कुल एक ही है।

तो क्यों लूप डिजाइन जब हम इन सभी में निर्मित कार्यों के साथ कर सकते हैं? लूप का उपयोग मुख्य रूप से इन 3 बिंदुओं के आवेदन पर आधारित हैः

  1. कुछ संचालन और सरणियों के लिए गणना के लिए।
  2. इतिहास की समीक्षा करने के लिए, उदाहरण के लिए, यह पता लगाने के लिए कि कितने पिछले उच्च बिंदु वर्तमान BAR के उच्च बिंदु से अधिक हैं। चूंकि वर्तमान BAR का उच्च बिंदु केवल उस BAR पर जाना जाता है जहां स्क्रिप्ट चल रही है, इसलिए समय में पिछले BAR को वापस करने और विश्लेषण करने के लिए एक लूप की आवश्यकता होती है।
  3. जब पाइन भाषा के अंतर्निहित कार्य पिछले बारों के लिए गणना को पूरा नहीं कर सकते हैं।

जबकि statemnet

..whileकथन लूप अनुभाग में कोड को तब तक निष्पादित करता है जब तक कि while संरचना में निर्णय की स्थिति गलत नहीं हो जाती।

return value = while judgment condition
    statement                    // Note: There can be break and continue in the statement
    statement                    // Note: The last statement is the return value

while के अन्य नियम for लूप के समान हैं। लूप बॉडी के स्थानीय कोड ब्लॉक की अंतिम पंक्ति रिटर्न वैल्यू है, जो कई मान वापस कर सकती है। जब loop condition true हो, तो लूप निष्पादित करें, और जब स्थिति false हो, तो लूप को रोकें। ब्रेक और जारी रखें कथन भी लूप बॉडी में उपयोग किए जा सकते हैं।

हम अभी भी प्रदर्शन के लिए चलती औसत की गणना के उदाहरण का उपयोग करेंगेः

length = 10

sma(data, length) => 
    i = 0 
    sum = 0 
    while i < 10 
        sum += data[i]
        i += 1
        sum / length

plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)

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

counter = 5
fact = 1

ret = while counter > 0
    fact := fact * counter
    counter := counter - 1
    fact

plot(ret, title="ret")  // ret = 5 * 4 * 3 * 2 * 1

सरणी

पाइन भाषा में सरणियों की परिभाषा अन्य प्रोग्रामिंग भाषाओं के समान है। पाइन s सरणियां एक आयामी सरणियां हैं। आमतौर पर इसका उपयोग डेटा की एक निरंतर श्रृंखला को संग्रहीत करने के लिए किया जाता है। सरणी में संग्रहीत एकल डेटा को सरणी का तत्व कहा जाता है, और इन तत्वों के प्रकार हो सकते हैंः पूर्णांक, फ्लोटिंग पॉइंट, स्ट्रिंग, रंग मान, बुलियन मान। एफएमजेड पर पाइन भाषा प्रकारों के बारे में बहुत सख्त नहीं है, और यह एक ही समय में सरणी में स्ट्रिंग और संख्याओं को भी संग्रहीत कर सकती है। चूंकि सरणी की अंतर्निहित संरचना भी एक श्रृंखला संरचना है, यदि ऐतिहासिक ऑपरेटर का उपयोग पिछले बार पर सरणी की स्थिति को संदर्भित करने के लिए किया जाता है। इसलिए ऐतिहासिक ऑपरेटर का उपयोग करने के बजाय[]सरणी में एक तत्व को संदर्भित करने के लिए, हम कार्यों का उपयोग करने की जरूरत हैarray.get()औरarray.set(). सरणी में तत्वों का सूचकांक क्रम यह है कि सरणी के पहले तत्व का सूचकांक 0 है और अगले तत्व का सूचकांक 1 से बढ़ाया जाता है.

हम इसे एक सरल कोड के साथ चित्रित करते हैंः

var a = array.from(0)
if bar_index == 0 
    runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1])
else if bar_index == 1 
    array.push(a, bar_index)
    runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1])
else if bar_index == 2
    array.push(a, bar_index)
    runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1], ", a on the last second BAR, i.e. the value of a[2]:", a[2])
else if bar_index == 3 
    array.push(a, bar_index)
    runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1], ", a on the last second BAR, i.e. the value of a[2]:", a[2], ", a on the last third BAR, i.e. the value of a[3]:", a[3])
else if bar_index == 4 
    // Obtain elements by index using array.get, modify elements by index using array.set
    runtime.log("Before array modification:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
    array.set(a, 1, 999)
    runtime.log("After array modification:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))

सरणी घोषित करें

प्रयोगarray<int> a, float[] bएक सरणी घोषित करने के लिए या सिर्फ एक चर है कि एक सरणी को सौंपा जा सकता है घोषित करने के लिए, उदाहरण के लिएः

array<int> a = array.new(3, bar_index)
float[] b = array.new(3, close)
c = array.from("hello", "fmz", "!")
runtime.log("a:", a)
runtime.log("b:", b)
runtime.log("c:", c)
runtime.error("stop")

सरणी चर को आरंभ करने के लिएarray.newऔरarray.fromवहाँ भी कई प्रकार से संबंधित कार्यों के समान हैंarray.newपाइन भाषा में:array.new_int(), array.new_bool(), array.new_color(), array.new_string()आदि।

var कीवर्ड array declaration mode के साथ भी काम करता है. var कीवर्ड के साथ घोषित arrays को केवल पहले BAR पर ही आरंभ किया जाता है. आइए एक उदाहरण के साथ देखें:

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 के मूल्य के साथ है।

सरणी में तत्वों को पढ़ना और लिखना

सरणी में निर्दिष्ट सूचकांक स्थिति में तत्व प्राप्त करने के लिए array.get का उपयोग करें, और सरणी में निर्दिष्ट सूचकांक स्थिति में तत्व को संशोधित करने के लिए array.set का उपयोग करें.

array.get का पहला पैरामीटर संसाधित करने के लिए सरणी है, और दूसरा पैरामीटर निर्दिष्ट सूचकांक है। array.set के लिए पहला पैरामीटर संसाधित करने के लिए सरणी है, दूसरा पैरामीटर निर्दिष्ट सूचकांक है, और तीसरा पैरामीटर लिखने के लिए तत्व है।

हम निम्नलिखित सरल उदाहरण का प्रयोग करते हैं:

lookbackInput = input.int(100)
FILL_COLOR = color.green

var fillColors = array.new(5)
if barstate.isfirst
    array.set(fillColors, 0, color.new(FILL_COLOR, 70))
    array.set(fillColors, 1, color.new(FILL_COLOR, 75))
    array.set(fillColors, 2, color.new(FILL_COLOR, 80))
    array.set(fillColors, 3, color.new(FILL_COLOR, 85))
    array.set(fillColors, 4, color.new(FILL_COLOR, 90))

lastHiBar = - ta.highestbars(high, lookbackInput)
fillNo = math.min(lastHiBar / (lookbackInput / 5), 4)

bgcolor(array.get(fillColors, int(fillNo)), overlay=true)
plot(lastHiBar, title="lastHiBar")
plot(fillNo, title="fillNo")

उदाहरण आधार रंग हरे रंग को आरंभ करता है, घोषणा करता है और रंगों को संग्रहीत करने के लिए एक सरणी को आरंभ करता है, और फिर रंगों के लिए विभिन्न पारदर्शिता मानों को असाइन करता हैcolor.newरंग स्तर की गणना वर्तमान BAR के अधिकतम मूल्य से 100 लुकबैक अवधि में उच्च की दूरी की गणना करके की जाती है। पिछले 100 लुकबैक चक्रों में HIGH के अधिकतम मूल्य के करीब दूरी, रैंक अधिक है और संबंधित रंग मूल्य गहरा (कम पारदर्शिता) है। कई समान रणनीतियाँ N लुकबैक अवधि के भीतर वर्तमान मूल्य स्तर का प्रतिनिधित्व करने के लिए इस विधि का उपयोग करती हैं।

सरणी तत्वों के माध्यम से पुनरावृत्ति

कैसे एक सरणी के माध्यम से पुनरावृत्ति करने के लिए, हम उपयोग कर सकते हैं के लिए / के लिए में / जबकि कथन है कि हम पहले सीखा है.

a = array.from(1, 2, 3, 4, 5, 6)

for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1)
    array.set(a, i, i)
    
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)

i = 0
while i < array.size(a)
    array.set(a, i, i)
    i += 1

runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)

for [i, ele] in a 
    array.set(a, i, i)

runtime.log(a)
runtime.error("stop")

इन तीन पारगमन विधियों के निष्पादन परिणाम समान हैं।

सरणियों को किसी स्क्रिप्ट के वैश्विक दायरे में, या किसी फ़ंक्शन या if शाखा के स्थानीय दायरे में घोषित किया जा सकता है।

ऐतिहासिक डेटा संदर्भ

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

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().

  1. सरणी के मिटाने के कार्य से संबंधित कार्य:

array.remove(), array.shift(), array.pop(), array.clear().

हम इन सरणी जोड़ने और हटाने ऑपरेशन कार्यों का परीक्षण करने के लिए निम्नलिखित उदाहरण का उपयोग करते हैं।

a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("array a:", a, ", ret:", ret)

ret := array.insert(a, 1, "Y")
runtime.log("array a:", a, ", ret:", ret)

ret := array.push(a, "D")
runtime.log("array a:", a, ", ret:", ret)

ret := array.remove(a, 2)
runtime.log("array a:", a, ", ret:", ret)

ret := array.shift(a)
runtime.log("array a:", a, ", ret:", ret)

ret := array.pop(a)
runtime.log("array a:", a, ", ret:", ret)

ret := array.clear(a)
runtime.log("array a:", a, ", ret:", ret)

runtime.error("stop")

जोड़ों, हटाने का अनुप्रयोगः कतारों के रूप में सरणी

हम arrays और arrays को जोड़ने और हटाने के कुछ functions का उपयोग करके एक queue data structure का निर्माण कर सकते हैं। tick prices के moving average की गणना करने के लिए queues का उपयोग किया जा सकता है। कोई पूछ सकता है, हमें एक queue structure का निर्माण क्यों करना चाहिए? क्या हमने पहले औसत की गणना करने के लिए arrays का उपयोग नहीं किया था?

एक कतार एक संरचना है जो अक्सर प्रोग्रामिंग के क्षेत्र में उपयोग की जाती है, एक कतार की विशेषताएं हैंः

जो तत्व पहले कतार में प्रवेश करता है, वह पहले कतार छोड़ देता है।

इस प्रकार, यह सुनिश्चित करता है कि कतार में डेटा नवीनतम डेटा है, और कि कतार की लंबाई अनिश्चित काल तक विस्तारित नहीं होगी।

निम्नलिखित उदाहरण में, हम प्रत्येक टिक की कीमत को रिकॉर्ड करने के लिए एक कतार संरचना का उपयोग करते हैं, टिक स्तर पर मोबाइल औसत मूल्य की गणना करते हैं, और फिर इसे 1 मिनट के-लाइन स्तर पर चलती औसत के साथ तुलना करते हैं।

strategy("test", overlay=true)

varip a = array.new_float(0)
var length = 10

if not barstate.ishistory
    array.push(a, close)

    if array.size(a) > length
        array.shift(a)

sum = 0.0
for [index, ele] in a 
    sum += ele

avgPrice = array.size(a) == length ? sum / length : na

plot(avgPrice, title="avgPrice")
plot(ta.sma(close, length), title="ta.sma")

ध्यान दें कि जब घोषणा सरणी एक, हम घोषणा मोड निर्दिष्ट और कुंजी शब्द का उपयोगvariantइस तरह, प्रत्येक मूल्य परिवर्तन array a में दर्ज किया जाएगा.

सरणी गणना और ऑपरेशन फ़ंक्शन आम तौर पर उपयोग किए जाते हैं

सहसंबंध कार्यों की गणना करें:

array.avg()एक सरणी में सभी तत्वों के औसत मूल्य की गणना करता है,array.min()एक सरणी में सबसे छोटे तत्व की गणना करता है,array.max()एक सरणी में सबसे छोटे तत्व की गणना करता है,array.stdev()एक सरणी में सभी तत्वों के मानक विचलन की गणना करता है,array.sum()एक सरणी में सभी तत्वों के मानक विचलन की गणना करता है.

परिचालन से संबंधित कार्य:array.concat()दो सरणियों को विलय करने या संबद्ध करने के लिए।array.copy()सरणी की प्रतिलिपि बनाने के लिए।array.joinएक सरणी के सभी तत्वों को एक स्ट्रिंग में जोड़ता है.array.sort()ऊपर या नीचे क्रम में क्रमबद्ध करने के लिए।array.reverse()सरणी को उलटने के लिए।array.slice()सरणी को स्लाइस करने के लिए।array.includes()तत्व का न्याय करने के लिए।array.indexof()पैरामीटर के रूप में पारित मूल्य की पहली घटना के सूचकांक पर लौटने के लिए. यदि मान नहीं पाया जाता है, -1 लौटाया जाएगा.array.lastindexof()मान की अंतिम घटना का पता लगाने के लिए.

सरणी गणना से संबंधित कार्यों के परीक्षण उदाहरणः

a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)

runtime.log("Arithmetic average of the array a:", array.avg(a))
runtime.log("The minimum element in the array a:", array.min(a))
runtime.log("The maximum element in the array a:", array.max(a))
runtime.log("Standard deviation in array a:", array.stdev(a))
runtime.log("Sum of all elements of the array a:", array.sum(a))
runtime.error("stop")

ये आमतौर पर उपयोग किए जाने वाले सरणी गणना कार्य हैं।

संचालन से संबंधित कार्यों के उदाहरण:

a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)

runtime.log("array a: ", a, ", array b: ", b)
runtime.log("array a, array b is concatenated with:", array.concat(a, b))
c = array.copy(b)

runtime.log("Copy an array b and assign it to the variable c, variable c:", c)

runtime.log("use array.join to process the array c, add the symbol + to the middle of each element, concatenating all elements results in a string:", array.join(c, "+"))
runtime.log("Sort the array b, in order from smallest to largest, using the parameter order.ascending:", array.sort(b, order.ascending))     // array.sort function modifies the original array
runtime.log("Sort the array b, in order from largest to smallest, using the parameter order.descending:", array.sort(b, order.descending))   // array.sort function modifies the original array

runtime.log("array a:", a, ", array b:", b)
array.reverse(a)   // This function modifies the original array
runtime.log("reverse the order of all elements in the array a, after reversing, the array a is:", a)    

runtime.log("Intercept array a, index 0~index 3, and follow the rule of left-closed and right-open interval:", array.slice(a, 0, 3))
runtime.log("Search for element 11 in array b:", array.includes(b, 11))
runtime.log("Search for element 100 in array a:", array.includes(a, 100))
runtime.log("Connect array a and array b, and search the index position of the first occurrence of element 2:", array.indexof(array.concat(a, b), 2), " , observe array.concat(a, b):", array.concat(a, b))
runtime.log("Connect array a and array b, and search the index position of the last occurrence of element 6:", array.lastindexof(array.concat(a, b), 6), " , observe array.concat(a, b):", array.concat(a, b))

runtime.error("stop")

कार्य

कस्टम फ़ंक्शन

पाइन भाषा को कस्टम फ़ंक्शन के साथ डिज़ाइन किया जा सकता है। सामान्य तौर पर पाइन भाषा में कस्टम फ़ंक्शन के लिए निम्नलिखित नियम लागू होते हैंः

  1. सभी फ़ंक्शन स्क्रिप्ट के वैश्विक दायरे में परिभाषित होते हैं. एक फ़ंक्शन को दूसरे फ़ंक्शन के भीतर घोषित नहीं किया जा सकता है.
  2. कार्यों को अपने स्वयं के कोड में खुद को कॉल करने की अनुमति नहीं है (रिकर्शन) ।
  3. सिद्धांत रूप में, सभी PINE भाषा के अंतर्निहित ड्राइंग कार्यों (barcolor(), fill(), hline(), plot(), plotbar(), plotcandle()) कस्टम कार्यों में नहीं बुलाया जा सकता है।
  4. फ़ंक्शन को सिंगल लाइन या मल्टीपल लाइन के रूप में लिखा जा सकता है। अंतिम कथन का रिटर्न मान वर्तमान फ़ंक्शन का रिटर्न मान है, जिसे टपल रूप में लौटाया जा सकता है।

हम भी हमारे पिछले ट्यूटोरियल में कई बार कस्टम कार्यों का इस्तेमाल किया है, जैसे कि एक पंक्ति के रूप में डिजाइन किया गयाः

barIsUp() => close > open

क्या वर्तमान BAR एक सकारात्मक रेखा है जब फ़ंक्शन वापस करता है।

कई पंक्तियों के लिए डिज़ाइन किए गए कस्टम फ़ंक्शनः

sma(data, length) => 
    i = 0 
    sum = 0 
    while i < 10 
        sum += data[i]
        i += 1
        sum / length

plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)

हम एक कस्टम फ़ंक्शन का उपयोग एसएमए औसत गणना के एक फ़ंक्शन का एहसास करने के लिए करते हैं।

इसके अतिरिक्त, कस्टम फ़ंक्शन के दो उदाहरण हैं जिन्हें हम वापस कर सकते हैंः

twoEMA(data, fastPeriod, slowPeriod) =>
    fast = ta.ema(data, fastPeriod)
    slow = ta.ema(data, slowPeriod)
    [fast, slow]

[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)

एक फ़ंक्शन फास्ट लाइन, स्लो लाइन और दो ईएमए औसत की गणना कर सकता है।

अंतर्निहित कार्य

अंतर्निहित कार्य आसानी से पाया जा सकता हैFMZ PINE स्क्रिप्ट दस्तावेज़.

पाइन भाषा में अंतर्निहित कार्यों का वर्गीकरणः

  1. स्ट्रिंग प्रोसेसिंग फ़ंक्शनstr. series.
  2. रंग मान प्रसंस्करण कार्यcolor. series.
  3. पैरामीटर इनपुट फ़ंक्शनinput. series.
  4. सूचक गणना कार्यta. series.
  5. ड्राइंग फ़ंक्शनplot. series.
  6. सरणी हैंडलिंग फ़ंक्शनarray. series.
  7. व्यापार से संबंधित कार्यstrategy. series.
  8. गणितीय क्रियाओं से संबंधित कार्यmath. series.
  9. अन्य कार्य (समय प्रबंधन, गैर-ग्राफ श्रृंखला ड्राइंग कार्य,request.श्रृंखला कार्य, प्रकार हैंडलिंग कार्य, आदि)

व्यापारिक कार्य

..strategy.कार्यों की श्रृंखला है कि हम अक्सर रणनीतियों के डिजाइन में उपयोग कर रहे हैं कार्यों हैं, और इन कार्यों व्यापार संचालन के निष्पादन के साथ निकटता से संबंधित हैं जब रणनीति विशेष रूप से चल रहा है.


  1. strategy.entry

strategy.entryफ़ंक्शन एक अधिक महत्वपूर्ण फ़ंक्शन है जब हम एक आदेश रखने के लिए एक रणनीति लिखते हैं, फ़ंक्शन के लिए कई महत्वपूर्ण पैरामीटर हैंःid, direction, qty, whenआदि।

पैरामीटर:

  • id: यह संदर्भ के लिए एक ट्रेडिंग स्थिति को एक नाम देने के रूप में समझा जा सकता है। इस आईडी को रद्द करने, आदेशों को संशोधित करने और बंद पदों के लिए संदर्भित किया जा सकता है।
  • direction: यदि आदेश की दिशा लंबी है (खरीदें), तो अंतर्निहित चर में पास करेंstrategy.long, और यदि आप शॉर्ट (बेचना) जाना चाहते हैं, चर में पारितstrategy.short.
  • qty: रखे जाने वाले आदेशों की राशि निर्दिष्ट करें, यदि यह पैरामीटर पारित नहीं किया जाता है, तो आदेशों की डिफ़ॉल्ट राशि का उपयोग किया जाएगा।
  • when: निष्पादन शर्त, आप इस पैरामीटर को निर्दिष्ट कर सकते हैं यह नियंत्रित करने के लिए कि यह वर्तमान आदेश ऑपरेशन ट्रिगर किया जाता है या नहीं।
  • limit: आदेश सीमा मूल्य निर्दिष्ट करें।
  • stopस्टॉप लॉस की कीमत।

कार्यवाही के विशिष्ट विवरणstrategy.entryसमारोह पैरामीटर सेटिंग्स द्वारा नियंत्रित कर रहे हैं जबstrategyफ़ंक्शन कहा जाता है, और यह भी द्वारा नियंत्रित किया जा सकता है [पाइन भाषा व्यापार वर्ग पुस्तकालय टेम्पलेट तर्क](https://www.fmz.com/bbs-topic/9293#template-arguments-of-pine-language-trade-class-library) सेटिंग नियंत्रण, Pine language trade-class library template arguments लेनदेन के अधिक विवरणों को नियंत्रित करते हैं, आप विवरण के लिए लिंक किए गए प्रलेखन की जांच कर सकते हैं.

हम पर ध्यान केंद्रितpyramiding, default_qty_valueमापदंडोंstrategyहम परीक्षण के लिए निम्नलिखित कोड का उपयोग करते हैंः

/*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 के रूप में, हम एक ही दिशा में ट्रेडों की अधिकतम संख्या सेट 3 करने के लिए। तो चार में से एकstrategy.entryउदाहरण में आदेश संचालन निष्पादित नहीं किया जाता है। चूंकि हमने यह भी निर्दिष्ट किया हैdefault_qty_valueपैरामीटर 0.1, यह होना चाहिएstrategy.entryआईडी के साथ ऑपरेशनlong1डिफ़ॉल्ट ऑर्डर आकार 0.1 है।strategy.entryफ़ंक्शन कॉल जब हम निर्दिष्टdirectionजैसा किstrategy.long, तो backtest परीक्षण आदेश सभी खरीद आदेश हैं.

ध्यान दें कि आदेश ऑपरेशनstrategy.entry("long3", ...कोड में एक ही आईडी के लिए दो बार कहा जाता हैःlong3, पहलाstrategy.entryआदेश ऑपरेशन नहीं भरा गया था, और दूसरे कॉल के लिएstrategy.entryइस आईडी के लिए आदेश को संशोधित करना था (बैकटेस्ट परीक्षण में दिखाए गए डेटा से यह भी पता चलता है कि इस सीमा आदेश के लिए आदेश मात्रा को 0.3 में संशोधित किया गया था) । एक और मामला, उदाहरण के लिए, यदि आईडी long3 के साथ पहला आदेश भरा गया है, तोstrategy.entryआईडी long3 के अनुसार ऑर्डर करने के लिए फ़ंक्शन, तो ऑर्डर की स्थिति आईडी long3 पर जमा की जाएगी।


  1. strategy.close

..strategy.closeसमारोह का उपयोग निर्दिष्ट पहचान आईडी के साथ प्रवेश स्थिति को बंद करने के लिए किया जाता है। मुख्य पैरामीटर हैंःid, when, qty, qty_percent.

पैरामीटर:

  • id: प्रविष्टि आईडी जो बंद करने की जरूरत है आईडी है कि हम निर्दिष्ट जब हम एक प्रविष्टि आदेश समारोह का उपयोग कर एक स्थिति खोलने, जैसे किstrategy.entry.
  • when: निष्पादन की शर्तें।
  • qty: बंद पदों की संख्या
  • qty_percent: बंद पदों का प्रतिशत।

आइए एक उदाहरण के माध्यम से इस फंक्शन के उपयोग के विवरण से परिचित हों: द/*backtest ... */कोड में कॉन्फ़िगरेशन जानकारी हैFMZ.COMअंतरराष्ट्रीय वेबसाइट बैकटेस्ट, आप इसे हटा सकते हैं और बाजार, किस्म, समय सीमा और अन्य जानकारी आप परीक्षण करने की जरूरत सेट.

/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

strategy("close Demo", pyramiding=3)

var enableStop = false 
if enableStop
    runtime.error("stop")

strategy.entry("long1", strategy.long, 0.2)
if strategy.opentrades >= 3 
    strategy.close("long1")                   // Multiple entry orders, no qty parameters specified, close all
    // strategy.close()                          // Without specifying the id parameter, the current position will be closed
    // strategy.close("long2")                   // If a non-existent id is specified then nothing is done
    // strategy.close("long1", qty=0.15)         // Specify qty parameters to close a position
    // strategy.close("long1", qty_percent=50)   // qty_percent is set to 50 to close 50% of the positions marked by long1
    // strategy.close("long1", qty_percent=80, when=close<open)  // Specify the parameter when, change it to close>open and it won't trigger
    enableStop := true

परीक्षण रणनीति में प्रविष्टि आईडी long1 के साथ लगातार तीन लंबी प्रविष्टियां दिखाई जाती हैं और फिर विभिन्न पैरामीटर का उपयोग किया जाता है।strategy.closeएक स्थिति को बंद करते समय बैकटेस्ट के विभिन्न परिणामों को सेट करने के लिए।strategy.closeइस फ़ंक्शन में स्थिति को बंद करने के लिए ऑर्डर की कीमत निर्दिष्ट करने के लिए कोई पैरामीटर नहीं है, इस फ़ंक्शन का उपयोग मुख्य रूप से वर्तमान बाजार मूल्य पर स्थिति को तुरंत बंद करने के लिए किया जाता है।


  1. strategy.close_all

कार्यstrategy.close_allसभी वर्तमान पदों को बंद करने के लिए प्रयोग किया जाता है, क्योंकि पाइन भाषा स्क्रिप्ट पदों केवल एक दिशा हो सकता है, कि अगर वहाँ एक संकेत वर्तमान स्थिति के विपरीत दिशा में ट्रिगर बंद कर दिया जाएगा वर्तमान स्थिति और फिर संकेत ट्रिगर के अनुसार इसे खोलने के लिए है। तोstrategy.close_allयह कहा जाता है जब वर्तमान दिशा में सभी पदों को बंद कर देगा.strategy.close_allकार्य है:when.

पैरामीटर:

  • when: निष्पादन की शर्तें।

आइए एक उदाहरण का उपयोग करेंः

/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

strategy("closeAll Demo")

var enableStop = false 
if enableStop
    runtime.error("stop")

strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open)
strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open)

if strategy.position_size < 0 
    strategy.close_all()
    enableStop := true 

परीक्षण कोड 0 की स्थिति संख्या से शुरू होता है (यानीstrategy.position_size==0सच है), तो जब जब पैरामीटर द्वारा निर्धारित शर्तों को पूरा कर रहे हैं, केवल जब पैरामीटरstrategy.entryआईडी long के साथ प्रवेश फ़ंक्शन निष्पादित किया जाता है. एक लंबी स्थिति रखने के बाद,strategy.position_size0 से अधिक है तो आईडी short के साथ प्रवेश फ़ंक्शन निष्पादित किया जा सकता है, चूंकि वर्तमान लंबी स्थिति आयोजित की जाती है, इस समय इस शॉर्टिंग रिवर्स सिग्नल के परिणामस्वरूप लंबी स्थिति बंद हो जाएगी और फिर विपरीत दिशा में छोटी स्थिति खोलेगी। फिर हम यदि स्थिति में लिखते हैं कि जबstrategy.position_size < 0, यानी एक छोटी स्थिति रखने पर, वर्तमान होल्डिंग दिशा में सभी पदों को बंद कर दिया जाएगा।enableStop := true. रणनीति निष्पादन को रोकता है ताकि लॉग का निरीक्षण किया जा सके.

यह पाया जा सकता है कि समारोहstrategy.close_allआदेश के समापन की कीमत को निर्दिष्ट करने के लिए कोई पैरामीटर नहीं है, इस फ़ंक्शन का उपयोग मुख्य रूप से वर्तमान बाजार मूल्य पर स्थिति को तुरंत बंद करने के लिए किया जाता है।


  1. strategy.exit

..strategy.exitइस फ़ंक्शन के विपरीत, प्रवेश स्थिति को बंद करने के लिए उपयोग किया जाता हैstrategy.closeऔरstrategy.close_allकार्य वर्तमान बाजार मूल्य पर एक स्थिति को तुरंत बंद करते हैं।strategy.exitसमारोह पैरामीटर सेटिंग्स के अनुसार स्थिति को बंद कर देगा।

पैरामीटर:

  • id: वर्तमान क्लोजआउट शर्त ऑर्डर का ऑर्डर आईडी।
  • from_entry: बंद होने वाली स्थिति की प्रविष्टि आईडी निर्दिष्ट करने के लिए प्रयोग किया जाता है।
  • qty: बंद पदों की संख्या
  • qty_percent: बंद पदों का प्रतिशत, सीमाः 0 ~ 100.
  • profit: मुनाफा लक्ष्य अंक में व्यक्त किया गया।
  • loss: स्टॉप लॉस लक्ष्य, अंकों में व्यक्त किया गया।
  • limit: लाभ लक्ष्य, मूल्य द्वारा निर्दिष्ट।
  • stop: स्टॉप लॉस लक्ष्य, मूल्य द्वारा निर्दिष्ट।
  • when: निष्पादन की शर्तें।

पैरामीटर उपयोग को समझने के लिए एक परीक्षण रणनीति का उपयोग करें।

/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/

strategy("strategy.exit Demo", pyramiding=3)

varip isExit = false 

findOrderIdx(idx) =>
    ret = -1 
    if strategy.opentrades == 0 
        ret
    else 
        for i = 0 to strategy.opentrades - 1 
            if strategy.opentrades.entry_id(i) == idx
                ret := i 
                break
        ret

strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0)
strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0)
strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0)

if not isExit and strategy.opentrades > 0
    // strategy.exit("exitAll")          // If only one id parameter is specified, the exit order is invalid, and the parameters profit, limit, loss, stop and other exit conditions also need to be set at least one, otherwise it is also invalid
    strategy.exit("exit1", "long1", profit=50)                    // Since the long1 entry order is not filled, the exit order with ID exit1 is also on hold until the corresponding entry order is filled before exit1 is placed
    strategy.exit("exit2", "long2", qty=0.1, profit=100)          // Specify the parameter qty to close 0.1 positions in the position with ID long2
    strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000)   // Specify the parameter qty_percent to close 50% of the positions in the position with ID long3
    isExit := true 

if bar_index == 0 
    runtime.log("The price per point:", syminfo.mintick)    // The price per point is related to the "Pricing Currency Precision" parameter setting on the Pine language template parameters

हम बैकटेस्ट के लिए वास्तविक समय मूल्य मॉडल का उपयोग करते हैं, परीक्षण रणनीति 3 प्रविष्टि संचालन (strategy.entryकार्य) औरlong1जानबूझकर सेट किया जाता हैlimitएक लंबित आदेश मूल्य के साथ पैरामीटर 1, तो यह भरा नहीं जा सकता है. फिर सशर्त बाहर निकलने समारोह का परीक्षणstrategy.exitहमने point by profit और price by profit का उपयोग किया, एक निश्चित संख्या में पदों को बंद किया, और प्रतिशत में बंद किए गए पदों को। उदाहरण की लंबाई को देखते हुए, केवल take profit प्रदर्शित किया गया है। स्टॉप-लॉस ऑपरेशन भी समान है।strategy.exitकार्य में अधिक जटिल ट्रैलिंग स्टॉप पैरामीटर भी हैं:trail_price, trail_points, trail_offsetभी इस उदाहरण में परीक्षण किया जा सकता है उनके उपयोग को सीखने के लिए.


  1. strategy.cancel

..strategy.cancelइन कार्यों का उपयोग सभी पूर्व-लंबित आदेशों को रद्द/रोकने के लिए किया जाता है। ये कार्यःstrategy.order, strategy.entry , strategy.exitप्रवेश आईडी उत्पन्न कर सकता है। इस कार्य के मुख्य पैरामीटर हैंःid, when.

पैरामीटर:

  • id: प्रवेश आईडी रद्द की जानी है।
  • when: निष्पादन की शर्तें।

यह कार्य समझने में आसान है, और इसका उपयोग उन प्रविष्टि आदेशों को रद्द करने के लिए किया जाता है जो भरे नहीं गए हैं।

/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

strategy("strategy.cancel Demo", pyramiding=3)

var isStop = false 
if isStop 
    runtime.error("stop")

strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0

अधिक