상세 컨텐츠

본문 제목

나스닥 선물 숏 전략 만들기 (with 시그널메이커, 트레이딩뷰)

Trading

by jaryeonge 2025. 1. 17. 11:25

본문

오늘은 나스닥 선물 NQ의 숏 전략을 만들어보고자 한다. 나스닥이 상승하든 하락하든 꾸준한 수익을 거두기 위해서는 숏 포지션을 취하는 전략도 필요하다. 다만 롱 포지션을 취할 때와는 성격이 다소 다르므로 새로운 종목을 대하듯이 전략을 만들어나가야 한다.

 

롱과 숏의 차이점

EURUSD와 같이 환율을 다루는 선물과는 다르게 NQ의 상승추세와 하락추세는 모양새가 다르다. 내가 주로 다루는 타임프레임은 1시간봉인데 이를 기준으로 보면 상승추세는 주로 완만하게(2~30도) 형성되고, 하락추세는 급격하게(6~70도) 형성된다. 물론 모든 추세가 그렇다는 건 아니지만 경험상 대체적으로 그렇다.

 

NQ 1시간봉 캔들 차트

 

따라서 롱 포지션을 취할 때 사용했던 전 고점 돌파와 같이 꾸준하고 느린 추세에 적합한 전략은 숏 포지션과 맞지 않다. 빠르게 저점으로 돌파하듯이 형성되는 캔들이 많으므로 이를 최대한 포착하여 베팅하는 것이 중요하다.

 

core idea

위와 같은 숏 포지션 특징을 고려하여 전략을 짜기 위한 핵심 아이디어를 수립했다.

  • 상승추세를 유지하고 있을 때, 급격하게 하방 채널을 돌파하는 경우에 진입
    • 상승추세 정의
    • 하방 채널 돌파 정의
  • 1차 - 2차 - 3차로 분할하여 각각의 청산 라인 설정
    • 가격이 저점에서 얼마나 멀어지는 지를 척도로 1, 2, 3차 라인 설정

이를 구현하기 위해 Highest, Lowest, SMA, ATR를 사용할 것이다. "뭐가 이렇게 간단해? 다른 고급지표들은 안쓰나?" 하는 생각을 가질 수도 있다. 다양하고 어려운 지표들을 쓰는 것이 정답이 될 수도 있으나 경험상 오버피팅의 여지가 적은, 직관적이고 심플한 지표를 사용하여 경우에 돈을 버는 경우가 많았다. 따라서 요즘은 최대한 간단하게 전략을 짜려고 한다.

 

트레이딩뷰 (pine script)

먼저 트레이딩뷰를 통해 전략을 만드는 법을 알아보자

 

상승추세 정의: 80일 이동 평균선보다 5, 13, 30 이동평균선이 위에 있는 경우

SMA1_LEN = 5
SMA2_LEN = 13
SMA3_LEN = 30
SMA4_LEN = 80

sma1 = ta.sma(close, SMA1_LEN)
sma2 = ta.sma(close, SMA2_LEN)
sma3 = ta.sma(close, SMA3_LEN)
sma4 = ta.sma(close, SMA4_LEN)

condition = sma1 > sma4 and sma2 > sma4 and sma3 > sma4

 

하방 채널 돌파 정의: 전 종가가 "고점 - (atr * 상수)" 이하인 경우

GLOBAL_HIGEHST_LEN = 50
ENTRY_X = 6.8
ATR_LEN = 23

global_highest = ta.highest(close, GLOBAL_HIGEHST_LEN)
atr = ta.atr(ATR_LEN)

entry_line = global_highest - (atr * ENTRY_X)

condition = close[1] > entry_line

 

1, 2, 3차 청산 라인 설정

1차: 30일 이동 평균선보다 종가가 높은 경우

2차: 300일 이동 평균선보다 종가가 높은 경우

3차: 그 외의 경우

LOCAL_LOWEST_LEN = 10
ATRX = 2
TRAIL_X = 2
TRAIL_X2 = 2.5
TRAIL_X3 = 1

SMA3_LEN = 30
SMA5_LEN = 300

sma3 = ta.sma(close, SMA3_LEN)
sma5 = ta.sma(close, SMA5_LEN)

local_lowest = ta.lowest(close, LOCAL_LOWEST_LEN)
atr = ta.atr(ATR_LEN)

trail_line1 = local_lowest + (atr * ATRX * TRAIL_X)
trail_line2 = local_lowest + (atr * ATRX * TRAIL_X2)
trail_line3 = local_lowest + (atr * ATRX * TRAIL_X3)

if (sma3 > close)
    strategy.exit("short", stop = trail_line1)
else
    if (sma5 > close)
        strategy.exit("short", stop = trail_line2)
    else
        strategy.exit("short", stop = trail_line3)

 

코드 전문

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

//@version=6
strategy("NQ60 Short", overlay=true, fill_orders_on_standard_ohlc = true)

