슈퍼트렌드 V.1 -- 슈퍼트렌드 라인 시스템

저자:리디아, 창작: 2022-12-01 11:36:33, 업데이트: 2023-09-11 20:04:38

img

I. 이야기 의 기원

제 친한 친구인 란 씨는 이 지표를 오랫동안 관찰해 왔고 새해 첫날에 이 지표가 수치로 변환될 수 있는지에 대해 논의하기 위해 추천했습니다. 이런 소원을 이루기 위해 지체하는 사람이 지금까지 지연한 것은 유감입니다. 사실, 최근 알고리즘에 대한 저의 이해는 급속도로 향상되었습니다. 어느 날 파인 언어의 번역기를 쓸 수 있을 것으로 추정됩니다. 모든 것이 파이썬이 될 수 있습니다. 아무 말도 없이 전설적인 슈퍼 트렌드 라인을 소개해 드리겠습니다.

II. 시스템 도입

CMC 시장의 새로운 세대의 지능형 거래 시스템에서 우리는 사용할 기술 지표에서 슈퍼 트렌드 라인을 선택할 수 있습니다. 우리는 우리의 선호도에 따라 증가 신호와 감소 신호의 색과 두께를 조정할 수 있습니다. 슈퍼 트렌드 인디케이터는 무엇입니까? 슈퍼 트렌드 인디케이터 공식을 이해하기 전에 ATR를 이해하는 것이 필요합니다. 왜냐하면 슈퍼 트렌드는 인디케이터 값을 계산하기 위해 ATR 값을 채택하기 때문입니다. 주요 알고리즘은 또한 다음 그림에서 설명됩니다.

img

간단히 살펴봅시다. 주로 HL2 (k-line 평균 가격) + ATR의 n 배가 있는 채널을 설명합니다. 트렌드 돌파구를 만듭니다. 하지만 이 기사는 간단합니다. 상세한 알고리즘이 없습니다. 사실, 정말 있습니다.

img

이 차트를 보면, 트렌드에 맞춰져 있습니다. 불행히도, 그것은 단지 경고 신호입니다.

III. 소스 코드 학습

코드가 길지 않아서 번역해볼게요!

img

전체 소나무 코드는 위와 같습니다.

VI. 코드 전환

여기서 우리는 FMZ에 새로운 전략을 만들고, 그것을 슈퍼트렌드라고 부릅니다.

img

다음으로, 우리는 두 개의 매개 변수를 설정합니다, 인수와 Pd

img

