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

सुपरट्रेंड V.1 -- सुपरट्रेंड लाइन सिस्टम

लेखक:FMZ~Lydia, बनाया गयाः 2022-12-01 11:36:33, अद्यतन किया गयाः 2023-09-11 20:04:38

img

I. कहानी की उत्पत्ति

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

II. प्रणाली की शुरूआत

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

img

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

img

चार्ट को देखते हुए, यह प्रवृत्ति के अनुरूप है। दुर्भाग्य से, यह केवल अलर्ट का अलार्म सिग्नल है।

III. सोर्स कोड सीखना

कोड बहुत लंबा नहीं है, तो चलो इसे अनुवाद करने की कोशिश करते हैं.!

img

पूर्ण पाइन कोड उपरोक्त के समान है।

VI. कोड रूपांतरण

यहाँ हम एफएमजेड पर एक नई रणनीति बनाते हैं, इसे सुपरट्रेंड नाम देते हैं

img

अगला, हम दो मापदंडों, कारक और पीडी सेट करेंगे

img

कोड ऑपरेशन को बेहतर ढंग से सरल बनाने और समझने में आसानी के लिए, हमें पायथन के उन्नत डेटा विस्तार पैकेज पांडा का उपयोग करने की आवश्यकता है (https://pandas.pydata.org/) एफएमजेड अब इस पुस्तकालय का समर्थन करता है।

  1. हमें पांडा पुस्तकालय और समय पुस्तकालय आयात करने की जरूरत है
  2. मुख्य कार्य में, त्रैमासिक अनुबंधों का उपयोग निर्धारित करें (मुख्य रूप से ओकेएक्स के लिए)
  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)
  1. हम K-लाइन के OHCLV पुनर्प्राप्त करने की जरूरत है, तो हम GetRecords का उपयोग (()
  2. हम पैंडा M15 = pd.DataFrame ((रिकॉर्ड) के लिए पुनर्प्राप्त डेटा आयात
  3. हमें तालिका के हेडर लेबल को संशोधित करने की आवश्यकता है. M15. स्तंभ = [time,open,high,low,close,volume,OpenInterest] वास्तव में, यह open, high, low, और close के प्रारंभिक अक्षरों को लोअरकेस में बदलने के लिए है, ताकि हमारे बाद के कोड लेखन को अपरकेस से लोअरकेस में बदलने की आवश्यकता न हो।
def doTicker(records):
    M15 = pd.DataFrame(records)
    M15.columns = ['time','open','high','low','close','volume','OpenInterest']  
  1. डेटा सेट hl2 hl2=(high+low) /2 में एक स्तंभ जोड़ें
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
  1. तो चलो ATR की गणना करते हैं क्योंकि एटीआर गणना एक चर लंबाई आयात करने की जरूरत है, जिसका मूल्य पीडी है

फिर हम MyLanguage के मैनुअल का उल्लेख करते हैं, और एटीआर वास्तविक उतार-चढ़ाव आयाम के औसत मूल्य के एल्गोरिथ्म चरण निम्नानुसार हैंः TR: MAX ((MAX ((((HIGH-LOW),ABS ((REF ((CLOSE,1)-HIGH)),ABS ((REF ((CLOSE,1)-LOW)); एटीआरः आरएमए ((TR,N)

TR मान निम्नलिखित तीन अंतरों में से अधिकतम है

  1. चालू व्यापार दिवस पर उच्चतम मूल्य और निम्नतम मूल्य के बीच उतार-चढ़ाव HIGH-LOW
  2. पिछले व्यापार दिवस के समापन मूल्य और वर्तमान व्यापार दिवस के उच्चतम मूल्य REF (CLOSE, 1) के बीच उतार चढ़ाव - HIGH
  3. पिछले व्यापार दिवस के समापन मूल्य और वर्तमान व्यापार दिवस के निम्नतम मूल्य के बीच उतार-चढ़ाव (CLOSE, 1) - LOW तो TR: MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));

पायथन की गणना में

M15['prev_close']=M15['close'].shift(1)

हम पिछले पंक्ति में बंद के डेटा को पुनर्प्राप्त करने के लिए एक prev_close सेट करने की जरूरत है, कि है, एक ग्रिड द्वारा एक नया पैरामीटर बनाने के लिए बंद करने के लिए सही स्थानांतरित करें

ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]

इसके बाद, हम एक मध्यवर्ती चर को परिभाषित करते हैं जो TR के लिए 3 विरोधाभासी मूल्यों की एक सरणी को रिकॉर्ड करता है। (उच्च-निम्न) (उच्च-पूर्व_कुल) (निम्न-पूर्व_कुल)

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

अंत में, हमें एटीआर, एटीआरः आरएमए (टीआर, एन) के मूल्य की गणना करने की आवश्यकता है। यह पाया जाता है कि आरएमए एल्गोरिथ्म वास्तव में ईएमए एल्गोरिथ्म का एक निश्चित मूल्य संस्करण है। एन हम आयात चर है. एटीआर के डिफ़ॉल्ट पैरामीटर 14 है. यहाँ हम अल्फा = लंबाई के पारस्परिक आयात.

===

तो ईएमएम एल्गोरिथ्म ईएमए की गणना करने के लिए प्रयोग किया जाता है एटीआर की गणना की पूरी प्रक्रिया इस प्रकार है

    #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'])

अप=एचएल2 - (क) कारक * एटीआर Dn=hl2 +(कारक * 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 की प्रत्येक गणना के लिए स्वयं पुनरावृत्ति की आवश्यकता होती है। यानी प्रत्येक चरण को पिछले चरण के अनुसार गणना की जानी चाहिए। इसलिए, डेटा सेट को लूप में दोहराया जाना चाहिए।

सबसे पहले, हम डेटा सेट के लिए नए क्षेत्रों ट्रेंडअप, ट्रेंडडाउन, ट्रेंड, लाइन कलर बनाते हैं। और उन्हें एक प्रारंभिक मूल्य देते हैं फिर हम 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]) यदि बंद[-1]>TrendUp[-1] अन्यथा ऊपर इसका मतलब यह है कि यदि पिछले बंद>पिछले ट्रेंडअप सच है, तो ऊपर और पिछले ट्रेंडअप के बीच अधिकतम मूल्य लिया जाएगा; यदि नहीं, तो ऊपर का मूल्य लिया जाएगा और वर्तमान ट्रेंडअप को पारित किया जाएगा

        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=min(Dn,TrendDown[-1]) यदि बंद[-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]

निम्नलिखित नियंत्रण दिशा की गणना के लिए झंडा है. मैं छद्म कोड सरल बनाया ट्रेंड= 1 यदि (बंद > ट्रेंडडाउन[-1]) अन्यथा (x) x = -1 यदि (close

इसका अर्थ यह है कि यदि समापन मूल्य>पिछले ट्रेंडडाउन, 1 का मूल्य (बुलिश) ले लो। यदि नहीं, एक्स का मूल्य ले लो। यदि समापन मूल्य पिछले ट्रेंडअप से कम है, तो -1 का मान लें (बियर) यदि नहीं, तो पिछले ट्रेंड (अपरिवर्तित अर्थ) को लें छवि भाषा में अनुवाद करने के लिए यह है कि तेजी के लिए ऊपरी ट्रैक संक्रमण ध्वज का ब्रेकआउट; और मंदी के लिए निचले ट्रैक संक्रमण ध्वज का ब्रेकआउट। अन्यथा समय नहीं बदलेगा।

        M15['Tsl'].values[x] = M15['TrendUp'].values[x] if  (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]

Tsl और Linecolor की गणना करें Tsl=RendUp यदि (ट्रेंड==1) अन्यथा TrendDown Tsl छवि पर सुपरट्रेंड का प्रतिनिधित्व करने के लिए उपयोग किया जाने वाला मान है। इसका मतलब है कि जब हम तेजी में होते हैं तो छवि पर नीचे की ट्रैक को चिह्नित करना, और जब हम मंदी में होते हैं तो छवि पर ऊपरी ट्रैक को चिह्नित करना। linecolor= green if (Trend==1) अन्यथा 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)

img img

V. पूरा कोड

मैंने समग्र कोड संरचना को समायोजित किया। और मैंने लंबी और छोटी रणनीति में जाने से संबंधित आदेश निर्देशों को मिलाया। यहाँ पूरा कोड हैः

'''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

VI. बैकटेस्टिंग और सारांश

हमने बैकटेस्टिंग के लिए पिछले वर्ष के डेटा का चयन किया। हम 15 मिनट की अवधि के लिए OKEX त्रैमासिक अनुबंध का उपयोग करते हैं। सेट पैरामीटर हैंः कारक=3 पीडी=45 Vol=100 (प्रत्येक आदेश के लिए 100 अनुबंध) वार्षिक प्रतिफल लगभग 33% है। सामान्य तौर पर, निकासी बहुत ज्यादा नहीं है, 312 की तेज गिरावट का प्रणाली पर अपेक्षाकृत बड़ा प्रभाव पड़ा। यदि 312 नहीं है, तो रिटर्न बेहतर होना चाहिए।

img

VII. अंत में लिखें

सुपरट्रेंड एक बहुत अच्छा ट्रेडिंग सिस्टम है

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

मैं ट्रेड व्यू पर अलग-अलग डीएन, ट्रेंडअप और ट्रेंडडीएन ग्राफ करता हूं, जिससे रणनीति को बेहतर ढंग से समझना आसान हो जाता है। इसे एक नज़र में स्पष्ट रूप से देखें:

img

इसके अतिरिक्त, github पर js का एक संस्करण है. मैं js में अच्छा नहीं हूँ, लेकिन ऐसा लगता है कि अगर कथन के साथ कुछ गलत है। पताःhttps://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

अंत में, मैंने मूल संस्करण का पता लगाया। यह 29 मई 2013 को प्रकाशित किया गया था लेखक राजेंद्रन आर. C++ कोड Mt4 फोरम पर प्रकाशित किया गया था:https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4मैंने C++ के अर्थ को मोटे तौर पर समझा है, और जब मुझे अवसर मिलेगा, मैं इसे फिर से लिखूंगा।

मुझे आशा है कि आप इससे सार सीख सकते हैं। यह मुश्किल है!


संबंधित

अधिक