
1. 개요
듀얼 이동평균(Dual Moving Average) 은 가장 고전적이고 기본적인 추세 추종 전략 중 하나입니다.
이 전략은 두 개의 단순 이동평균(단기 ma_fast, 장기 ma_slow) 사이의 교차 관계만을 사용합니다.
- 단기 MA가 장기 MA를 아래에서 위로 돌파 → 골든 크로스 → 매수 신호 생성
- 단기 MA가 장기 MA를 위에서 아래로 이탈 → 데드 크로스 → 매도 신호 생성
PulseForce에서 dual_moving_avg 전략은 미니멀하지만 고도로 표준화된 추세 추종 구현입니다.
- 1분 봉 사용 (
timeframe = "1m") - 신호 조건으로 듀얼 이동평균 + 거래량 > 0 만 사용
- 청산 로직은 통합 리스크 프레임워크를 따름: “매도 신호 + 일일 SL/TP + 하드 SL/TP”
ma_fast / ma_slow / daily_* / force_*등의 파라미터를 대상으로 HyperOpt 최적화 지원- 모든 전략 파라미터는 PulseForce 앱에서 시각적으로 설정 가능
ma_crossover가 더 많은 추세 필터와 변동성 조정을 포함한 “강화 버전”이라면,dual_moving_avg는 구조가 매우 단순하고 해석이 쉬운 더 순수한 이동평균 교차 버전입니다.
2. 기원과 포지셔닝
듀얼 이동평균 교차 전략은 초기 기술적 분석까지 거슬러 올라갑니다.
컴퓨터와 시스템 트레이딩의 등장과 함께, 이 전략은 추세 추종 전략의 “Hello World”가 되었습니다.
- 초기 CTA / 추세 추종 펀드
이동평균 교차를 핵심 추세 신호로 폭넓게 사용 - 현대 퀀트 시스템
듀얼 이동평균은 여전히 추세 추종의 핵심 기반으로, 다요인 모델, CTA 시스템, 추세 필터 등에 내장됨 - 교육 및 연구
초보자 교육이든 학술적 논의든, 듀얼 MA는 거의 항상 추세 전략의 기본 예시로 사용됨
PulseForce 내에서 dual_moving_avg의 포지셔닝은 다음과 같습니다.
“구조적으로 매우 깔끔한 베이스라인(기준) 추세 전략.”
MA Crossover, Momentum, MACD Trend 등 더 복잡한 전략과의 수익률, 드로우다운, 거래 스타일 비교에 활용됩니다.
3. 이 전략은 어떤 문제를 해결하는가?
듀얼 이동평균 전략은 핵심적으로 다음 세 가지 질문을 다룹니다.
추세 방향 변화는 어떻게 단순하고 직접적으로 식별할 것인가?
→ 단기 MA와 장기 MA의 상대 위치 및 교차를 통해 강세/약세 추세 상태를 판단합니다.단일 캔들이나 국소 패턴에 대한 과도한 의존은 어떻게 줄일 것인가?
→ 이동평균은 가격을 평활화하여 고빈도 노이즈 및 비정상 단일 캔들의 영향을 줄입니다.조정 가능한(tunable) 추세 추종 전략은 어떻게 만들 것인가?
→ma_fast / ma_slow를 조정하면, 더 빠르게 반응하는 변형 또는 더 안정적인 변형을 쉽게 만들 수 있습니다.
4. 핵심 지표와 신호 로직
4.1 지표 계산
이 전략은 단순 이동평균(SMA) 을 사용합니다.
f = int(self._val(self.ma_fast))
s = int(self._val(self.ma_slow))
# Simple moving averages
df["ma_fast"] = ta.SMA(df, timeperiod=f)
df["ma_slow"] = ta.SMA(df, timeperiod=s)
필수 기본 데이터:
close / open / high / low: 정제를 위해 모두 전방 채움(ffill)volume: 누락 데이터로 인한 신호 오류를 피하기 위해 0으로 채움
4.2 매수 로직: 골든 크로스
def populate_buy_trend(self, dataframe: DataFrame, metadata: Dict) -> DataFrame:
df = dataframe.copy()
cond = (
(df["ma_fast"].shift(1) < df["ma_slow"].shift(1)) & # Previous bar: short MA below long MA
(df["ma_fast"] > df["ma_slow"]) & # Current bar: short MA crosses above long MA → Golden Cross
(df["volume"] > 0) # Must have volume
)
df.loc[:, "buy"] = 0
df.loc[cond, "buy"] = 1
return df
의미:
- 단순히
>여부를 보는 것이 아니라, “단기 MA가 장기 MA 아래에 있다가 위로 올라서는 상태 변화” 가 반드시 발생해야 합니다. → 반복 트리거를 방지합니다. - RSI, 돌파, 변동성 필터 등을 추가하지 않은 가장 순수한 골든 크로스 정의를 사용합니다. → 베이스라인 전략으로 이상적입니다.
volume > 0는 거래 정지 종목이나 비정상 데이터를 걸러내기 위한 조건입니다.
4.3 매도 신호 레이어: 데드 크로스
전략은 정적 메서드 _has_sell_signal 로 데드 크로스 발생 여부를 판단합니다.
@staticmethod
def _has_sell_signal(prev: Optional[pd.Series], curr: Optional[pd.Series]) -> bool:
try:
if prev is None or curr is None:
return False
return (float(prev.get("ma_fast", np.nan)) > float(prev.get("ma_slow", np.nan))) and \
(float(curr.get("ma_fast", np.nan)) < float(curr.get("ma_slow", np.nan)))
except Exception:
return False
조건:
- 이전 봉:
ma_fast > ma_slow(단기 추세가 장기 추세 위) - 현재 봉:
ma_fast < ma_slow(단기 추세가 장기 MA 아래로 이탈)
두 조건이 모두 충족되면 데드 크로스(강세 → 약세 전환) 로 간주됩니다.
다만 즉시 청산하지는 않으며, 이 신호를 custom_exit 에 전달한 뒤 SL/TP 로직에 따라 청산 여부를 결정합니다.
5. 통합 청산 로직: 매도 신호 + SL/TP
custom_exit 에서 dual_moving_avg 는 PulseForce 표준 리스크 제어 프로세스를 완전히 구현합니다.
def custom_exit(
self,
pair: str,
trade: Trade,
current_time: datetime,
current_rate: float,
current_profit: float,
**kwargs,
):
# ① Hard thresholds first (Force SL/TP)
if current_profit <= -self.force_stop_loss.value:
return "hard_sl"
if current_profit >= self.force_take_profit.value:
return "hard_tp"
# ② Fetch prev/curr rows and check for Death Cross
df = self._get_analyzed_df(pair)
if df is None or df.empty:
return None
prev, curr = self._get_prev_curr_rows(df, current_time)
if not self._has_sell_signal(prev, curr):
return None
# ③ Only after the sell signal layer occurs, apply daily SL/TP to decide the actual exit
th = self._pick_trend_thresholds()
sl = th["sl"]
tp = th["tp"]
if current_profit <= -sl:
return "sl_signal"
if current_profit >= tp:
return "tp_signal"
return None
이는 세 가지 보호 레이어로 요약할 수 있습니다.
Force SL/TP(하드 임계값)
- 모든 신호를 무시하고, 미실현 손익이 하드 임계값에 도달하면 즉시 청산합니다.
- 급락/급등(플래시 크래시, 스파이크 등)과 같은 극단적 시장 움직임으로부터 보호하기 위함입니다.
매도 신호 레이어(데드 크로스)
- 데드 크로스가 없으면, 일일 SL/TP만으로는 청산하지 않습니다.
- “추세가 유지되는 동안은 최대한 보유한다”는 아이디어를 반영합니다.
일일 SL/TP(추세 기반 청산)
- 데드 크로스가 발생한 이후에만
daily_stop_loss / daily_take_profit을 적용해 실제 청산 여부를 결정합니다. - 이는 순수 PnL 기반 청산보다 추세 추종 논리에 더 가깝습니다.
- 데드 크로스가 발생한 이후에만
6. PulseForce 파라미터 및 HyperOpt 최적화
PulseForce 앱(Apple App Store 및 Google Play 제공)은 트레이딩 작업, 백테스트, 하이퍼파라미터 최적화를 위한 시각적 설정 UI를 제공하여 전략을 완전히 파라미터화할 수 있습니다.
Backtest 설정 UI:
HyperOpt 설정 UI:
다음 파라미터들은 종목별로 최적의 조합을 찾기 위해 최적화 가능합니다.
6.1 기본 파라미터
이 파라미터들은 추세 신호 자체의 형태를 결정합니다.
| Param Key | Name | Description | Optimizable | Suggested initial search range (otp_init_min ~ otp_init_max) |
|---|---|---|---|---|
ma_fast |
빠른 MA 기간 | 단기 MA 기간; 값이 작을수록 더 빠르게 반응 | ✅ | 8 ~ 25 |
ma_slow |
느린 MA 기간 | 장기 MA 기간; 값이 클수록 더 부드러움 | ✅ | 40 ~ 90 |
코드에서는 HyperOpt 공간에 다음과 같이 매핑됩니다.
ma_fast = IntParameter(3, 100, default=10, space="buy", optimize=True)
ma_slow = IntParameter(5, 200, default=30, space="buy", optimize=True)
PulseForce 내 HyperOpt를 사용하면 종목별로 가장 적합한 단기/장기 MA 기간을 자동으로 탐색할 수 있습니다.
6.2 자본 배분(Capital Allocation)
자본 배분 파라미터는 다른 전략들과 일관된 구조를 유지합니다.
전략이 사용할 최대 자금과, 추세 상태별 노출 규모를 제어합니다. 기본적으로는 최적화 대상이 아니지만 UI에서 조정할 수 있습니다.
| Param Key | Description |
|---|---|
max_funds_allowed_using |
이 전략에 할당 가능한 최대 자본 |
allowable_funds_neutral |
중립(Neutral) 구간 자본 배분 |
allowable_funds_uptrend |
상승 추세(Uptrend) 구간 자본 배분 |
allowable_funds_downtrend |
하락 추세(Downtrend) 구간 자본 배분 |
6.3 손절(Stop Loss) 파라미터
손절 파라미터는 HyperOpt 최적화를 지원합니다.
| Param Key | Name | Meaning | Optimizable | Suggested Range |
|---|---|---|---|---|
force_stop_loss |
강제 손절 비율 | 하드 손절 임계값 | ✅ | 0.005 ~ 0.30 |
daily_stop_loss |
일일 손절 비율 | 데드 크로스(매도 신호) 이후에만 활성화되는 일일 손절 | ✅ | 0.01 ~ 0.3 |
6.4 익절(Take Profit) 파라미터
익절 파라미터 또한 완전히 최적화 가능합니다.
| Param Key | Name | Meaning | Optimizable | Suggested Range |
|---|---|---|---|---|
force_take_profit |
강제 익절 비율 | 하드 익절 임계값 | ✅ | 0.005 ~ 0.30 |
daily_take_profit |
일일 익절 비율 | 매도 신호 이후에만 활성화되는 일일 익절 | ✅ | 0.01 ~ 0.3 |
하드 TP와 일일 TP를 결합하면 다층형 이익 보호 메커니즘을 구성할 수 있습니다.
7. Dual MA를 언제 사용하면 좋은가?
7.1 가장 적합한 시나리오
- 뚜렷한 추세 특성이 있는 자산:
예) 미국 성장주, 추세형 ETF, 주요 지수, 변동성이 큰 암호화폐 - 단순한 규칙 + 깔끔한 신호를 선호하는 사용자:
여러 지표에 의존하지 않아 과최적화(overfitting) 위험이 낮음 - 베이스라인 전략이 필요한 연구/비교 환경:
MA Crossover, MACD, Momentum 등의 초과 수익 비교에 활용
7.2 덜 적합한 시나리오
- 장기간 박스권에 머물며 잦은 휩쏘(whipsaw)가 발생하는 종목
- 초단기 랜덤 움직임처럼 고주파 노이즈가 매우 강한 환경
- 매우 정밀한 진입이 필요한 경우(듀얼 MA는 “추세 초입”보다는 “추세 중간 구간”을 더 잘 잡는 편)
8. 강점과 약점
강점
- 구조가 매우 단순하고 투명하여 해석 가능성이 높음
- 파라미터 수가 적음 → HyperOpt 최적화가 더 안정적이고 과최적화에 덜 취약
- 다음 목적에 이상적:
- 베이스라인(벤치마크) 전략
- 교육/온보딩
- 더 복잡한 전략과의 비교
- PulseForce 리스크 프레임워크를 완전히 준수:
- 하드 SL/TP 임계값
- 일일 SL/TP
- 통합
custom_exit프로세스
약점
- RSI, 거래량, 변동성 등을 고려하지 않음 → 횡보/변동 장에서 민감해져 거짓 신호가 늘 수 있음
- 더 고급 추세 전략(예: AI 필터가 포함된 Momentum)과 비교하면 일부 종목에서 성능이 다소 열세일 수 있음
- 명시적 일일 추세 필터가 없음 → 매우 노이즈가 큰 환경에서는 추가 필터와의 결합이 필요할 수 있음
9. 요약
dual_moving_avg는 PulseForce 내에서 가장 순수하고 표준적인 듀얼 이동평균 교차 구현입니다.
- 단기/장기 MA의 골든 크로스 / 데드 크로스만으로 추세 신호 생성
- 하드 임계값 + 일일 손절/익절을 결합한 통합 리스크 프레임워크 적용
ma_fast / ma_slow / daily_* / force_*를 대상으로 HyperOpt 지원- UI 설정 + 백테스트 + 하이퍼최적화를 통해 사용자는 자신에게 맞는 듀얼 MA 스타일을 빠르게 구축 가능
특히 다음 용도로 적합합니다.
- 첫 번째 추세 추종 전략
- Momentum / MA Crossover / MACD Trend 등과 비교하기 위한 베이스라인
- PulseForce 파이프라인(전략 → 파라미터 → 리스크 → 백테스트 → HyperOpt)을 학습하기 위한 예시 전략
더 많은 전략과 최신 기능을 확인하려면:
👉 PulseForce 공식 웹사이트: https://www.hiforce.ai