코드 동작을 더 단순화하고 이해를 촉진하기 위해, 우리는 파이썬의 고급 데이터 확장 패키지 판다스를 사용해야 합니다 (https://pandas.pydata.org/) FMZ는 이제 이 도서관을 지원합니다.

  1. 판다 라이브러리와 시간 라이브러리를 가져와야 합니다.
  2. 주요 기능에서 분기 계약의 사용을 설정 (주로 okex)
  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-line의 OHCLV를 검색해야 합니다. 그래서 우리는 GetRecords를 사용합니다.
  2. 검색된 데이터를 판다 M15에 가져옵니다.
  3. M15.columns = [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을 계산해 봅시다 왜냐하면 ATR 계산은 변수 길이를 가져오기 때문에 그 값은 Pd

다음으로 MyLanguage의 매뉴얼을 참조하고, ATR 실제 변동 진폭의 평균 값의 알고리즘 단계는 다음과 같습니다. TR: MAX (MAX (MAX)) HIGH (HIGH) LOW (HIGH-LOW) ABS (REF) CLOSE (REF) HIGH (HIGH)), ABS (REF) CLOSE (REF) LOW (Low) ATR: RMA (TR,N)

TR 값은 다음 세 가지 차이 중 최대 값입니다.

  1. 현재 거래일에 가장 높은 가격과 가장 낮은 가격 사이의 변동 HIGH-LOW
  2. 이전 거래일의 종료 가격과 현재 거래일의 최고 가격의 변동 (REF) (CLOSE, 1) - HIGH
  3. 이전 거래일의 종료 가격과 현재 거래일의 최저 가격의 변동 REF (CLOSE, 1) - LOW 그래서 TR: MAX (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 개의 대조 값의 배열을 기록하는 중간 변수를 정의합니다. (HIGH-LOW) (high-prev_close) (low-prev_close)

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

마지막으로 ATR, ATR: RMA (TR, N) 의 값을 계산해야 합니다. RMA 알고리즘은 EMA 알고리즘의 고정 값 변수입니다. N는 우리가 가져오는 변수입니다. ATR의 기본 매개 변수는 14입니다. 여기 우리는 알파=길이의 역수를 가져옵니다.

===

그 다음 ewm 알고리즘은 ema를 계산하는 데 사용됩니다 전체 ATR 계산 과정은 다음과 같습니다.

    #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 계산을 시작 하 고 Dn

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

위=hl2 - (배분자 * atr) Dn=hl2 +(포터 * atr) 간단하지 않나요?

여기 TV에서 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

이 단락의 주요 내용은 상승 단계에 있는 경우 (아래 라인) 트렌드업=맥스 (올림, 트렌드업 [1]) 하락 단계에 있는 경우 (올라선) 트렌드다운=분 (Dn, 트렌드다운 [1]) 즉, ATR 값은 Bandit Bollinger 전략과 비슷한 기술을 사용했습니다. 채널의 다른 쪽을 좁혀라

여기서, 트렌드업과 트렌드다운의 각각의 계산은 자기 반복을 필요로 합니다. 즉, 각 단계는 이전 단계에 따라 계산되어야 합니다. 따라서 데이터 세트는 루프에서 반복되어야 합니다.

먼저, 우리는 새로운 필드를 생성합니다 트렌드업, 트렌드다운, 트렌드, 데이터 세트에 대한 라인 컬러. 그리고 그들에게 초기 값을 부여 그 다음 우리는 문법 Fillna (0) 을 사용하여 0으로 계산된 결과의 null 값으로 데이터를 채울 수 있습니다.

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

for 루프를 활성화 루프에서 파이썬 삼차 연산을 사용

    for x in range(len(M15)):

트렌드업을 계산합니다. 트렌드업 = MAX(업,트렌드업[-1]) 만약 닫힌다면[-1]>트렌드업[-1] 그렇지 않으면 업 이것은 대략적으로 만약 이전 Close>previous TrendUp가 사실이라면, Up와 이전 TrendUp 사이의 최대 값이 취해질 것이고, 그렇지 않다면, Up값이 취해 현재의 TrendUp에 전달될 것입니다.

        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]

마찬가지로, 트렌드다운을 계산 트렌드다운=min(Dn,트렌드다운[-1]) close[-1]<트렌드다운[-1] else Dn 이것은 대략적으로 이전 종료 < 이전 트렌드다운이 사실이라면, Dn와 이전 트렌드다운 사이의 최소 값이 취해집니다. 그렇지 않으면 Dn 값이 취해지고 현재 트렌드다운에 전달됩니다.

        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 if (close > TrendDown[-1]) else (x) x = -1 if (close

그 의미는 닫기 가격> 이전 트렌드다운, 1의 값을 취하는 것입니다. 그렇지 않으면, x의 값을 취합니다. 닫기 가격이 이전 트렌드업보다 낮다면 -1 (하락) 의 값을 취합니다. 그렇지 않으면 이전 트렌드 (변화되지 않은 것을 의미합니다) 를 취합니다. 이미지 언어로 번역하면 상승세를 나타내는 상단 트레크 전환 플래그의 파업, 하단 트레크 전환 플래그의 파업은 하락세를 나타냅니다.

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

Tsl와 Linecolor를 계산하세요 Tsl= if (Trend==1) else TrendDown를 표시하는 경우 tsl는 이미지에 있는 슈퍼트렌드를 나타내는 값입니다. 이것은 상승세에 있을 때 이미지의 하향 트랙을 표시하고 하향세에 있을 때 이미지의 상위 트랙을 표시하는 것을 의미합니다. linecolor= 녹색 if (Trend==1) else 붉은 라인 컬러의 의미는 우리가 상승세에 있다면 녹색선을 표시하고, 하락세에 있다면 빈 색을 표시하는 것입니다. (주로 트레이드뷰 디스플레이의 목적으로)

        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 Pd=45 Vol=100 (각 주문에 100계약) 연간 수익률은 약 33%입니다. 일반적으로는, 금단술은 그다지 많지 않습니다. 312의 급격한 감소는 시스템에 비교적 큰 영향을 미쳤습니다. 312가 없다면 수익이 더 좋아질 겁니다.

img

VII. 끝에 적어

슈퍼트렌드는 아주 좋은 거래 시스템입니다.

슈퍼트렌드 시스템의 주요 원칙은 ATR 채널의 돌파구 전략을 채택하는 것입니다 (켄트 채널과 비슷합니다) 그러나 그 변화는 주로 Bandit Bollinger의 좁히는 전략 또는 Donchian 원리의 역으로 인해 발생합니다. 시장 운영에서 상부와 하부 채널은 지속적으로 좁아집니다. 채널 돌파 스티어링의 작동을 달성하기 위해. (채널이 돌파되면 상부 및 하부 트랙은 초기 값으로 돌아갈 것입니다.)

저는 트레이드뷰에서 트렌드업과 트렌드을 따로 그래프로 그려보았습니다. 이는 전략을 더 쉽게 이해할 수 있게 합니다. 한눈에 알 수 있습니다.

img

또한, github에 js의 버전이 있습니다. 나는 js에 잘하지 않습니다, 하지만 if 명령어에 뭔가 문제가 있는 것 같습니다. 주소:https://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

마침내, 저는 원본 버전을 찾아냈습니다. 2013년 5월 29일에 출판되었습니다. 저자: 라잔드란 R. C++ 코드는 Mt4 포럼에 게시되었습니다:https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4저는 C++의 의미를 대략적으로 이해했고, 기회가 있을 때 다시 쓸 것입니다.

그 내용의 본질을 배울 수 있기를 바랍니다. - 어렵네!


관련

더 많은