क्रॉसिंग संकेत बताता है कि घटना कहाँ हुई। शुरुआत से ऐसी कितनी घटनाएँ हुईं यह चाहिए, तो प्रोग्राम को काउंटर की वैल्यू याद रखनी होगी।

सामान्य वेरिएबल पर्याप्त क्यों नहीं?

ये दोनों हर कैंडल पर गिनती फिर शुरू करते हैं:

count = 0
count += 1

पहली लाइन हर main() पर शून्य देती है। दूसरी एक जोड़ती है, इसलिए नतीजा हर कैंडल पर 1 है।

+= छोटा असाइनमेंट है: count += 1 का अर्थ count = count + 1 जैसा है। पुरानी वैल्यू पढ़ें, एक जोड़ें और वापस रखें।

घटनाएँ जोड़ने के लिए अलग शुरुआत चाहिए। केवल काउंटर पहली बार बने तब शून्य करना है।

Persistent वेरिएबल

count: Persistent[int] = 0

Persistent कहता है कि वैल्यू कैंडल के बीच बचाएँ। शुरुआती शून्य केवल एक बार सेट करता है। अगली कैंडल पिछली बंद कैंडल की बची वैल्यू से जारी रहती है।

int पूर्णांक काउंटर का टाइप है। Persistent को pynecore से वैसे ही इंपोर्ट करते हैं जैसे पहले Series को।

इससे डिस्क पर डेटा सेव नहीं होता। नई रन डेटा की शुरुआत से शून्य काउंटर के साथ चलती है। यहाँ प्रोग्राम के भीतर कैंडल के बीच बचाना है।

ऊपर की क्रॉसिंग गिनें

event_counter.py बनाएँ:

"""
@pyne edge
"""
from pynecore import Persistent
from pynecore.lib import close, color, plot, script, ta


@script.indicator("Crossing Counter", overlay=False)
def main():
    fast_average = ta.sma(close, 5)
    slow_average = ta.sma(close, 20)
    crosses_up = ta.crossover(fast_average, slow_average)
    count: Persistent[int] = 0
    if crosses_up:
        count += 1
    plot(count, "Crossing count", color=color.blue, linewidth=2)

डेमो पर चलाएँ। अलग पैनल का काउंटर शून्य से शुरू है। ऊपर की क्रॉसिंग पर एक बढ़ता है और बीच की कैंडल पर समान रहता है।

event_counter.py के साथ PyneIDE में कुल क्रॉसिंग की गिनती की लाइन है।
हर ऊपर की क्रॉसिंग पर काउंटर एक बढ़ता है, अन्य कैंडल पर वैल्यू बचती है।

आखिरी वैल्यू जैसे 12 हो, तो पूरे प्रोसेस डेटा में बारह ऊपर की क्रॉसिंग हैं। स्क्रीन पर छोटी अवधि में कम संकेत हो सकते हैं। ज़ूम करने से काउंटर फिर शुरू नहीं होता।

स्टेट और हिस्ट्री

दो चिह्न अलग काम करते हैं:

चिह्नरनटाइम से क्या चाहते हैं?
Series[float]हर कैंडल की पिछली वैल्यू दोबारा मिल सके
Persistent[int]अगली कैंडल बची हुई वैल्यू से शुरू हो

Series का असाइनमेंट हर कैंडल पर होता है और वैल्यू की हिस्ट्री बनती है। Persistent की शुरुआती असाइनमेंट एक बार होती है; फिर कोड के बदलाव स्टेट आगे ले जाते हैं।

काउंटर की पिछली वैल्यू भी सीधे चाहिए तो वर्तमान काउंटर को अलग Series में रखें। बचाना और पुरानी वैल्यू इंडेक्स करना अलग बातें हैं।

पिछले मान और सुरक्षित स्टेटSeries के पिछले मान इंडेक्स से पढ़े जा सकते हैं। Persistent काउंटर का मान अगली कैंडल तक रखता है; काउंटर तभी बढ़ता है जब crosses_up का मान True हो। मान और संकेत केवल उदाहरण के लिए हैं। price: 102; price[1]: 99; price[2]: 101; price[3]: 100. crosses_up: False → True → False → True. count: 0 → 1 → 1 → 2.price: Series[float] = closeचौथी कैंडल के बाद के पिछले मानकैंडल1100price[3]2101price[2]399price[1]4102pricecount: Persistent[int] = 0शुरुआती मान: केवल एक बारकैंडलcrosses_upcount1False02True13False14True2
पिछले मान और सुरक्षित स्टेटSeries के पिछले मान इंडेक्स से पढ़े जा सकते हैं। Persistent काउंटर का मान अगली कैंडल तक रखता है; काउंटर तभी बढ़ता है जब crosses_up का मान True हो। मान और संकेत केवल उदाहरण के लिए हैं।

बचने वाला वेरिएबल कहाँ रखें?

काउंटर शर्त से पहले ऐसी जगह घोषित करते हैं जो हर कैंडल पर आती है। शर्त के बिना भी वैल्यू है और plot हर कैंडल पर दिखा सकता है।

main() से ऊपर सामान्य बदलने वाला ग्लोबल काउंटर न बनाएँ। कैंडल के बीच स्टेट उसके इस्तेमाल की जगह पर चिह्न से बताएँ।

यह ऐतिहासिक रन एक कैंडल पर एक बार गणना करती है। एक कैंडल को कई बार जाँचने वाले मोड में Persistent पिछली बंद कैंडल के स्टेट से फिर शुरू होता है। इसलिए यह सभी तकनीकी निष्पादन की संख्या नहीं रखता। किताब का काउंटर बंद कैंडल की घटनाओं के लिए है।

शर्त वैल्यू रीसेट भी कर सकती है

लगातार बढ़ती कैंडल गिनें तो गिरती या समान ओपन-क्लोज़ पर शून्य कर सकते हैं:

if close > open:
    streak += 1
else:
    streak = 0

पहले streak को Persistent[int] बनाएँ। यहाँ शून्य करना जानबूझकर शर्त वाला काम है। हर कैंडल की शुरुआत में अपने आप नहीं होता।

स्वयं करके देखें

दूसरा बचने वाला काउंटर जोड़ें। नीचे की क्रॉसिंग गिने और नारंगी लाइन बने। दोनों गणनाएँ हर कैंडल पर हों।

अभ्यास का हल

ऊपर की क्रॉसिंग के साथ:

crosses_down = ta.crossunder(fast_average, slow_average)
down_count: Persistent[int] = 0
if crosses_down:
    down_count += 1
plot(down_count, "Downward count", color=color.orange, linewidth=2)

पुराना count और उसकी ड्रॉइंग रखें। दोनों स्वतंत्र हैं। नई रन दोनों को शून्य से बनाती है।

एक संकेत पर जाँचें

क्रॉसिंग वाले अध्याय के संकेत और काउंटर का बदलाव उसी डेटा पर मिलाएँ। ऊपर की क्रॉस वाली कैंडल पर ठीक एक बढ़ना चाहिए। अगली पर तभी बढ़े जब नई ऊपर की क्रॉसिंग हो।