Type/to search
0
Follow
48
Followers
SuperTrend V.1--Super Trend Line System
Original
Created 2020-04-20 22:10:36  Updated 2024-12-12 21:03:30
 28
 12168

img

1. Asal usul cerita

Rakan baik saya Ran telah memerhati penunjuk ini untuk masa yang lama dan mengesyorkannya kepada saya sebelum Hari Tahun Baru untuk membincangkan sama ada ia boleh ditukar kepada bentuk kuantitatif.
Malangnya, saya mengalami kelewatan dan tidak membantunya memenuhi hasratnya sehingga kini, sebenarnya pemahaman saya tentang algoritma telah mencapai kemajuan yang besar baru-baru ini.
Saya bercadang untuk menulis penterjemah pain suatu hari nanti. Semuanya boleh jadi ular sawa. .
Okay, tanpa berlengah lagi, mari kita perkenalkan barisan trend super legenda ini. .

2. Pengenalan Sistem

Sistem perdagangan pintar generasi baharu CMC Markets - Supertrend
Berikut adalah artikel yang memperkenalkan sistem ini.
img

Dalam sistem perdagangan pintar generasi baharu dalam Pasaran CMC, pilih "Super Trend Line" dalam penunjuk teknikal untuk memanggilnya.
Seperti yang ditunjukkan dalam rajah, anda boleh melaraskan "warna dan ketebalan" isyarat naik dan turun mengikut pilihan anda.
Jadi apakah penunjuk supertrend? Sebelum memahami formula penunjuk supertrend, adalah perlu untuk memahami ATR kerana supertrend menggunakan nilai ATR untuk mengira nilai penunjuk.

Algoritma utama juga diperkenalkan dalam gambar di bawah.
img

Pada pandangan kasar, penerangan utama ialah saluran HL2 (harga purata K-line) didarab dengan n kali ATR. Buat pelarian trend.
Tetapi artikel itu agak ringkas. Tiada algoritma terperinci. Kemudian saya memikirkan Tradingview komuniti terbaik.
Tidak menghairankan. Sudah tentu, ia ada di sana.
img

Jika dilihat dari graf, ia agak konsisten dengan trend. Tetapi malangnya ia hanyalah isyarat Makluman.

3. Kaji kod sumber

Kod itu tidak kelihatan terlalu panjang, jadi mari menterjemahkannya dan mencubanya. ! (っ•̀ω•́)っ✎⁾⁾!
img
Kod pain lengkap adalah seperti di atas. .

4. Penukaran Kod

Di sini kami mencipta strategi baharu dalam FMZ dan menamakannya SuperTrade
img

Seterusnya, kami menetapkan dua parameter Faktor dan Pd
img

Untuk memudahkan operasi kod dengan lebih baik dan menjadikannya lebih mudah difahami, kami perlu menggunakan pakej pengembangan data lanjutan Pythonpandas

Semasa makan tengah hari, saya bertanya kepada Guru Mengmeng sama ada FMZ menyokong perpustakaan ini. Saya menyemaknya pada sebelah petang dan ia benar-benar berkesan.
Hebat sungguh cikgu Mengmeng.

1. Kita perlu mengimport perpustakaan masa perpustakaan panda
2. Sediakan kontrak suku tahunan dalam fungsi utama (terutamanya menjalankan OKEX)
3. Tetapkan gelung doTicker() untuk diuji sekali setiap 15 minit.
Jalankan kod pada kitaran 15 minit
Seterusnya 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)

4. Kita perlu mendapatkan semula OHCLV K-line, jadi gunakan GetRecords()
5. Kami mengimport data yang diambil ke dalam panda M15 = pd.DataFrame(rekod)
6. Kita perlu mengubah suai teg pengepala jadual. M15.lajur =['time','open','high','low','close','volume','OpenInterest']
Malah, ia hanya menukar huruf pertama 'terbuka', 'tinggi', 'rendah' ​​dan 'dekat' kepada huruf kecil, supaya lebih mudah untuk menulis kod kemudian tanpa berselang-seli antara huruf besar dan huruf kecil.

def doTicker(records): M15 = pd.DataFrame(records) M15.columns = ['time','open','high','low','close','volume','OpenInterest']

7. Tambahkan lajur hl2 pada set data hl2=(tinggi+rendah)/2

#HL2 M15['hl2']=(M15['high']+M15['low'])/2

8. Seterusnya, mari kita mengira ATR
Oleh kerana pengiraan ATR memerlukan import panjang berubah-ubah, nilainya ialah Pd

Kemudian kami merujuk kepada manual bahasa Mai, dan langkah algoritma purata turun naik 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 ialah yang terbesar daripada tiga perbezaan berikut.

  1. Turun naik antara harga tertinggi dan harga terendah hari dagangan semasa TINGGI-RENDAH
  2. Turun naik antara harga penutupan hari dagangan sebelumnya dan harga tertinggi hari dagangan semasa (RUJUK(TUTUP,1)-TINGGI)
  3. Turun naik antara harga penutupan hari dagangan sebelumnya dan harga terendah hari dagangan semasa (RUJUK(CLOSE,1)-RENDAH)
    Jadi TR : MAX(MAX((HIGH-RENDAH),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));

