제 친한 친구인 란 씨는 이 지표를 오랫동안 관찰해 왔고 새해 첫날에 이 지표가 수치로 변환될 수 있는지에 대해 논의하기 위해 추천했습니다. 이런 소원을 이루기 위해 지체하는 사람이 지금까지 지연한 것은 유감입니다. 사실, 최근 알고리즘에 대한 저의 이해는 급속도로 향상되었습니다. 어느 날 파인 언어의 번역기를 쓸 수 있을 것으로 추정됩니다. 모든 것이 파이썬이 될 수 있습니다. 아무 말도 없이 전설적인 슈퍼 트렌드 라인을 소개해 드리겠습니다.
CMC 시장의 새로운 세대의 지능형 거래 시스템에서 우리는 사용할 기술 지표에서
간단히 살펴봅시다. 주로 HL2 (k-line 평균 가격) + ATR의 n 배가 있는 채널을 설명합니다. 트렌드 돌파구를 만듭니다. 하지만 이 기사는 간단합니다. 상세한 알고리즘이 없습니다. 사실, 정말 있습니다.
이 차트를 보면, 트렌드에 맞춰져 있습니다. 불행히도, 그것은 단지 경고 신호입니다.
코드가 길지 않아서 번역해볼게요!
전체 소나무 코드는 위와 같습니다.
여기서 우리는 FMZ에 새로운 전략을 만들고, 그것을 슈퍼트렌드라고 부릅니다.
다음으로, 우리는 두 개의 매개 변수를 설정합니다, 인수와 Pd
코드 동작을 더 단순화하고 이해를 촉진하기 위해, 우리는 파이썬의 고급 데이터 확장 패키지 판다스를 사용해야 합니다 (https://pandas.pydata.org/) FMZ는 이제 이 도서관을 지원합니다.
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
다음으로 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 값은 다음 세 가지 차이 중 최대 값입니다.
파이썬 계산에서
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=
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)
전체적인 코드 구조를 조정했습니다. 그리고 나는 전략에 긴 거리와 짧은 거와 관련된 순서 지침을 통합했습니다. 여기 전체 코드가 있습니다.
'''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
우리는 지난 해의 데이터를 백테스팅을 위해 선택했습니다. 우리는 15분 동안 OKEX 분기 계약을 사용합니다. 설정된 매개 변수는 다음과 같습니다. 인수=3 Pd=45 Vol=100 (각 주문에 100계약) 연간 수익률은 약 33%입니다. 일반적으로는, 금단술은 그다지 많지 않습니다. 312의 급격한 감소는 시스템에 비교적 큰 영향을 미쳤습니다. 312가 없다면 수익이 더 좋아질 겁니다.
슈퍼트렌드는 아주 좋은 거래 시스템입니다.
슈퍼트렌드 시스템의 주요 원칙은 ATR 채널의 돌파구 전략을 채택하는 것입니다 (켄트 채널과 비슷합니다) 그러나 그 변화는 주로 Bandit Bollinger의 좁히는 전략 또는 Donchian 원리의 역으로 인해 발생합니다. 시장 운영에서 상부와 하부 채널은 지속적으로 좁아집니다. 채널 돌파 스티어링의 작동을 달성하기 위해. (채널이 돌파되면 상부 및 하부 트랙은 초기 값으로 돌아갈 것입니다.)
저는 트레이드뷰에서 트렌드업과 트렌드
또한, 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++의 의미를 대략적으로 이해했고, 기회가 있을 때 다시 쓸 것입니다.
그 내용의 본질을 배울 수 있기를 바랍니다. - 어렵네!