SuperTrend V.1 -- Sistem Garis Super Trend

Penulis:Lydia, Dicipta: 2022-12-01 11:36:33, Dikemas kini: 2023-09-11 20:04:38

img

I. Asal cerita

Encik Ran, kawan baik saya, telah memerhatikan penunjuk ini untuk masa yang lama dan mengesyorkannya kepada saya sebelum Hari Tahun Baru untuk membincangkan sama ada ia boleh ditukar menjadi kuantiti. Malangnya, penundaan telah menunda sehingga sekarang untuk membantu dia memenuhi keinginan seperti itu. Dianggarkan bahawa suatu hari nanti saya akan menulis penterjemah untuk bahasa Pine. Baiklah, tanpa banyak omong kosong, mari kita perkenalkan garis super trend yang legendaris.

II. Pengenalan sistem

Dalam sistem perdagangan pintar generasi baru di CMC Markets, kita boleh memilih Super Trend Line dari penunjuk teknikal yang akan digunakan, Kita boleh menyesuaikan warna dan ketebalan dari peningkatan isyarat dan penurunan isyarat mengikut pilihan kita sendiri. Jadi apa itu indikator super trend? Sebelum memahami formula indikator super trend, adalah perlu untuk memahami ATR, kerana super trend menggunakan nilai ATR untuk mengira nilai indikator. Algoritma utama juga diterangkan dalam gambar berikut:

img

Lihat secara ringkas. Ia terutamanya menerangkan saluran di mana HL2 (k-line harga purata) ditambah n kali ATR. Buat trend terobosan. Tetapi artikelnya mudah. Tiada algoritma terperinci. Kemudian saya memikirkan komuniti yang paling menakjubkan, TradingView. Memang, ia memang ada.

img

Melihat carta, ia adalah selaras dengan trend.

III. Pembelajaran kod sumber

Kodnya tidak terlalu panjang, jadi mari kita cuba menerjemahkannya.!

img

Kod pinus lengkap adalah seperti di atas.

VI. Penukaran kod

Di sini kita mencipta strategi baru di FMZ, menamakannya sebagai SuperTrend

img

Seterusnya, kita akan menetapkan dua parameter, Faktor dan Pd

img

