अंतिम प्रोजेक्ट: जाँची जा सकने वाली रणनीति
अपनी बदलने योग्य रणनीति बनाएँ और संकेत, ट्रेड तथा नतीजे जाँचें।
अंतिम प्रोजेक्ट में सीखी चीज़ें एक फ़ाइल में आएँगी: मूविंग एवरेज, इनपुट, शर्त, अपना फ़ंक्शन, ऑर्डर और प्रदर्शन। लक्ष्य है कि हर निर्णय का आधार डेटा और लिखे नियम में खोज सकें।
कोड के बिना प्रोग्राम बताएँ
रणनीति दो EMA की क्रॉसिंग देखती है। तीसरी लंबी SMA से जाँचती है कि क्लोज़ औसत से ऊपर है।
लॉन्ग प्रवेश के लिए तेज़ EMA धीमी के नीचे से ऊपर जाए और क्लोज़ ट्रेंड SMA से ऊपर हो। लंबाई का क्रम तेज़ < धीमी < ट्रेंड हो। न हो तो प्रवेश ऑर्डर न दे।
नीचे की EMA क्रॉसिंग लॉन्ग की मार्केट एग्ज़िट करती है। प्रवेश के साथ टिक स्टॉप और लक्ष्य हैं। सिम्युलेशन निश्चित एक यूनिट, 0.1 प्रतिशत कमीशन और दो टिक स्लिपेज लेता है।
ये काम के नियम हैं। इनसे किसी बाज़ार पर लाभ का दावा नहीं करते। जाँच के लिए किताब का निश्चित डेमो डेटा है।
पूरा प्रोग्राम
final_strategy.py बनाएँ:
"""
@pyne edge
"""
from pynecore.lib import close, color, input, location, plot, plotshape, script, shape, strategy, ta
def lengths_are_ordered(fast: int, slow: int, trend: int) -> bool:
return fast < slow and slow < trend
@script.strategy(
"Filtered Crossing Strategy",
overlay=True,
initial_capital=10000,
default_qty_type=strategy.fixed,
default_qty_value=1,
pyramiding=1,
commission_type=strategy.commission.percent,
commission_value=0.1,
slippage=2,
)
def main(
fast_length: int = input.int(9, title="Fast EMA length", minval=1, maxval=200),
slow_length: int = input.int(21, title="Slow EMA length", minval=1, maxval=200),
trend_length: int = input.int(50, title="Trend SMA length", minval=1, maxval=200),
use_trend_filter: bool = input.bool(True, title="Use trend filter"),
stop_ticks: int = input.int(100, title="Stop distance (ticks)", minval=1),
target_ticks: int = input.int(200, title="Target distance (ticks)", minval=1),
):
fast_average = ta.ema(close, fast_length)
slow_average = ta.ema(close, slow_length)
trend_average = ta.sma(close, trend_length)
crosses_up = ta.crossover(fast_average, slow_average)
crosses_down = ta.crossunder(fast_average, slow_average)
valid_lengths = lengths_are_ordered(fast_length, slow_length, trend_length)
trend_passes = not use_trend_filter or close > trend_average
entry_signal = valid_lengths and crosses_up and trend_passes
if entry_signal:
strategy.entry("Long", strategy.long)
if crosses_down:
strategy.close("Long")
strategy.exit("Bracket", "Long", loss=stop_ticks, profit=target_ticks)
plot(fast_average, "Fast EMA", color=color.blue, linewidth=2)
plot(slow_average, "Slow EMA", color=color.orange, linewidth=2)
plot(trend_average, "Trend SMA", color=color.gray, linewidth=2)
plotshape(entry_signal, "Entry signal", style=shape.triangleup,
location=location.belowbar, color=color.green)सेव करके डेमो पर चलाएँ। तीन औसत और प्रवेश शर्त के हरे त्रिकोण आएँगे। असली भरे प्रवेश-निकास रणनीति के ट्रेड चिह्न बताते हैं।

