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

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

एक मोटे तौर पर देखा जाए तो मुख्य विवरण HL2 (K-लाइन का औसत मूल्य) का एक चैनल है जिसे n गुणा ATR से गुणा किया गया है। एक प्रवृत्ति सफलता बनाएँ.
लेकिन यह लेख काफी संक्षिप्त है। इसमें कोई विस्तृत एल्गोरिथ्म नहीं है। फिर मैंने सबसे अच्छे समुदाय ट्रेडिंगव्यू के बारे में सोचा।
आश्चर्य की बात नहीं. निःसंदेह, यह वहां है।

ग्राफ से पता चलता है कि यह प्रवृत्ति के अनुरूप है। लेकिन दुर्भाग्य से यह सिर्फ एक चेतावनी संकेत है।
कोड ज्यादा लंबा नहीं लगता, इसलिए आइए इसका अनुवाद करें और प्रयास करें। ! (っ•̀ω•́)っ✎⁾⁾!
पूरा पाइन कोड ऊपर दिया गया है। .
यहां हम FMZ में एक नई रणनीति बनाते हैं और इसे सुपरट्रेड नाम देते हैं

इसके बाद, हम दो पैरामीटर Factor और Pd निर्धारित करते हैं

कोड के संचालन को बेहतर ढंग से सरल बनाने और इसे समझना आसान बनाने के लिए, हमें पायथन के उन्नत डेटा विस्तार पैकेज का उपयोग करने की आवश्यकता हैpandas
दोपहर के भोजन के दौरान, मैंने शिक्षक मेंगमेंग से पूछा कि क्या एफएमजेड इस लाइब्रेरी का समर्थन करता है। मैंने दोपहर में इसकी जांच की और यह वास्तव में काम कर रहा था। शिक्षक मेंगमेंग वास्तव में अद्भुत हैं।
1. हमें पांडा लाइब्रेरी टाइम लाइब्रेरी को आयात करने की आवश्यकता है 2. मुख्य फ़ंक्शन में त्रैमासिक अनुबंध सेट करें (मुख्य रूप से OKEX चलाना) 3. प्रत्येक 15 मिनट में एक बार परीक्षण करने के लिए doTicker() लूप सेट करें। कोड को 15 मिनट के चक्र पर चलाएं इसके बाद हम doTicker() में मुख्य रणनीति लिखते हैं।
import pandas as pd
import time
def main():
exchange.SetContractType("quarter")
preTime = 0
Log(exchange.GetAccount())
while True:
records = exchange.GetRecords(PERIOD_M15)
if records and records[-2].Time > preTime:
preTime = records[-2].Time
doTicker(records[:-1])
Sleep(1000 *60)
4. हमें K-लाइन का OHCLV प्राप्त करने की आवश्यकता है, इसलिए GetRecords() का उपयोग करें 5. हम प्राप्त डेटा को pandas में आयात करते हैं M15 = pd.DataFrame(records) 6. हमें टेबल हेडर टैग को संशोधित करने की आवश्यकता है। M15.कॉलम =[‘time’,‘open’,‘high’,‘low’,‘close’,‘volume’,‘OpenInterest’] वास्तव में, यह केवल ‘ओपन’, ‘हाई’, ‘लो’ और ‘क्लोज’ के प्रथम अक्षरों को लोअरकेस में बदल देता है, ताकि बाद में अपरकेस और लोअरकेस के बीच परिवर्तन किए बिना कोड लिखना आसान हो जाए।
def doTicker(records):
M15 = pd.DataFrame(records)
M15.columns = ['time','open','high','low','close','volume','OpenInterest']
7. डेटा सेट hl2=(high+low)/2 में एक कॉलम hl2 जोड़ें
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
8. अब, एटीआर की गणना करते हैं क्योंकि एटीआर की गणना के लिए एक परिवर्तनीय लंबाई के आयात की आवश्यकता होती है, इसका मान Pd है
फिर हम माई भाषा मैनुअल का संदर्भ लेते हैं, और एटीआर वास्तविक अस्थिरता औसत के एल्गोरिथ्म चरण निम्नानुसार हैं: TR : MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); ATR : RMA(TR,N)
TR मान निम्नलिखित तीन अंतरों में से सबसे बड़ा है। 1. वर्तमान कारोबारी दिन के उच्चतम मूल्य और निम्नतम मूल्य के बीच उतार-चढ़ाव उच्च-निम्न 2. पिछले कारोबारी दिन के समापन मूल्य और वर्तमान कारोबारी दिन के उच्चतम मूल्य के बीच उतार-चढ़ाव (REF(CLOSE,1)-HIGH) 3. पिछले कारोबारी दिन के समापन मूल्य और वर्तमान कारोबारी दिन के न्यूनतम मूल्य के बीच उतार-चढ़ाव (REF(CLOSE,1)-LOW) तो TR : MAX(MAX((उच्च-निम्न),ABS(REF(बंद,1)-उच्च)),ABS(REF(बंद,1)-निम्न));
पायथन गणना में
M15['prev_close']=M15['close'].shift(1)
सबसे पहले, पिछली पंक्ति में बंद का डेटा प्राप्त करने के लिए prev_close सेट करें, अर्थात, एक नया पैरामीटर बनाने के लिए close को 1 ग्रिड से दाईं ओर ले जाएं
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
इसके बाद, TR के तीन तुलनात्मक मूल्यों की सरणी को रिकॉर्ड करने के लिए एक मध्यवर्ती चर को परिभाषित करें। (उच्च-निम्न)(उच्च-पिछला_बंद)(निम्न-पिछला_बंद)
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
हम डेटा सेट में TR नाम से एक नया कॉलम परिभाषित करते हैं। TR का मान मध्यवर्ती चर का अधिकतम निरपेक्ष मान है। हम abs() और max() फ़ंक्शन का उपयोग करते हैं।
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
अंत में, हमें ATR, ATR: RMA (TR, N) के मान की गणना करने की आवश्यकता है। यह पाया गया कि RMA एल्गोरिथ्म वास्तव में EMA एल्गोरिथ्म का एक निश्चित मूल्य वाला संस्करण है। N वह चर है जिसे हमने आयात किया है, जहां ATR के लिए डिफ़ॉल्ट पैरामीटर 14 है। यहाँ हम अल्फा = लम्बाई का व्युत्क्रम आयात करते हैं।
===
फिर EMA की गणना करने के लिए EWM एल्गोरिथ्म का उपयोग करें संपूर्ण एटीआर गणना प्रक्रिया इस प्रकार है
#ATR(PD)
length=Pd
M15['prev_close']=M15['close'].shift(1)
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
9 अप और डाउन की गणना शुरू करें
M15['Up']=M15['hl2']-(Factor*M15['atr'])
M15['Dn']=M15['hl2']+(Factor*M15['atr'])
Up=hl2 -(Factor * atr) Dn=hl2 +(Factor * atr) क्या यह सरल नहीं है?
निम्नलिखित टीवी में लाइनों 15-21 का मुख्य कोड खंड है
TrendUp=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend = close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown
linecolor = Trend == 1 ? green : red
इस अनुच्छेद का मुख्य उद्देश्य यह व्यक्त करना है, यदि तेजी के चरण में, (निचली रेखा) TrendUp = max(Up,TrendUp[1]) यदि यह गिरती अवस्था में है, (ऊपरी रेखा) TrendDown=min(Dn,TrendDown[1]) कहने का तात्पर्य यह है कि, एक प्रवृत्ति में, एटीआर मूल्य बैंडिट बोलिंगर रणनीति के समान तकनीक का उपयोग कर रहा है। चैनल के दूसरे किनारे को संकीर्ण करते रहें
यहां, ट्रेंडअप और ट्रेंडडाउन की प्रत्येक गणना को स्वयं दोहराया जाना आवश्यक है। अर्थात्, प्रत्येक चरण की गणना पिछले चरण के आधार पर की जानी चाहिए। इसलिए हमें डेटा सेट के माध्यम से लूप करने की आवश्यकता है।
यहां हमें सबसे पहले डेटा सेट के लिए नए फ़ील्ड TrendUp, TrendDown, Trend और linecolor बनाने की आवश्यकता है। और उन्हें एक प्रारंभिक मूल्य दें फिर 0 के साथ पहले से गणना किए गए परिणामों में शून्य मानों के साथ डेटा भरने के लिए fillna (0) सिंटैक्स का उपयोग करें
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
फॉर लूप शुरू करें लूप में पायथन टर्नरी ऑपरेशन का उपयोग करना
for x in range(len(M15)):
ट्रेंडअप की गणना TrendUp = MAX(Up,TrendUp[-1]) if close[-1]>TrendUp[-1] else Up सामान्य अर्थ यह है कि यदि पिछला क्लोज > पिछला ट्रेंडअप, यदि यह सत्य है, तो अप का अधिकतम मान लें और पिछला ट्रेंडअप, यदि यह सत्य नहीं है, तो अप मान लें और इसे वर्तमान ट्रेंडअप में पास करें
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
इसी तरह, TrendDown की गणना करें TrendDown=min(Dn,TrendDown[-1]) if close[-1]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
नीचे नियंत्रण दिशा की गणना के लिए ध्वज है। मैंने छद्म कोड को सरल बनाया है Trend= 1 if (close > TrendDown[-1]) else (x) x = -1 if (close< TrendUp[-1]) else Trend[-1]
इसका अर्थ यह है कि यदि समापन मूल्य पिछले ट्रेंडडाउन से अधिक है, तो 1 लें (तेजी) यदि नहीं, तो x लें यदि समापन मूल्य पिछले ट्रेंडअप से कम है, तो -1 (शॉर्ट) लें। यदि नहीं, तो पिछला ट्रेंड लें (जिसका अर्थ है कि यह अपरिवर्तित रहता है)। ग्राफिक भाषा में अनुवादित, इसका अर्थ है कि ध्वज को तेजी में बदलने के लिए ऊपरी रेल को तोड़ना, ध्वज को मंदी में बदलने के लिए निचली रेल को तोड़ना, तथा बाकी समय अपरिवर्तित रहना।
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
Tsl और Linecolor की गणना करें Tsl= rendUp if (Trend==1) else TrendDown टीएसएल का उपयोग ग्राफ पर सुपरट्रेंड के मूल्य को दर्शाने के लिए किया जाता है। इसका मतलब यह है कि जब आप तेजी में हों, तो चार्ट पर निचले ट्रैक को चिह्नित करें, और जब आप मंदी में हों, तो चार्ट पर ऊपरी ट्रैक को चिह्नित करें। linecolor= ‘green’ if (Trend==1) else ‘red’ लाइनकलर का अर्थ है यदि आप तेजी में हैं, तो हरे रंग की रेखा को चिह्नित करें, यदि आप मंदी में हैं, तो खाली रंग को चिह्नित करें (मुख्य रूप से ट्रेडिंगव्यू डिस्प्ले के लिए उपयोग किया जाता है)
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else 'red'
निम्नलिखित पंक्तियाँ 23-30 मुख्यतः प्लॉटिंग के लिए हैं, जिन्हें यहाँ विस्तार से नहीं समझाया जाएगा।
अंत में, सिग्नल नियंत्रण खरीदने और बेचने के लिए कोड की 2 लाइनें हैं ट्रेडिंगव्यू में, इसका मतलब फ्लैग को उलटने के बाद संकेत देना है। सशर्त कथनों को पायथन में परिवर्तित करें। यदि पिछला ट्रेंड फ्लैग -1 से 1 में बदलता है, तो इसका मतलब है कि ऊपरी प्रतिरोध टूट गया है। लंबे समय तक खोलें यदि पिछला ट्रेंड फ़्लैग 1 से -1 में बदलता है, तो इसका मतलब है कि नीचे की ओर समर्थन टूट गया है। शॉर्ट पोजीशन खोलें।
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long',"Create Order Buy)
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long',"Create Order Sell)
इस अनुभाग का पूरा कोड इस प्रकार है:
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
for x in range(len(M15)):
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else 'red'
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long',"Create Order Buy)
Log('Tsl=',Tsl)
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long',"Create Order Sell)
Log('Tsl=',Tsl)


