하이켄 아시 모멘텀 퀀트 전략

저자:차오장, 날짜: 2024-01-19 15:29:35
태그:

img

전반적인 설명

이 전략은 매일 헤이켄 아시 촛불을 기반으로 하며, 다른 시간 프레임에 걸쳐 동력 분석과 결합하여 현재 가격의 기본 지원을 동적으로 결정하고 진입 및 출구 지점을 식별합니다.

전략 논리

  1. 다른 시간 프레임에 걸쳐 Heiken Ashi 촛불의 폐쇄 가격을 계산하여 후속 추진 분석의 기초로 계산합니다.

  2. 오픈 가격과 역사적인 폐쇄 가격 사이의 비율 변화를 계산합니다. 월별 및 일간 시간 프레임 모두에 걸쳐. 이것은 역사적인 수준에 비해 현재 가격의 힘의 힘을 반영합니다.

  3. 일일 및 월간 모멘텀 변동의 평균을 취하십시오. 이것은 약간의 소음을 필터링하고 더 안정적인 모멘텀 벤치마크를 얻습니다.

  4. 평균 모멘텀 변동에 기초하여 현재 가격에 실제로 반영된 시장 지원 힘을 계산할 수 있습니다. 즉 시장 소음을 제외한 동적 모멘텀 문턱입니다.

  5. 클로즈 가격이 모멘텀 임계값을 넘으면 매월 장기 포지션이 시작됩니다. 가격이 임계값을 넘으면 포지션이 종료됩니다.

장점 분석

가장 큰 장점은 단순히 가격을 추격하는 대신 전략은 진입 및 출입 가격의 실제 지원 힘을 계산한다는 사실에 있습니다. 이것은 효과적으로 시장의 잡음을 필터링하고 안정적인 상승 추세를 파악 할 수 있습니다.

또한, 모든 기본 데이터는 하이켄 아시 촛불에서 파생되며, 이는 본질적으로 다른 유형의 촛불 전략에서 존재하는 연결된 시간 프레임에 대한 과도한 의존의 문제를 줄이는 데 도움이됩니다. 따라서 안정성은 더 좋습니다.

위험 분석

가장 큰 위험은 동력 계산이 역사적인 가격에만 의존한다는 것입니다. 기본 기업 기본 또는 시장 체제가 중대한 변화를 보인다면 역사적인 가격의 대표성이 감소하여 입출출을 식별하는 오류가 발생합니다.

또한, 전략은 월별 및 일일 시간 프레임을 활용합니다. 이것은 실시간 성능이 가장 좋지 않다는 것을 의미합니다. 급격한 가격 변화에 신속하게 대응할 능력이 부족합니다. 따라서 가격이 갑자기 변할 때 출구가 시간에 발생하지 않을 위험이 있습니다.

완화 가능한 방법은 더 높은 주파수 데이터와 회사 기본에 대한 실시간 피드백을 통합하는 것입니다. 또는 검증 및 최적화를 위해 더 주관적인 거래 신호로 보완합니다.

최적화 방향

이 전략이 더 향상될 수 있는 몇 가지 방법이 있습니다.

  1. 헤이켄 아시 촛불 자체를 더욱 향상시켜 무게 구성을 최적화합니다.

  2. 더 많은 시간 프레임을 통합하고, 안정성을 높이기 위해 기하급수적으로 평균된 점수 메커니즘을 구축합니다.

  3. 더 높은 주파수 데이터, 예를 들어 분자 바를 도입하여 실시간성을 향상시킵니다.

  4. 이윤 경고와 M&A 소문을 동력 계산에 포함시켜 회사의 기본 요소를 추가합니다.

  5. 월간 항목 위에 일 & 주 기반의 이익 취득 및 재입구 메커니즘을 추가하는 것을 고려하십시오.

결론

요약하자면, 전략은 전반적으로 매우 안정적이며, 모멘텀 추적은 위험을 효과적으로 제어합니다. 가장 큰 장점은 가격 자체보다는 가격의 근본적인 힘을 사용하여 진입 및 출입을위한 진정한 시장 조건을 결정하는 것입니다. 다음 단계는 더 높은 빈도와 더 많은 정보 데이터를 통합하여 더 나은 시장 기회를 활용함으로써 더 개선하는 것입니다.


