SuperTrend V.1 - Hệ thống đường xu hướng siêu

Tác giả:bài giảng, Tạo: 2020-04-20 22:10:36, Cập nhật: 2023-10-08 19:57:57

img

Câu chuyện bắt nguồn từ

Một người bạn thân của tôi, Vago, đã quan sát được chỉ số này trong một thời gian dài và đã đề xuất cho tôi trước năm mới để thảo luận về việc có thể chuyển đổi thành định lượng hay không. Thật không may, sự trì hoãn đã phạm tội, đã kéo dài đến bây giờ để giúp anh ấy thực hiện mong muốn như vậy, trong thực tế, nhận thức về thuật toán gần đây đã tăng vọt. Có thể một ngày nào đó bạn sẽ viết một trình dịch viên pine. Không cần nói quá nhiều, chúng ta hãy giới thiệu về siêu xu hướng trong truyền thuyết này.

2/ Hướng dẫn hệ thống

CMC Markets thế hệ mới của hệ thống giao dịch thông minh SupertrendCó một bài viết về hệ thống này tại đây.img

Trong hệ thống giao dịch thông minh thế hệ mới của CMC Markets, việc điều chỉnh đường xu hướng siêu cao trong các chỉ số kỹ thuật có thể được sử dụng ngay lập tức. Như hình trên, bạn có thể điều chỉnh màu sắc và độ mịn theo sở thích của mình đối với tín hiệu tăng, tín hiệu giảm. Trước khi hiểu công thức của chỉ số siêu xu hướng, điều cần thiết là hiểu ATR, bởi vì siêu xu hướng sử dụng giá trị ATR để tính giá trị chỉ số.

Các thuật toán chính trong số đó được mô tả dưới đây.img

Nhìn chung, mô tả chính là HL2 (k đường trung bình) nhân kênh ATR n lần; làm đột phá xu hướng. Tuy nhiên, bài viết viết khá đơn giản. Không có thuật toán chi tiết. Sau đó tôi nghĩ đến cộng đồng tốt nhất là Tradingview. Không có gì đáng ngạc nhiên.img

Theo biểu đồ, nó có vẻ phù hợp hơn với xu hướng.

Ba, học mã nguồn

Nếu bạn thấy mã không quá dài, hãy thử dịch nhé.imgMã pin đầy đủ được hiển thị dưới đây.

Bốn, chuyển đổi mã

Ở đây chúng tôi đã xây dựng một chiến lược mới ở FMZ, gọi là SuperTrade.img

Sau đó chúng ta sẽ đặt 2 tham số là Factor, Pd.img

Để đơn giản hóa mã hoạt động tốt hơn, dễ hiểu hơn, sử dụng gói mở rộng dữ liệu cao cấp của Pythoncá voi

Trong bữa trưa, tôi hỏi giáo viên về FMZ, liệu FMZ có hỗ trợ thư viện này không. Trong khi đó, một người phụ nữ trẻ tuổi khác cũng bị ảnh hưởng bởi những điều này.

1.我们要导入pandas库time库 2.在main函数当中设置使用季度合约(主要跑okex) 3. Thiết lập một vòng doTicker để kiểm tra 1 lần trong 15 phút.Nó chạy mã theo chu kỳ 15 phút. Sau đó, chúng tôi viết các chiến lược chính trong 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. Chúng ta muốn lấy OHCLV của đường k, vì vậy chúng ta sử dụng GetRecords 5. Chúng ta sẽ nhập dữ liệu thu được vào panda M15 = pd.DataFrame (records) M15.columns = [time tab,open tab,high tab,low tab,close tab,volume tab,OpenInterest tab]Thực tế là thay đổi chữ cái đầu tiên của open, high, low, close, và close thành chữ viết nhỏ, giúp bạn viết mã sau này mà không phải viết lớn và viết nhỏ.

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

7. cho tập dữ liệu thêm một hàng hl2 hl2= ((high+low) /2)

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

8.接着我们来计算ATRVì tính toán của ATR là nhập một variable length, nó lấy Pd