//Parameters
GLOBAL_HIGEHST_LEN = 50
LOCAL_LOWEST_LEN = 10

ENTRY_X = 6.8
ATRX = 2
TRAIL_X = 2
TRAIL_X2 = 2.5
TRAIL_X3 = 1

ATR_LEN = 23

SMA1_LEN = 5
SMA2_LEN = 13
SMA3_LEN = 30
SMA4_LEN = 80
SMA5_LEN = 300

//Variables
global_highest = ta.highest(close, GLOBAL_HIGEHST_LEN)

local_lowest = ta.lowest(close, LOCAL_LOWEST_LEN)

sma1 = ta.sma(close, SMA1_LEN)
sma2 = ta.sma(close, SMA2_LEN)
sma3 = ta.sma(close, SMA3_LEN)
sma4 = ta.sma(close, SMA4_LEN)
sma5 = ta.sma(close, SMA5_LEN)

atr = ta.atr(ATR_LEN)

trail_line1 = local_lowest + (atr * ATRX * TRAIL_X)
trail_line2 = local_lowest + (atr * ATRX * TRAIL_X2)
trail_line3 = local_lowest + (atr * ATRX * TRAIL_X3)

entry_line = global_highest - (atr * ENTRY_X)

//strategy
//진입 조건
short_entry_condition = sma1 > sma4 and sma2 > sma4 and sma3 > sma4 and close[1] > entry_line

if (short_entry_condition)
    strategy.entry("short", strategy.short, stop = entry_line)

// 청산 조건
if (sma3 > close)
    strategy.exit("short", stop = trail_line1)
else
    if (sma5 > close)
        strategy.exit("short", stop = trail_line2)
    else
        strategy.exit("short", stop = trail_line3)

// plotting
plot(entry_line, color = color.green)
plot(trail_line1, color = color.red)
plot(trail_line2, color = color.orange)
plot(trail_line3, color = color.yellow)

 

Best Cases (지속적인 하락추세 형성 or 급격하게 하락한 경우)

 

 

Worst Cases (횡보구간에서 역시 손해를 많이 본다...)

시그널메이커

참고용으로 시그널메이커 코드도 같이 정리해보았다. 트레이딩뷰 프리미엄 유저가 아니라면 조회할 수 있는 데이터가 한정적이기 때문에 시그널메이커에서 백테스를 해야 한다. 실제로 거래를 해야하는 플랫폼은 시그널메이커이기 때문에 ideation하기 편한 트레이딩뷰에서 전략을 최초로 구성해보고 최종 점검은 시그널메이커에서 하는 것을 추천한다.

/*-----------------------------------------------------------------------------------------------------------------------

* 본 전략적용 추천사항
* Data1 : NQ 선물 60분봉 차트
* Data2 : 없음.

*/

Params :
GlobalHighestParam(50),
LocalLowestParam(10),
EntryX(6.8),
ATRX(2),
TrailX(2),
TrailX2(2.4),
TrailX3(1),
ATRParam(23),
Sma1Param(5),
Sma2Param(13),
Sma3Param(30),
Sma4Param(80),
Sma5Param(300);

Vars : 
GlobalHighest(0),
LocalLowest(0),
TrailLine1(0),
TrailLine2(0),
TrailLine3(0),
EntryLine(0),
Sma1(0),
Sma2(0),
Sma3(0),
Sma4(0),
Sma5(0),
ShortCondition(False);

GlobalHighest = Highest(C, GlobalHighestParam);
LocalLowest = Lowest(C, LocalLowestParam);

Sma1 = Sma(C, Sma1Param);
Sma2 = Sma(C, Sma2Param);
Sma3 = Sma(C, Sma3Param);
Sma4 = Sma(C, Sma4Param);
Sma5 = Sma(C, Sma5Param);

TrailLine1 = LocalLowest + (ATR(ATRParam) * ATRX * TrailX1);
TrailLine2 = LocalLowest + (ATR(ATRParam) * ATRX * TrailX2);
TrailLine3 = LocalLowest + (ATR(ATRParam) * ATRX * TrailX3);

EntryLine = GlobalHighest - (ATR(ATRParam) * EntryX);

ShortCondition = Sma1 > Sma4 And Sma2 > Sma4 And Sma3 > Sma4 And C[1] > EntryLine;

/* 매도진입 */
If CurrentEntries = 0 And ShortCondition Then Sell("Short", AtStop, EntryLine, 3);

/* 단계별 매도 청산 */
If Sma3 > C Then 
Begin
ExitShort ("ExitShort1", AtStop, TrailLine1, DEF, 3);
End
Else
Begin
If Sma5 > C Then ("ExitShort2", AtStop, TrailLine2, DEF, 3)
Else ExitShort ExitShort ("ExitShort3", AtStop, TrailLine3, DEF, 3);
End;

관련글 더보기