/*backtest
start: 2023-01-12 00:00:00
end: 2024-01-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FrancoPassuello

//@version=5
strategy("Heiken Ashi ADM", overlay=true)
haClose = (open + high + low + close) / 4
// prevHaOpen = line.new(na, na, na, na, width = 1)
haOpen = (open[1] + close[1]) / 2
// line.set_xy1(prevHaOpen, bar_index[1], nz(haOpen[1]))
// line.set_xy2(prevHaOpen, bar_index, haClose[1])


[monopen, _1monopen, _2monopen, _3monopen, _4monopen, _5monopen, _6monopen] = request.security(syminfo.tickerid, "M", [haOpen, haOpen[1], haOpen[2], haOpen[3], haOpen[4], haOpen[5], haOpen[6]] , barmerge.gaps_off, barmerge.lookahead_on)
[monclose, _1monclose, _3monclose, _6monclose] = request.security(syminfo.tickerid, "M", [haClose, haClose[1], haClose[3], haClose[6]] , barmerge.gaps_off, barmerge.lookahead_on)
[dayclose1, _21dayclose, _63dayclose, _126dayclose, dayclose] = request.security(syminfo.tickerid, "1D", [haClose[1], haClose[21], haClose[63], haClose[126], haClose], barmerge.gaps_off, barmerge.lookahead_on)
[dayopen1, _21dayopen, _63dayopen, _126dayopen] = request.security(syminfo.tickerid, "1D", [haOpen[1], haOpen[21], haOpen[63], haOpen[126]], barmerge.gaps_off, barmerge.lookahead_on)


get_rate_of_return(price1, price2) =>
    return_ = (price1/price2 -1)*100
    return_

m0 = get_rate_of_return(monclose, monopen)
m1 = get_rate_of_return(_1monclose, _1monopen)
m2 = get_rate_of_return(monclose, _2monopen)
m3 = get_rate_of_return(_1monclose, _3monopen)
m4 = get_rate_of_return(monclose, _4monopen)
m5 = get_rate_of_return(monclose, _5monopen)
m6 = get_rate_of_return(_1monclose, _6monopen)
MS = (m1 + m3 + m6)/100
CS = (m0 + m2 + m5)/100

d1 = get_rate_of_return(dayclose1, _21dayopen)
d2 = get_rate_of_return(dayclose1, _63dayopen)
d3 = get_rate_of_return(dayclose1, _126dayopen)
DS = (d1 + d2 + d3)/100

//Last (DAILY)
lastd_s_avg1 = DS/3

lastd_Approximate1 = dayclose1*(1-lastd_s_avg1)

last_approx1_d21 = lastd_Approximate1 / _21dayopen-1
last_approx1_d63 = lastd_Approximate1 / _63dayopen-1
last_approx1_d126 = lastd_Approximate1 / _126dayopen-1

lastd_s_avg2 = (last_approx1_d21 + last_approx1_d63 + last_approx1_d126) / 3
lastd_approximate2 = (dayclose1)*(1-(lastd_s_avg1 + lastd_s_avg2))
lastd_price = lastd_approximate2

//plot(lastd_price,color = color.rgb(255, 255, 255, 14), title = "Last momentum threshold")

//Last

last_s_avg1 = MS/3

last_Approximate1 = _1monclose*(1-last_s_avg1)

last_approx1_m1 = last_Approximate1 / _1monopen-1
last_approx1_m3 = last_Approximate1 / _3monopen-1
last_approx1_m6 = last_Approximate1 / _6monopen-1

last_s_avg2 = (last_approx1_m1 + last_approx1_m3 + last_approx1_m6) / 3
last_approximate2 = (_1monclose)*(1-(last_s_avg1 + last_s_avg2))
last_price = last_approximate2
Scoring_price = _1monclose*(1-CS)

plot(last_price,color = color.rgb(255, 255, 255, 14), title = "Last momentum threshold")
//plot(Scoring_price,color = color.rgb(234, 0, 255, 14), title = "Last momentum threshold")

//Long based on month close and being the first trade of the month.

var int lastClosedMonth = -1
limit_longCondition = _1monclose > last_approximate2 and (lastClosedMonth == -1 or month(time) != lastClosedMonth)

// Long based on day close and being the first trade of the month.
limit_Dlongcondition = dayclose1 > lastd_approximate2 and (lastClosedMonth == -1 or month(time) != lastClosedMonth)

// Close trade based on day close

DCloseLongCondition = dayclose1<lastd_approximate2

//Old standard Trading rules
longCondition = _1monclose > Scoring_price
MCloseLongCondition = _1monclose<Scoring_price
shortCondition = CS < 0

if (longCondition)
    strategy.entry("Long", strategy.long)


if (strategy.position_size > 0 and MCloseLongCondition)
    strategy.close("Long")
    lastClosedMonth := month(time)

더 많은