Dalam pengiraan Python

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

Mula-mula, sediakan prev_close untuk mendapatkan data close dalam baris sebelumnya, iaitu, bergerak dekat kanan dengan 1 grid untuk membentuk parameter baharu

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

Seterusnya, tentukan pembolehubah perantaraan untuk merekodkan tatasusunan tiga nilai perbandingan TR. (TINGGI-RENDAH)(tinggi-prev_close)(rendah-prev_close)

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

Kami mentakrifkan lajur baharu bernama TR dalam set data Nilai TR ialah nilai mutlak maksimum bagi pembolehubah perantaraan Kami 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()

Akhir sekali, kita perlu mengira nilai ATR, ATR: RMA (TR, N Didapati bahawa algoritma RMA sebenarnya adalah varian nilai tetap bagi algoritma EMA).
N ialah pembolehubah yang kami import, dengan parameter lalai untuk ATR ialah 14. Di sini kita mengimport alpha = salingan panjang.

===

Kemudian gunakan algoritma EWM untuk mengira EMA
Proses pengiraan ATR yang 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 Mula mengira Naik dan Dn

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

Up=hl2 -(Factor * atr)
Dn=hl2 +(Factor * atr)
Bukankah ia mudah?

Berikut ialah segmen kod teras baris 15-21 dalam 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

Tujuan utama perenggan ini adalah untuk menyatakan,
Jika dalam fasa kenaikan harga, (garisan bawah) TrendUp = max(Up,TrendUp[1])
Jika ia dalam peringkat jatuh, (garis atas) TrendDown=min(Dn,TrendDown[1])
Maksudnya, dalam trend, nilai ATR telah menggunakan teknik yang serupa dengan strategi Bandit Bollinger.
Teruskan menyempitkan bahagian lain saluran

Di sini, setiap pengiraan TrendUp dan TrendDown perlu diulang sendiri.
Maksudnya, setiap langkah mesti dikira berdasarkan langkah sebelumnya.
Jadi kita perlu mengulangi set data.

Di sini kita perlu mencipta medan baharu TrendUp, TrendDown, Trend dan warna garisan untuk set data. Dan berikan mereka nilai awal
Kemudian gunakan sintaks fillna(0) untuk mengisi data dengan nilai nol dalam hasil yang dikira 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)

Mulakan gelung untuk
Menggunakan operasi ternary Python dalam gelung

for x in range(len(M15)):

Mengira TrendUp
TrendUp = MAX(Up,TrendUp[-1]) if close[-1]>TrendUp[-1] else Up
Maksud umum ialah jika penutupan sebelumnya > TrendUp sebelumnya, jika benar, ambil nilai maksimum Naik dan TrendUp sebelumnya, jika tidak benar, ambil nilai Naik dan hantar 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, kira TrendDown
TrendDown=min(Dn,TrendDown[-1]) if close[-1]<TrendDown[-1] else Dn
Maksud umum ialah jika penutupan sebelumnya < TrendDown sebelumnya, jika benar, ambil nilai minimum antara Dn dan TrendDown sebelumnya, jika tidak benar, ambil nilai Dn dan hantar ke TrendDown semasa

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]

Di bawah ialah bendera untuk mengira arah kawalan saya memudahkan kod pseudo
Trend= 1 if (close > TrendDown[-1]) else (x)
x = -1 if (close< TrendUp[-1]) else Trend[-1]

