Tuan Ran, teman baik saya, telah mengamati indikator ini untuk waktu yang lama dan merekomendasikannya kepada saya sebelum Hari Tahun Baru untuk mendiskusikan apakah dapat dikonversi ke dalam kuantifikasi. Sangat disayangkan bahwa penunda telah menunda sampai sekarang untuk membantunya memenuhi keinginan seperti itu. Diperkirakan suatu hari nanti aku akan menulis penerjemah untuk bahasa Pine. Nah, tanpa banyak omong kosong, mari kita perkenalkan garis super trend legendaris.
Dalam sistem perdagangan cerdas generasi baru di CMC Markets, kita dapat memilih
Lihatlah secara singkat. Ini terutama menggambarkan saluran di mana HL2 (harga rata-rata garis k) ditambah n kali ATR. Buat terobosan tren. Tapi artikelnya sederhana. tidak ada algoritma rinci. lalu saya memikirkan komunitas yang paling luar biasa, TradingView. Memang, memang ada.
Melihat grafiknya, itu sesuai dengan tren.
Kode tidak terlalu panjang, jadi mari kita coba menerjemahkannya.!(っ•̀ω•́)っ
Kode pinus lengkap adalah seperti di atas.
Di sini kita membuat strategi baru di FMZ, menamainya sebagai SuperTrend
Selanjutnya, kita akan menetapkan dua parameter, Faktor dan Pd
Untuk lebih menyederhanakan operasi kode dan memfasilitasi pemahaman, kita perlu menggunakan paket ekspansi data canggih Python
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):
M15 = pd.DataFrame(records)
M15.columns = ['time','open','high','low','close','volume','OpenInterest']
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
Kemudian kita merujuk ke manual MyLanguage, dan langkah algoritma dari nilai rata-rata amplitudo fluktuasi nyata ATR adalah sebagai berikut: TR: MAX ((MAX ((((HIGH-LOW),ABS ((REF ((CLOSE,1)-HIGH)),ABS ((REF ((CLOSE,1)-LOW)); ATR: RMA(TR,N)
Nilai TR adalah maksimum dari tiga perbedaan berikut
Dalam perhitungan Python
M15['prev_close']=M15['close'].shift(1)
Kita perlu mengatur prev_close untuk mengambil data close di baris sebelumnya, yaitu, bergerak dekat ke kanan oleh satu kisi untuk membentuk parameter baru
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
Selanjutnya, kita mendefinisikan variabel menengah yang mencatat array dari 3 nilai kontras untuk TR. (HIGH-LOW) (high-prev_close) (low-prev_close)
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
Kita mendefinisikan kolom baru dalam set data dan menamainya sebagai TR. Nilai TR adalah nilai absolut terbesar dari variabel perantara, 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 menghitung nilai ATR, ATR: RMA (TR, N). Ternyata algoritma RMA adalah varian nilai tetap algoritma EMA sebenarnya. N adalah variabel yang kita impor. parameter default ATR adalah 14.
===
Kemudian algoritma ewm digunakan untuk menghitung ema Proses perhitungan ATR lengkap adalah sebagai 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 Mulai menghitung 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 sederhana?
Ini adalah bagian kode inti dari 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
Poin utama dari paragraf ini adalah untuk menyatakan bahwa, Jika berada dalam tahap bullish, (garis bawah) TrendUp=max (Up, TrendUp [1]) Jika berada di tahap jatuh, (garis atas) TrendDown=min (Dn, TrendDown [1]) Artinya, dalam tren, nilai ATR telah menggunakan teknologi yang mirip dengan strategi Bandit Bollinger. Tetap mempersempit sisi lain dari saluran
Di sini, setiap perhitungan TrendUp dan TrendDown membutuhkan iterasi diri. Artinya, setiap langkah harus dihitung sesuai dengan langkah sebelumnya. Oleh karena itu, set data harus diulang dalam loop.
Pertama, kita membuat bidang baru TrendUp, TrendDown, Trend, linecolor untuk set data. dan memberi mereka nilai awal Kemudian kita menggunakan tata bahasa fillna (0) untuk mengisi data dengan nilai nol 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)
Aktifkan loop for Menggunakan operasi ternar python dalam loop
for x in range(len(M15)):
Menghitung TrendUp TrendUp = MAX(Up,TrendUp[-1]) jika dekat[-1]>TrendUp[-1] sebaliknya Up Ini kira-kira berarti bahwa jika penutupan sebelumnya>TrendUp sebelumnya benar, nilai maksimum antara Up dan TrendUp sebelumnya akan diambil; jika tidak, nilai Up akan diambil dan diteruskan ke TrendUp saat ini
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]
Demikian pula, menghitung 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 ini adalah bendera untuk menghitung arah kontrol. Trend= 1 jika (close > TrendDown[-1]) sebaliknya (x) x = -1 jika (dekat< TrendUp[-1]) sebaliknya Trend[-1]
Artinya adalah bahwa jika harga penutupan > TrendDown sebelumnya, ambil nilai 1 (bullish). Jika tidak, ambil nilai x Jika harga penutupan lebih rendah dari TrendUp sebelumnya, ambil nilai -1 (bearish). Jika tidak, ambil Trend sebelumnya (berarti tidak berubah) Untuk menerjemahkan ke dalam bahasa gambar adalah bahwa pecahnya bendera transisi jalur atas untuk bullish; dan pecahnya bendera transisi jalur bawah untuk bearish.
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
Menghitung Tsl dan Linecolor
Tsl= rendUp jika (Trend==1) lain TrendDown
Tsl adalah nilai yang digunakan untuk mewakili SuperTrend pada gambar. Ini berarti untuk menandai jalur ke bawah pada gambar ketika kita berada di bullish, dan menandai jalur atas pada gambar ketika kita berada di bearish.
linecolor=
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 kode berikutnya sebagian besar adalah gambar plot, yang tidak dijelaskan di sini.
Akhirnya ada 2 baris kode untuk mengontrol sinyal beli dan jual Dalam Tradeview, itu berarti bahwa sinyal diberikan setelah membalikkan Bendera Mengkonversi pernyataan bersyarat ke Python. Jika bendera Trend terakhir berubah dari -1 menjadi 1, itu berarti bahwa resistance atas telah melebihi dan membuka posisi panjang. Jika bendera Trend terakhir berubah dari 1 menjadi -1, itu berarti bahwa dukungan ke bawah telah melebihi dan membuka posisi short.
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)
Kode lengkapnya adalah sebagai 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)
Aku menyesuaikan keseluruhan struktur kode. Dan saya menggabungkan instruksi order yang berkaitan dengan pergi panjang dan pergi pendek ke dalam strategi. Ini kode 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 publik:https://www.fmz.com/strategy/200625
Kami memilih data dari tahun lalu untuk backtesting. Kami menggunakan kontrak triwulanan OKEX untuk periode 15 menit. Parameter yang ditetapkan adalah: Faktor = 3 Pd=45 Vol=100 (100 kontrak untuk setiap pesanan) Pengembalian tahunan adalah sekitar 33%. Secara umum, penarikan tidak terlalu banyak, Penurunan tajam dari 312 memiliki dampak yang relatif besar pada sistem, Jika tidak ada 312, pengembalian harus lebih baik.
SuperTrend adalah sistem perdagangan yang sangat baik
Prinsip utama sistem SuperTrend adalah mengadopsi strategi terobosan saluran ATR (mirip dengan saluran Kent) Namun, perubahannya terutama disebabkan oleh penggunaan strategi penyempitan Bandit Bollinger, atau kebalikan dari prinsip Donchian. Dalam operasi pasar, saluran atas dan bawah terus menyempit. Untuk mencapai operasi kemudi terobosan saluran. (Setelah saluran menerobos, jalur atas dan bawah akan kembali ke nilai awal)
Saya memetakan, dn, TrendUp dan TrendDn secara terpisah pada TradeView, yang membuat lebih mudah untuk memahami strategi yang lebih baik. Lihatlah dengan jelas:
Selain itu, ada versi js di github. Saya tidak pandai dengan js, tapi sepertinya ada yang salah dengan pernyataan if. Alamatnya:https://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js
Akhirnya, aku menemukan versi aslinya. Diterbitkan pada tanggal 29 Mei 2013 Penulisnya adalah Rajandran R. Kode C++ dipublikasikan di forum Mt4:https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4Saya telah memahami secara kasar arti C++, dan saya akan menulis ulang ketika saya memiliki kesempatan.
Kuharap kau bisa belajar esensinya darinya. Ini sulit.~!