हर कैंडल पर क्या निकलता है?
तीनों औसत और दोनों क्रॉस शर्तों से पहले हैं। फ़िल्टर प्रवेश रोके तब भी गणना होती है। इससे स्टेट पूरी कैंडल श्रृंखला पर जाता है।
lengths_are_ordered तीन नंबर जाँचकर लॉजिकल वैल्यू देता है। अपना कैंडल स्टेट नहीं है। valid_lengths वर्तमान नतीजा आगे के एक्सप्रेशन के लिए रखता है।
फ़िल्टर बंद हो या क्लोज़ SMA से ऊपर हो तो trend_passes सत्य है। input.bool बदलने वाला लॉजिकल इनपुट है। बंद फ़िल्टर पर not use_trend_filter सत्य है, इसलिए दूसरा हिस्सा नहीं चाहिए।
फ़िल्टर बंद होने पर भी औसत निकलता और दिखता है। स्विच प्रवेश जाँच बदलता है, लाइन का प्रदर्शन नहीं।
लंबाई का गलत संबंध
अलग इनपुट सीमा केवल 1 से 200 तय करती हैं। तेज़ 30 और धीमी 10 दे सकते हैं, जो माँगे क्रम के विरुद्ध है।
फ़ंक्शन इसलिए संबंध अलग जाँचता है। गलत क्रम पर लाइन बनती है, लेकिन entry_signal सत्य नहीं हो सकता। प्रोग्राम गलत संबंध पर प्रवेश नहीं देने लगता।
डिबगर में valid_lengths से सीधे देखें। बची इनपुट गलत हों तो पूरी रन में असत्य रहेगा।
हर संकेत नया ट्रेड नहीं बनता
हरा त्रिकोण प्रवेश शर्त है। रणनीति ऑर्डर सिम्युलेटर को देती है। भरने के लिए अगली कैंडल, पर्याप्त पूँजी या अनुमत मात्रा भी चाहिए हो सकती है।
pyramiding=1 के कारण पहले से लॉन्ग हो तो नया लॉन्ग जरूरी नहीं स्वीकार हो। इसलिए संकेत और ट्रेड की संख्या समान न मानें।
शुरुआत में पचास वाली ट्रेंड SMA गायब है। फ़िल्टर चालू हो तो कीमत को उसके ऊपर सत्य नहीं कह सकते, इसलिए प्रवेश की शर्त पूरी नहीं।
सही काम की जाँच करें
पहले डिफ़ॉल्ट लें और Properties में मात्रा, खर्च और भरने का मोड देखें। पहले बचा बदलाव सोर्स को बदल सकता है।
हरा संकेत चुनें। डिबगर या ग्राफ़ से वर्तमान और पिछली कैंडल की EMA देखें। क्रॉसिंग, SMA फ़िल्टर और लंबाई संबंध जाँचें। तीनों सत्य हों।
फिर Trades में उससे जुड़ा प्रवेश खोजें। किस कैंडल और कीमत पर भरा देखें। निकास में क्रॉस, स्टॉप या लक्ष्य में से कारण पहचानें।
अनुमान वाले मामले आज़माएँ
जाँच के लिए ऐसा बदलाव लें जिसका नतीजा पहले बता सकें:
| बदलाव | क्या जाँचें? |
|---|---|
| तेज़ और धीमी समान | लंबाई जाँच से नया प्रवेश संकेत नहीं |
| ट्रेंड फ़िल्टर बंद | EMA क्रॉस को SMA से ऊपर कीमत नहीं चाहिए |
| स्टॉप और लक्ष्य बड़े | बदले स्तर से निकास कैंडल बदल सकती है |
| मात्रा बदले | कीमत संकेत वही, पैसे का आकार अलग हो सकता है |
एक रन में एक बदलाव करें। पहले उम्मीद, फिर असली नतीजा लिखें। न मिले तो डिबगर में पहला अलग निर्णय खोजें।
नतीजे मिलाना
फ़िल्टर चालू-बंद में डेटा, मात्रा, खर्च और लंबाई वही रखें। Performance कर्व और Trades साथ देखें। कम ट्रेड या अंतिम खुली पोज़िशन सारांश बदलती है।
असली ऐतिहासिक डेटा लें तो नतीजे देखने से पहले सेटिंग की अवधि और अलग जाँच अवधि तय करें। जाँच देखने के बाद पैरामीटर बदलें तो वह अवधि भी सेटिंग का हिस्सा बनती है।
शुरुआत में पर्याप्त वार्म-अप कैंडल चाहिए। अलग काटी अवधि चलाएँ तो औसत और पोज़िशन स्टेट फिर बनता है। इसलिए शुरुआत उसी अवधि के लंबे डेटा के बीच वाले नतीजे से अलग हो सकती है।
स्वयं करके देखें
Use crossings exit स्विच जोड़ें। चालू हो तो नीचे का क्रॉस बंद करे; बंद हो तो केवल स्टॉप-लक्ष्य। दोनों में नीचे का क्रॉस निकालें।
अभ्यास का हल
main() पैरामीटर में:
use_crossing_exit: bool = input.bool(True, title="Use crossings exit"),बंद करने की शाखा:
if use_crossing_exit and crosses_down:
strategy.close("Long")crosses_down = ta.crossunder(...) शर्त से पहले रहे। strategy.exit दोनों स्विच स्थिति में रहे।
क्रॉसिंग पर निकास बंद हो तो नीचे EMA क्रॉस के बाद भी पोज़िशन खुली रह सकती है। अगला प्रवेश संकेत तब भी आए, लेकिन पुरानी पोज़िशन से नया ट्रेड न खुले।
अपना रूप बनाएँ
नई नाम की कॉपी में एक नया नियम लिखें। किस डेटा और कैंडल पर निर्णय करेगा, हाथ से कैसे जाँचें और कौन-सा इनपुट बदलेगा, बताएँ।
पहले अलग वेरिएबल में निकालें। प्रवेश या निकास बनाने से पहले ग्राफ़ या डिबगर में देखें। पूरी रणनीति समझाने से पहले गणना में त्रुटि खोज पाएँगे।
सोर्स, बची सेटिंग और डेटा मिलकर प्रयोग बताते हैं। इन्हें रखें तो रन फिर बनाई और जाँची जा सकती है।