Maksudnya jika harga penutup > TrendDown sebelumnya, maka ambil 1 (bullish) jika tidak, ambil x
Jika harga penutup adalah kurang daripada TrendUp sebelumnya, maka ambil -1 (pendek Jika tidak, ambil Trend sebelumnya (yang bermaksud ia kekal tidak berubah).
Diterjemah ke dalam bahasa grafik, ia bermakna menembusi rel atas untuk menukar bendera kepada kenaikan harga, menembusi rel bawah untuk menukar bendera kepada menurun, dan masa yang lain kekal tidak berubah.

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

Kira Tsl dan Linecolor
Tsl= rendUp if (Trend==1) else TrendDown
Tsl digunakan untuk mewakili nilai SuperTrend pada graf. Ini bermakna apabila anda menaik, tandakan landasan bawah pada carta, dan apabila anda menurun, tandakan landasan atas pada carta.
linecolor= 'green' if (Trend==1) else 'red'
Maksud linecolor ialah jika anda yakin, tandakan garisan hijau, jika anda menurun, tandakan warna kosong (terutama digunakan untuk paparan Tradingview)

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'

Baris 23-30 berikut adalah terutamanya untuk merancang, yang tidak akan diterangkan secara terperinci di sini.

Akhir sekali, terdapat 2 baris kod untuk kawalan isyarat membeli dan menjual
Dalam Tradingview, ia bermaksud memberi isyarat selepas membalikkan Bendera.
Tukar pernyataan bersyarat kepada python.
Jika bendera Trend sebelumnya berubah dari -1 kepada 1, ini bermakna rintangan atas telah dipecahkan
Jika bendera Trend sebelumnya berubah dari 1 kepada -1, ini bermakna sokongan ke bawah telah dipecahkan.

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 untuk bahagian ini 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

5. Semua kod

Saya melaraskan struktur kod keseluruhan.
Dan gabungkan arahan pesanan berkaitan panjang dan pendek ke dalam strategi.
Berikut adalah kod lengkap

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

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

6. Ujian Balik dan Rumusan

Kami memilih data dari tahun lalu untuk ujian balik.
Gunakan kontrak suku tahunan OKEX dengan kitaran 15 minit.
Parameter yang ditetapkan ialah,
Factor=3
Pd=45
vol=100 (100 tiket setiap pesanan)
Pulangan tahunan adalah kira-kira 33%.
Secara umum, anjakan tidak terlalu besar.
Sebab utama untuk ini ialah ranap 312 yang mempunyai kesan ketara pada sistem.
Jika tiada 312, pulangan akan lebih baik.

img

6. Fikiran Akhir

SuperTrend ialah sistem perdagangan yang sangat baik

Prinsip utama sistem SuperTrend adalah menggunakan strategi pemecahan saluran ATR (serupa dengan saluran Kent)
Tetapi perubahan utama terletak pada penggunaan strategi penyempitan Bandit Bollinger, atau prinsip Donchian terbalik.
Saluran atas dan bawah sentiasa mengecil semasa operasi pasaran.
Untuk mencapai penembusan saluran dan operasi pusingan. (Setelah saluran menembusi, rel atas dan bawah kembali ke nilai asalnya)

Saya merancang dn TrendUp TrendDn secara berasingan pada TradingView
Ini akan membantu anda memahami strategi ini dengan lebih baik

Jelas sekali imbas
img

Terdapat juga versi js pada github. Saya tidak memahami js dengan baik, tetapi berdasarkan pernyataan if, nampaknya ada masalah.
Alamatnya ialahhttps://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

Akhirnya saya menjejaki versi asal.
Ia diterbitkan pada 2013.05.29
Ditulis oleh Rajandran R
Kod C++ diterbitkan dalam forum Mt4https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4
Saya secara kasar memahami maksud C++ dan akan menulis semula apabila saya mempunyai peluang.

Saya harap semua orang boleh belajar intipati daripadanya.
Ia sukar. ~!

Related Recommendations
Comment
All comments (25)

    YYDS!

    5 years ago

    如果直接使用这个策略在OK交易所交易需要怎么连接交易所,小白一个不会python,看不明白

    6 years ago

    这里如果312那波行情没吃到的话应该参数还有很大的调整空间,因为supertrend主要就是抓趋势单,312是不应该错过的。另外期待lz的pine翻译器早日问世

    6 years ago

    可惜各种周期和参数,回测效果都不怎么好, 不知道其它人怎么优化的?

    6 years ago

    可以了,弄好了,感谢您的付出

    6 years ago

    用不了呢,显示这个:Traceback (most recent call last): File "<string>", line 1473, in Run File "<string>", line 8, in <module> ImportError: No module named pandas

    6 years ago

    意思是缺少pandas包 你的系统可能需要pip install pandas

    6 years ago

    请问这是怎么处理的呢?万分感谢

    6 years ago

    pine的翻译器,期待

    6 years ago

    没啥文化只能说一声 牛逼!

    6 years ago

    “估摸着某一天写一个pine的翻译器。一切皆可python。”—— 牛,好些人看好这个!

    6 years ago

    啊哈哈,谢谢老板

    6 years ago

    期待期待,pine真的看不太懂,教程也很少

    6 years ago

    回测引擎的代码是否可以开源呢,我想实现复现一下 然后用svm找出最好的参数

    6 years ago

    这个系统好像也曾经是收益率前十的期货策略。长期坚持做下去是能赚钱的。

    6 years ago

    恩啊。学习精髓。

    6 years ago

    你好,请教下,PD就是 ATR的长度值吧? 比如 ATR(14) ,就是 PD赋值14了吧?

    6 years ago

    是的,完全正确

    6 years ago

    好的,谢谢!!!
    顺手mq4也收走了,谢谢。。 o(∩_∩)o

    6 years ago

    感谢梦梦老师哈

    6 years ago

    碰巧我也写了个JS版本的。

    6 years ago

    求JS版!

    6 years ago

    一会儿,公开。

    6 years ago

    赞的,!

    6 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)