Untuk lebih memudahkan operasi kod dan memudahkan pemahaman, kita perlu menggunakan Python's data lanjutan pengembangan pakej Pandas (https://pandas.pydata.org/) FMZ menyokong perpustakaan ini sekarang.

  1. Kita perlu mengimport perpustakaan panda dan perpustakaan masa
  2. Dalam fungsi utama, tetapkan penggunaan kontrak suku (terutamanya untuk okex)
  3. Tetapkan kitaran doTicker untuk mengesan sekali setiap 15 minit. Jalankan kod pada tempoh 15 minit Kemudian kita menulis strategi utama dalam 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. Kita perlu mendapatkan OHCLV K-line, jadi kita gunakan GetRecords()
  2. Kami mengimport data yang diambil ke panda M15 = pd.DataFrame ((rekod)
  3. M15.columns = [time,open,high,low,close,volume,OpenInterest] Sebenarnya, ia adalah untuk menukar huruf awal open, high, low, dan close ke huruf kecil, supaya penulisan kod kita kemudian tidak perlu berubah dari huruf besar ke huruf kecil.
def doTicker(records):
    M15 = pd.DataFrame(records)
    M15.columns = ['time','open','high','low','close','volume','OpenInterest']  
  1. Tambah lajur kepada set data hl2 hl2=(tinggi+rendah) / 2
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
  1. Kemudian mari kita mengira ATR Kerana pengiraan ATR perlu mengimport panjang berubah, yang nilainya adalah Pd

Kemudian kita merujuk kepada manual MyLanguage, dan langkah algoritma nilai purata amplitudo fluktuasi sebenar ATR adalah seperti berikut: TR: MAX ((MAX ((((HIGH-LOW),ABS ((REF ((CLOSE,1)-HIGH)),ABS ((REF ((CLOSE,1)-LOW)); ATR: RMA(TR,N)

Nilai TR adalah maksimum daripada tiga perbezaan berikut:

  1. Fluktuasi antara harga tertinggi dan harga terendah pada hari dagangan semasa HIGH-LOW
  2. Fluktuasi antara harga penutupan hari dagangan sebelumnya dan harga tertinggi hari dagangan semasa (REF) (LANGKAH, 1) - HIGH
  3. Fluktuasi antara harga penutupan hari dagangan sebelumnya dan harga terendah hari dagangan semasa REF (CLOSE, 1) - LOW Jadi TR: MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));

Dalam pengiraan Python

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

Kita perlu menubuhkan prev_close untuk mendapatkan data dekat dalam baris sebelumnya, iaitu, bergerak dekat kanan oleh satu grid untuk membentuk parameter baru

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

Seterusnya, kita menentukan pembolehubah pertengahan yang merekodkan pelbagai 3 nilai kontras untuk TR. (HIGH-LOW) (high-prev_close) (low-prev_close)

M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)

Kami menentukan lajur baru dalam set data dan menamakannya sebagai TR. Nilai TR adalah nilai mutlak terbesar dari pemboleh ubah pertengahan, menggunakan fungsi abs () dan max ()

    alpha = (1.0 / length) if length > 0 else 0.5
    M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()

Akhirnya, kita perlu mengira nilai ATR, ATR: RMA (TR, N). N adalah pembolehubah yang kita import. parameter lalai ATR adalah 14.

===

Kemudian algoritma ewm digunakan untuk mengira ema Proses pengiraan ATR lengkap adalah seperti berikut:

    #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 Mulakan mengira Up dan Dn

    M15['Up']=M15['hl2']-(Factor*M15['atr'])
    M15['Dn']=M15['hl2']+(Factor*M15['atr'])

Up=hl2 - ((Faktor * atr) Dn=hl2 +(Faktor * atr) Bukankah itu mudah?

Ini adalah bahagian kod teras baris 15-21 dari TV

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

Titik utama perenggan ini adalah untuk menyatakan bahawa, Jika ia berada dalam peringkat menaik, (garis bawah) TrendUp=max (Up, TrendUp [1]) Jika ia berada dalam peringkat jatuh, (garis atas) TrendDown=min (Dn, TrendDown [1]) Maksudnya, dalam trend, nilai ATR telah menggunakan teknologi yang serupa dengan strategi Bandit Bollinger. Tetap menyempitkan di sisi lain saluran

Di sini, setiap pengiraan TrendUp dan TrendDown memerlukan pengulangan diri. Iaitu, setiap langkah harus dikira mengikut langkah sebelumnya. Oleh itu, set data harus diulang dalam gelung.

Pertama, kita mencipta medan baru TrendUp, TrendDown, Trend, linecolor untuk set data. Kemudian kita menggunakan tatabahasa fillna (0) untuk mengisi data dengan nilai sifar dalam hasil yang dihitung sebelumnya dengan 0

    M15['TrendUp']=0.0
    M15['TrendDown']=0.0
    M15['Trend']=1
    M15['Tsl']=0.0
    M15['linecolor']='Homily'
    M15 = M15.fillna(0)

Membolehkan untuk gelung Menggunakan operasi ternar python dalam gelung

    for x in range(len(M15)):

Mengira TrendUp TrendUp = MAX(Up,TrendUp[-1]) jika dekat[-1]>TrendUp[-1] sebaliknya Up Ia kira-kira bermakna bahawa jika penutupan sebelumnya>TrendUp sebelumnya adalah benar, nilai maksimum antara Up dan TrendUp sebelumnya akan diambil; jika tidak, nilai Up akan diambil dan dihantar ke TrendUp semasa

        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]

Begitu juga, mengira TrendDown TrendDown=min(Dn,TrendDown[-1]) jika dekat[-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]

Berikut adalah bendera untuk mengira arah kawalan. Trend= 1 jika (tutup > TrendDown[-1]) sebaliknya (x) x = -1 jika (dekat< TrendUp[-1]) sebaliknya Trend[-1]

Maksudnya ialah jika harga penutupan> TrendDown sebelumnya, ambil nilai 1 (bullish). Jika tidak, ambil nilai x Jika harga penutupan adalah lebih rendah daripada TrendUp sebelumnya, ambil nilai -1 (bearish). Jika tidak, ambil Trend sebelumnya (bererti tidak berubah) Untuk diterjemahkan ke dalam bahasa imej adalah bahawa pecah bendera peralihan trek atas untuk bullish; dan pecah bendera peralihan trek bawah untuk bearish.

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

Mengira Tsl dan Linecolor Tsl= rendUp jika (Trend==1) sebaliknya TrendDown Tsl adalah nilai yang digunakan untuk mewakili SuperTrend pada imej. Ia bermaksud untuk menandakan trek ke bawah pada imej apabila kita berada dalam kenaikan, dan menandakan trek atas pada imej apabila kita berada dalam penurunan. linecolor= hijau jika (Trend==1) sebaliknya merah Makna linecolor adalah untuk menandakan garis hijau jika kita berada dalam bullish, dan menandakan warna kosong jika kita berada dalam bearish (terutamanya untuk tujuan paparan Tradeview)

        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 baris kod seterusnya adalah gambar plot, yang tidak dijelaskan di sini.

Akhirnya, terdapat 2 baris kod untuk mengawal isyarat beli dan jual Dalam Tradeview, ia bermakna bahawa isyarat diberikan selepas membalikkan Bendera Mengubah pernyataan bersyarat ke Python. Jika bendera Trend terakhir berubah dari -1 kepada 1, ini bermakna rintangan atas telah melebihi dan membuka kedudukan panjang. Jika bendera Trend terakhir berubah dari 1 kepada -1, ini bermakna sokongan ke bawah telah melebihi dan membuka kedudukan pendek.

    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)

Kod lengkap adalah seperti berikut:

    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. Kod lengkap

Saya menyesuaikan keseluruhan struktur kod. Dan saya menggabungkan arahan perintah yang berkaitan dengan pergi panjang dan pergi pendek ke dalam strategi. Ini kod lengkapnya:

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

Alamat strategi awam:https://www.fmz.com/strategy/200625

VI. Ujian belakang dan ringkasan

Kami memilih data tahun lepas untuk backtesting. Kami menggunakan kontrak suku OKEX untuk tempoh 15 minit. Parameter yang ditetapkan ialah: Faktor = 3 Pd=45 Vol=100 (100 kontrak untuk setiap pesanan) Pulangan tahunan adalah kira-kira 33%. Secara amnya, penarikan tidak banyak, Penurunan tajam 312 mempunyai kesan yang agak besar pada sistem, Jika tiada 312, pulangan harus lebih baik.

img

VII. Tulis di akhir

SuperTrend adalah sistem perdagangan yang sangat baik

Prinsip utama sistem SuperTrend adalah untuk mengamalkan strategi terobosan saluran ATR (mirip dengan saluran Kent) Walau bagaimanapun, perubahannya terutamanya disebabkan oleh penggunaan strategi penyempitan Bandit Bollinger, atau sebaliknya prinsip Donchian. Dalam operasi pasaran, saluran atas dan bawah terus menyempit. Untuk mencapai operasi stereng terobosan saluran. (Setelah saluran menembusi, trek atas dan bawah akan kembali ke nilai awal)

Saya merangka, dn, TrendUp dan TrendDn secara berasingan pada TradeView, yang memudahkan untuk memahami strategi yang lebih baik. Lihatlah dengan jelas:

img

Di samping itu, terdapat versi js di github. Saya tidak baik di js, tetapi nampaknya ada sesuatu yang salah dengan if statement. Alamatnya:https://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

Akhirnya, saya mengesan versi asal. Ia diterbitkan pada 29 Mei 2013 Penulisnya ialah Rajandran R. Kod C ++ telah diterbitkan di forum Mt4:https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4Saya telah memahami maksud C++, dan saya akan menulis semula apabila saya berpeluang.

Saya harap awak boleh belajar daripadanya. Ia sukar.~!


Berkaitan

Lebih lanjut