Sau đó, chúng ta hãy xem các bước của thuật toán để tìm ra giá trị trung bình của tần số biến động thực của ATR bằng cách xem hướng dẫn ngôn ngữ của chúng tôi: TR: MAX ((MAX ((HIGH-LOW), ABS ((REF ((CLOSE, 1) -HIGH)), ABS ((REF ((CLOSE, 1) -LOW)); ATR: RMA (TR,N)

Trong đó TR là giá trị lớn nhất trong 3 giá trị khác nhau dưới đây. 1, Phạm vi dao động giữa giá cao nhất và giá thấp nhất trong ngày giao dịch hiện tại 2, Phạm vi sóng giữa giá đóng cửa ngày giao dịch trước và giá cao nhất ngày giao dịch đó REF ((CLOSE, 1) - HIGH) 3, Phạm vi sóng giữa giá đóng cửa ngày giao dịch trước và giá thấp nhất ngày đó REF ((CLOSE, 1) - LOW) Vì vậy, TR: MAX ((MAX (((HIGH-LOW), ABS ((REF ((CLOSE, 1) -HIGH)), ABS ((REF ((CLOSE, 1) -LOW));

Trong Python

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

Để lấy dữ liệu close trên hàng trước, bạn cần thiết lập một parameter prev_close, tức là chuyển 1 vào bên phải của mảng để tạo ra một tham số mới.

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

Sau đó, xác định một biến trung gian để ghi lại một mảng 3 giá trị đối chiếu của TR.

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

Chúng ta định nghĩa TR trong một tập dữ liệu mới, lấy TR là giá trị tối đa của giá trị tuyệt đối của các biến trung gian, sử dụng hàm abs (() và max (())

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

Cuối cùng, chúng ta sẽ tính giá trị của ATR, ATR: RMA ((TR,N), theo đó thuật toán của RMA thực sự là một thuật toán EMA biến đổi giá trị cố định. N là một biến mà chúng ta nhập, trong đó các tham số mặc định của ATR là 14; ở đây chúng ta nhập số phân số của alpha = length.

===

Sau đó tính toán em bằng thuật toán ewm.Tiến trình tính toán ATR đầy đủ như sau:

    #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 bắt đầu tính Up và Dn

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

Up=hl2 - ((Factor * atr) Dn=hl2 + ((Factor * atr)) Có phải nó đơn giản không?

Dưới đây là đoạn mã cốt lõi trong TV từ 15 đến 21 dòng.

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

Một số người cho rằng, "Điều này không phải là điều tốt". Nếu ở giai đoạn tăng giá, (bottom line) TrendUp = max (Up, TrendUp[1]) Nếu ở giai đoạn giảm, (đường trên) TrendDown=min (Dn, TrendDown[1])Điều này có nghĩa là trong một xu hướng, giá trị của ATR luôn sử dụng một kỹ thuật tương tự như chiến lược cướp bóc. Cắt lại phía bên kia của lối đi

Ở đây, TrendUp và TrendDown cần tự lặp lại mỗi lần tính toán. Những người tham gia cuộc thi này đều là những người có ý thức về cuộc thi. Vì vậy, bạn nên quay vòng trên bộ dữ liệu.

Ở đây, bạn cần tạo các trường mới trên tập dữ liệu TrendUp, TrendDown, Trend, linecolor và gán cho chúng một giá trị ban đầu. Sau đó, sử dụng phác thảo fillna ((0) để điền vào 0 dữ liệu có giá trị trống trong kết quả tính toán trước đó.

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

Cho phép một vòng lặp for Sử dụng python thứ ba trong vòng lặp

    for x in range(len(M15)):

Tính toán TrendUpTrendUp = MAX ((Up,TrendUp[-1]) if close [-1]>TrendUp[-1] else Up Điều này có nghĩa là nếu giá trị lớn nhất trong số gần nhất > gần nhất là TrendUp, và giá trị lớn nhất trong số TrendUp trước đó là TrendUp, thì giá trị của Up sẽ không được tạo ra và sẽ được truyền đến TrendUp hiện tại.

        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]

Tương tự, tính 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]

Dưới đây là một biểu tượng tính toán hướng điều khiển, và tôi đã đơn giản hóa một số mã giả.Xu hướng = 1 nếu (kết thúc > Xu hướngDown[-1]) khác (x) x = -1 nếu (close< TrendUp[-1]) khác Trend[-1]

Điều đó có nghĩa là nếu giá đóng > một TrendDown trước đó, lấy 1 (xem thêm) không thành lập lấy x. Nếu giá đóng cửa < một TrendUp trước đó, lấy -1 (bỏ trống) không thành lập lấy một Trend (có nghĩa là không thay đổi) Dịch thành ngôn ngữ hình ảnh là vượt qua đường ray chuyển đổi cờ nhìn nhiều hơn, vượt qua đường ray chuyển đổi cờ nhìn không, thời gian khác không thay đổi.

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

Tính toán Tsl và LinecolorTsl = rendUp if (Trend==1) else TrendDown Tsl được sử dụng để biểu thị giá trị SuperTrend trên hình ảnh. Điều này có nghĩa là đánh dấu theo dõi trên biểu đồ khi xem nhiều và đánh dấu theo dõi trên biểu đồ khi nhìn trống. linecolor= green if (Trend==1) else red Linecolor có nghĩa là nếu xem nhiều thì đánh dấu đường xanh, nếu nhìn không thì đánh dấu màu trắng (chủ yếu dùng cho Tradeview display)

        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'

Sau đó, các dòng mã 23-30 chủ yếu là các bản vẽ phác thảo.

Cuối cùng, có 2 dòng mã để kiểm soát tín hiệu mua bán.Trong Tradingview, ý nghĩa của anh ta là báo hiệu sau khi đảo ngược Flag. Chuyển các điều kiện thành python. Nếu cờ xu hướng trước đó từ -1 trở thành 1, nó sẽ vượt qua ngưỡng kháng cự trên. Nếu cờ xu hướng trước đó từ 1 trở thành -1 thì nó sẽ phá vỡ và hỗ trợ giảm.

    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)

Mã đầy đủ cho đoạn này là:

    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, toàn bộ mã

Tôi đã thay đổi toàn bộ cấu trúc mã. Trong khi đó, các công ty khác cũng sẽ có những hướng dẫn về việc làm thêm việc làm trống. Dưới đây là toàn bộ mã.

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

Liên kết chiến lược công khai http://www.fmz.com/strategy/200625

6. Kiểm tra lại và tóm tắt

Chúng tôi đã chọn dữ liệu gần một năm để kiểm tra lại. Sử dụng hợp đồng quý okx theo chu kỳ 15 phút. Các tham số được đặt là: Các yếu tố là 3 Pd = 45 vol = 100 (đơn giản là 100 đơn hàng mỗi lần) Trong khi đó, một số doanh nghiệp khác cũng có lợi nhuận hàng năm, khoảng 33%. Tuy nhiên, một số người cho rằng việc rút lui là không lớn. Trong số đó, sự sụp đổ lớn của 312 đã gây ra một cú sốc lớn hơn cho hệ thống. Nếu không có 312, lợi nhuận sẽ khá hơn.

img

6 và cuối cùng.

SuperTrend là một hệ thống giao dịch rất tốt.

Quy tắc chính của hệ thống SuperTrend là sử dụng chiến lược phá vỡ kênh ATR (tương tự như kênh Kent) Tuy nhiên, thay đổi chủ yếu là sử dụng chiến lược thu hẹp của những tên cướp Brin, hay là nguyên tắc Dongjian ngược lại. Trong khi đó, một số doanh nghiệp khác cũng đang làm việc trên các kênh giao dịch. Để đạt được hoạt động chuyển hướng vượt qua kênh. (Một khi kênh vượt qua, đường ray lên xuống sẽ khôi phục lại giá trị ban đầu)

Tôi đã vẽ up dn TrendUp TrendDn trên TradingView. Điều này giúp chúng ta hiểu rõ hơn về chiến lược này.Một cái nhìn.img

Ngoài ra còn có một phiên bản js trên github. Tôi không hiểu gì về js, nhưng có vẻ như có một chút vấn đề. Địa chỉ:https://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

Cuối cùng, tôi đã tìm kiếm bản gốc. Nó được xuất bản vào ngày 29.05.2013. Tác giả là Rajandran R. Mã C++ được đăng trên diễn đàn Mt4https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4Tôi đã hiểu C++ một cách tổng quát và có cơ hội viết lại một bài nữa.

Tôi hy vọng mọi người có thể học được những điều quan trọng từ nó. Không có gì khó khăn cả.


Có liên quan

Thêm nữa

zdg4484YYDS!

Lglydz2010Nếu sử dụng trực tiếp chiến lược này giao dịch trên sàn giao dịch OK cần làm thế nào để kết nối sàn giao dịch, một con chuột trắng sẽ không Python, nhìn không hiểu

BamsmenỞ đây, nếu sóng 312 không ăn được, các tham số vẫn có nhiều chỗ để điều chỉnh, bởi vì siêu xu hướng chủ yếu là nắm bắt danh sách xu hướng, 312 không nên bỏ qua.

Thanh TửNhưng tất cả các chu kỳ và các tham số đều không hiệu quả, không biết người khác đã tối ưu hóa như thế nào?

Lão béo.Được rồi, đã hoàn thành, cảm ơn bạn đã đóng góp.

Lão béo.Traceback (most recent call last): File "", line 1473, in Run File "", line 8, in ImportError: No module named pandas

xunfeng91Người dịch của Pine, mong đợi

thời gianKhông có nền văn hóa nào có thể chỉ nói một từ: "Thật mạnh mẽ!"

Frank131419Một ngày nào đó, bạn sẽ có thể viết một phiên dịch viên của một cây thông minh. Mọi thứ đều có thể được làm bằng Python.

KmeansTôi muốn thực hiện lặp lại và sau đó sử dụng svm để tìm ra các tham số tốt nhất

dsaidasiHệ thống này dường như cũng là một chiến lược tương lai trong top 10 lợi nhuận.

Những đám mây nhẹXin chào, PD là chiều dài của ATR, phải không? ví dụ như ATR ((14) là PD được gán 14?

Giấc mơ nhỏTôn vinh

ovelsĐợi đợi, Pine thực sự không hiểu, và rất ít hướng dẫn.

bài giảngCó nghĩa là thiếu gói pandas, hệ thống của bạn có thể cần pip install pandas

Ant_SkyXin vui lòng giải quyết vấn đề này như thế nào?

bài giảngCảm ơn ông chủ.

Giấc mơ nhỏChờ một chút, công khai nhé.

LonelymanXin phiên bản JS!

bài giảngNhờ đó, bạn có thể học được những điều quan trọng nhất.

Những đám mây nhẹTốt, cảm ơn!!! Mq4 cũng bị loại bỏ, cảm ơn bạn.

bài giảngVâng, hoàn toàn đúng

bài giảngLạy Chúa!

Giấc mơ nhỏVà tình cờ tôi cũng đã viết một phiên bản JS.

bài giảngCảm ơn giáo viên Dream Dream.