मैंने समग्र कोड संरचना को समायोजित किया। और रणनीति में लंबे और छोटे से संबंधित आदेश निर्देशों को मर्ज करें। यहाँ पूरा कोड है
'''backtest
start: 2019-05-01 00:00:00
end: 2020-04-21 00:00:00
period: 15m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
'''
import pandas as pd
import time
def main():
exchange.SetContractType("quarter")
preTime = 0
Log(exchange.GetAccount())
while True:
records = exchange.GetRecords(PERIOD_M15)
if records and records[-2].Time > preTime:
preTime = records[-2].Time
doTicker(records[:-1])
Sleep(1000 *60)
def doTicker(records):
#Log('onTick',exchange.GetTicker())
M15 = pd.DataFrame(records)
#Factor=3
#Pd=7
M15.columns = ['time','open','high','low','close','volume','OpenInterest']
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
#ATR(PD)
length=Pd
M15['prev_close']=M15['close'].shift(1)
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
M15['Up']=M15['hl2']-(Factor*M15['atr'])
M15['Dn']=M15['hl2']+(Factor*M15['atr'])
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
for x in range(len(M15)):
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'Long' if ( M15['Trend'].values[x]==1) else 'Short'
linecolor=M15['linecolor'].values[-2]
close=M15['close'].values[-2]
Tsl=M15['Tsl'].values[-2]
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long','Create Order Buy')
Log('Tsl=',Tsl)
position = exchange.GetPosition()
if len(position) > 0:
Amount=position[0]["Amount"]
exchange.SetDirection("closesell")
exchange.Buy(_C(exchange.GetTicker).Sell*1.01, Amount);
exchange.SetDirection("buy")
exchange.Buy(_C(exchange.GetTicker).Sell*1.01, vol);
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long','Create Order Sell')
Log('Tsl=',Tsl)
position = exchange.GetPosition()
if len(position) > 0:
Amount=position[0]["Amount"]
exchange.SetDirection("closebuy")
exchange.Sell(_C(exchange.GetTicker).Buy*0.99,Amount);
exchange.SetDirection("sell")
exchange.Sell(_C(exchange.GetTicker).Buy*0.99, vol*2);
सार्वजनिक रणनीति लिंक: https://www.fmz.com/strategy/200625
हमने बैकटेस्टिंग के लिए पिछले वर्ष के डेटा का चयन किया। 15 मिनट के चक्र के साथ OKEX त्रैमासिक अनुबंध का उपयोग करें। निर्धारित पैरामीटर हैं, Factor=3 Pd=45 वॉल्यूम=100 (प्रति ऑर्डर 100 टिकट) वार्षिक रिटर्न लगभग 33% है। सामान्यतः, रिट्रेसमेंट बहुत बड़ा नहीं है। इसका मुख्य कारण 312 क्रैश है जिसका सिस्टम पर महत्वपूर्ण प्रभाव पड़ा है। यदि 312 न होता तो रिटर्न बेहतर होता।

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

गिटहब पर इसका js संस्करण भी उपलब्ध है। मैं js को बहुत अच्छी तरह से नहीं समझता, लेकिन if कथन से देखते हुए, ऐसा लगता है कि कुछ समस्या है। पता हैhttps://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js
अंततः मुझे मूल संस्करण मिल गया। यह 2013.05.29 को प्रकाशित हुआ था राजेंद्रन आर द्वारा लिखित C++ कोड Mt4 फोरम में प्रकाशितhttps://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4 मैं C++ का अर्थ मोटे तौर पर समझता हूं और मौका मिलने पर इसे पुनः लिखूंगा।
मुझे आशा है कि हर कोई इससे सार सीख सकेगा। यह मुश्किल है। ~!