퀀트머신의 기본 골격인 핀터스텔라 라이브러리 설치해보자
!pip install finterstellar

핀터스텔라 라이브러리를 이용해 애플(AAPL)의 주가를 가져와보자
get_price(symbol, start_date, end_date)
- symbol : 종목코드 (문자열 또는 리스트, 필수)
- start_date : 기간 시작 일자 (날짜, 생략 시 종료 일자 1년 전)
- end_date : 기간 종료 일자 (날짜, 생략 시 최즌 거래일)

import finterstellar as fs
df = fs.get_price('AAPL', start_date='2025-01-01', end_date='2025-12-31')
print(df)
가져온 데이터를 차트로 그려보자
draw_chart(df, left, right, log)
- df : 차트에 표시할 데이터 (데이터프레임, 필수)
- left : 왼쪽 y축에 표시할 값 (데이터프레임의 칼럼, 생략 가능)
- right : 오른쪽 y축에 표시할 값 (데이터프레임의 칼럼, 생략 가능)
- log : y축을 로그로 표시할지 여부 (True/False, 기본 False)

RSI(상대강도지수)
주식이나 코인 차트를 볼 때 자주 등장하는 RSI(Relative Strength Index, 상대강도지수)는 한마디로 “시장의 과열 정도를 알려주는 온도계”라고 이해하면 가장 쉽습니다. 사람들이 너무 많이 사서 가격이 비정상적으로 올랐는지(과매수), 아니면 너무 많이 팔아서 지나치게 떨어졌는지(과매도)를 0에서 100 사이의 숫자로 보여줍니다.
1. RSI를 보는 핵심 수치
보통 RSI는 14일간의 가격 변화를 기준으로 계산하며, 다음 두 가지 수치만 기억하면 됩니다.
- 70 이상 (과매수): “시장이 너무 뜨겁다!” 사람들이 너무 많이 샀으니 곧 가격이 떨어질 가능성이 높다는 신호입니다. (매도 검토)
- 30 이하 (과매도): “시장이 너무 차갑다!” 사람들이 너무 많이 팔았으니 곧 반등할 가능성이 높다는 신호입니다. (매수 검토)
- 50 (기준선): 상승세와 하락세가 팽팽한 지점입니다. 50 위로 올라가면 상승 힘이 더 세다고 봅니다.
2. RSI는 어떻게 계산되나요? (핵심 원리)
수식은 복잡해 보이지만 원리는 단순합니다.
쉽게 풀어서 설명하면:
- 최근 14일 동안 오른 날의 상승분만 다 더해서 평균을 냅니다.
- 반대로 떨어진 날의 하락분만 다 더해서 평균을 냅니다.
- 상승 힘이 하락 힘보다 얼마나 강한지를 비율로 따져서 0~100 사이의 점수를 매기는 것입니다.
3. RSI 활용 시 주의할 점
RSI는 매우 유용하지만, 맹신해서는 안 되는 이유가 있습니다.
- 강한 추세에서의 함정: 주가가 폭등하는 불장(강세장)에서는 RSI가 70을 넘어도 계속 상승할 수 있습니다. 반대로 폭락장에서는 30 밑에서 한참을 머물기도 합니다.
- 다이버전스(Divergence) 확인: 주가는 오르는데 RSI 지수는 낮아진다면, 이는 상승 힘이 빠지고 있다는 아주 강력한 하락 예고 신호가 될 수 있습니다.
💡 요약하자면
RSI는 “지금 이 가격이 심리적으로 과한가?”를 판단하는 보조 도구입니다. 70에 닿았다고 바로 팔기보다는, 거래량이나 다른 지표를 함께 보며 ‘과열’ 상태임을 인지하는 용도로 쓰시는 것이 좋습니다.
다이버전스(Divergence)
다이버전스(Divergence)는 ‘갈라지다’라는 뜻으로, 주식이나 코인의 ‘실제 가격’과 ‘보조지표(RSI 등)’의 움직임이 서로 반대로 가는 현상을 말합니다.
보통 주가가 올라가면 RSI 지수도 같이 올라가는 게 정상이지만, 주가는 올라가는데 RSI 지표는 오히려 내려가는 상황이 발생합니다. 이는 “가격은 억지로 올리고 있지만, 상승하는 힘(에너지)은 이미 빠지고 있다”는 강력한 추세 전환 신호로 해석합니다.
크게 두 가지 종류가 있습니다.
1. 하락 다이버전스 (Bearish Divergence)
- 상황: 주가는 전고점을 높이며 상승하고 있는데, RSI 지수는 전고점보다 낮아질 때.
- 의미: “가격은 올랐지만 매수세는 약해졌다.” 곧 하락으로 반전될 가능성이 높다는 강력한 경고입니다.
- 매매 전략: 이 신호가 나오면 수익 실현(매도)을 하거나 하락에 대비해야 합니다.
2. 상승 다이버전스 (Bullish Divergence)
- 상황: 주가는 저점을 더 낮추며 내려가고 있는데, RSI 지수는 저점이 오히려 높아질 때.
- 의미: “가격은 내려갔지만 하락하는 힘은 줄어들었다.” 곧 상승으로 반전될 가능성이 높다는 신호입니다.
- 매매 전략: 저점 매수(분할 매수)를 고려해 볼 수 있는 좋은 타이밍입니다.
💡 왜 다이버전스가 중요한가요?
다이버전스는 보조지표 중에서도 ‘가장 신뢰도가 높은 신호’ 중 하나로 꼽힙니다.
- 가짜 상승/하락 구별: 세력들이 가격을 억지로 끌어올리거나 내릴 때, 지표는 속이기 어렵기 때문에 ‘진짜 추세’를 파악하는 데 도움을 줍니다.
- 추세의 끝을 예고: 현재 진행 중인 상승세나 하락세가 곧 끝날 것임을 미리 암시해 줍니다.
⚠️ 주의사항
- 확인 후 진입: 다이버전스가 나타났다고 해서 바로 가격이 꺾이지 않을 때도 있습니다. (지표가 꺾인 채로 가격이 횡보하는 경우)
- 다른 지표와 병행: 거래량(Volume)이나 MACD 같은 다른 지표와 함께 보면 훨씬 정확도가 높아집니다.
MACD
주식이나 코인 차트에서 RSI만큼이나 자주 쓰이는 MACD(Moving Average Convergence Divergence)는 우리말로 ‘이동평균 수렴확산 지수’라고 부릅니다. RSI가 ‘현재 가격의 과열 상태’를 점수로 보여준다면, MACD는 ‘추세가 지금 어느 방향으로, 얼마나 강하게 달리고 있는가’를 보여주는 지표입니다.
1. MACD의 3가지 구성 요소
MACD 지표를 켜면 보통 두 개의 선과 막대그래프가 보입니다.
- MACD선 : 단기 이동평균선(12일)과 장기 이동평균선(26일)의 차이입니다. “지금 가격이 평소보다 얼마나 빨리 변하고 있는가”를 보여줍니다.
- 시그널선 : MACD선을 다시 9일 동안 평균 낸 선입니다. MACD선의 움직임을 부드럽게 만들어 추세를 더 잘 보이게 합니다.
- 히스토그램 : MACD선과 시그널선의 차이를 막대로 그린 것입니다. 막대가 길어지면 추세가 강해지는 것이고, 짧아지면 힘이 빠지고 있다는 뜻입니다.

2. 차트 속 주요 신호 보는 법
- 골든크로스 (Golden Cross): 위 이미지에서 MACD선(파란색)이 시그널선(주황색/빨간색)을 아래에서 위로 뚫고 올라가는 지점을 보세요. 이때 아래 막대그래프(히스토그램)도 0 위로 올라오기 시작하며, 실제 주가(캔들)도 상승세로 돌아서는 것을 확인할 수 있습니다.
- 데드크로스 (Dead Cross): 반대로 MACD선이 시그널선을 위에서 아래로 뚫고 내려가는 지점입니다. 상승 힘이 다했다는 신호이며, 이후 주가가 하락하거나 횡보하는 모습을 보입니다.
- 히스토그램 (막대): 막대가 0선 위에 있을 때는 상승 에너지가, 0선 아래에 있을 때는 하락 에너지가 강한 상태입니다. 막대의 길이가 가장 길어졌다가 줄어들기 시작하면 “곧 추세가 꺾이겠구나”라고 미리 짐작할 수 있습니다.
실전 팁: 실제 매매를 하실 때는 MACD 골든크로스가 ‘0선’보다 낮은 곳에서 발생할 때가 바닥권 매수 기회인 경우가 많습니다. 반대로 0선보다 한참 높은 곳에서 데드크로스가 나면 고점 신호일 확률이 높으니 주의 깊게 살펴보세요!
RSI를 이용해 애플의 주가를 분석해보자
rsi(df, w) : RSI 값을 산출한다.
- df : 주가 데이터 (데이터프레임, 필수)
- w : RSI 계산에 이용할 데이터 기간, w=20이면 20일 RSI 산출. (자연수, 생략 시 20)

fs.rsi(df, w=14)
fs.draw_chart(df, left='rsi', right='AAPL')
백테스팅
- 백테스팅(Backtesting) : 내 매매 전략을 과거의 데이터에 대입해 보는 가상 시뮬레이션
- 블래시(BLASH) : But Low And Sell High
- 스토캐스틱(Stochastic) : RSI와 형제 같은 지표지만, 훨씬 더 ‘성격이 급하고 예민한’ 지표입니다. “최근 가격 범위 안에서 현재 가격이 어느 위치(높은지 낮은지)에 있는가?”
indicator_to_signal(df, factor, buy, sell) : 주가 데이터, 투자 지표, 매수 기준값, 매도 기준값을 입력하면 이에 따른 트레이딩 시그널을 생성한다.
- df : 주가 데이터 (데이터프레임, 필수)
- factor : 투자 판단을 위한 지표, RSI, Stochastic 등 (문자열, 필수)
- buy : 매수 기준값 (숫자, 필수)
- sell : 매도 기준값 (숫자, 필수)

position(df) : 트레이딩 시그널 데이터를 입력하면 이에 따른 포지션을 산출한다.
- df : 트레이딩 시그널 데이터 (데이터프레임, 필수)

evaluate(df, cost) : 포지션 데이터를 입력하면 수익률을 산출한다.
- df : 포지션 데이터 (데이터프레임, 필수)
- cost : 매매 비용, 소수로 입력, 비용이 1%라면 0.01 입력 (소수, 기본값 0.001)

fs.evaluate(df, cost=.001)
fs.draw_chart(df, left='acc_rtn_dp', right='AAPL')
- acc (Accumulated): 누적된
- rtn (Return): 수익률
- dp (Daily / Display / Deposit): 맥락상 Daily(일별) 또는 Display(표시용)를 의미하며, 종합하면 “일별 누적 수익률”을 뜻합니다.
즉, 이 변수는 “전략대로 매매했을 때 시간이 지남에 따라 내 자산이 얼마나 불어났는지를 나타내는 누적 수익률 곡선”입니다.
투자 성과분석
- 샤프 지수(Sharpe Ratio) : 퀀트 투자나 백테스팅 결과를 평가할 때 가장 중요하게 여기는 지표 중 하나. 한마디로 “위험을 1만큼 감수했을 때 얻는 수익이 얼마인가?”를 나타내는 ‘투자 가성비 지표’입니다. 단순히 수익률만 높은 것이 아니라, 얼마나 “안정적으로” 벌었는지를 측정합니다.
- 무위험이자율 : 위험이 전혀 없는 순수한 투자의 기대수익률로 정기 예금, 국채 등의 이자율 등이 해당한다.
performance(df, rf_rate) : 수익률 데이터를 입력하면 성과평가 결과를 반환한다.
- df : 포지션 데이터 (데이터프레임, 필수)
- rf_rate : 무위험이자율, 소수로 입력, 1% 라면 0.01 입력. (소수, 기본값 0.01)

1. 코드 결과 한 줄 해석
CAGR: 10.58%(연복리 수익률): 1년 동안 투자했을 때 기대할 수 있는 복리 수익률입니다. 자산이 매년 약 10.6%씩 불어난다는 뜻으로, 시중 금리보다는 높으나 시장 평균보다는 낮을 수 있습니다.Accumulated return: 9.68%(누적 수익률): 투자 기간(0.9년) 동안 실제로 얻은 총 수익률입니다. CAGR보다 낮은 이유는 투자 기간이 1년이 채 되지 않았기 때문입니다.Average return: 3.50%(평균 수익률): 각 거래당 발생한 수익률의 평균치입니다.Benchmark return: 22.33%(비교 지수 수익률): 같은 기간 시장(예: 코스피, S&P500 등)을 그냥 보유했을 때의 수익률입니다. 내 전략보다 시장 수익률이 2배 이상 높았습니다.Number of trades: 3(매매 횟수): 총 3번의 진입과 청산이 있었습니다.Number of win: 2(익절 횟수): 3번의 거래 중 수익을 보고 나온 거래가 2번입니다.Hit ratio: 66.67%(승률): 전체 거래 중 수익을 낸 비율입니다 (2 \ 3 = 66.67%).Investment period: 0.9yrs(투자 기간): 백테스트 또는 실거래가 진행된 기간이 약 11개월임을 나타냅니다.Sharpe ratio: 0.28(샤프 지수): 위험(변동성) 대비 수익 효율성을 나타냅니다. 1.0 이상이면 우수하다고 보는데, 0.28은 위험을 감수한 것치고 수익이 만족스럽지 않음을 의미합니다.MDD: -24.20%(최대 낙폭): 투자 기간 중 최고점 대비 가장 많이 하락했을 때의 수치입니다. 내 자산이 한때 -24%까지 깨졌음을 의미합니다.Benchmark MDD: -30.22%(시장 최대 낙폭): 같은 기간 시장 지수는 최고점 대비 -30%까지 하락했습니다.
2. 최종 결론 정리
“시장은 이기지 못했지만, 방어력은 확인된 ‘로우 리스크-로우 리턴’형 전략”
- 시장 대비 성적 (Underperform): 벤치마크가 22% 오를 때 10% 수익에 그쳤습니다. 시장 상승기에는 다소 소외되는 전략일 수 있습니다.
- 리스크 관리: 시장이 -30% 하락할 때 -24%로 방어했습니다. 하락장에서는 시장보다 조금 더 안전하게 자산을 지켰습니다.
- 데이터의 한계: 매매 횟수가 3회로 너무 적고 기간이 1년 미만입니다. 현재의 66% 승률은 통계적으로 믿기 어려우며, 운의 요소가 크게 작용했을 가능성이 높습니다.
1행의 buy=60, sell=40 부분만 변경



결론부터 말하면
AAPL 구간에서는 RSI가 ‘추세 추종 지표’가 아니라 ‘역추세(Mean Reversion) 지표’로 작동했기 때문
그래서
buy=60, sell=40→ RSI 높을 때 사고, 낮을 때 판 전략(추세 추종)buy=40, sell=60→ RSI 낮을 때 사고, 높을 때 판 전략(역추세)
이 중에서 역추세가 더 잘 먹힌 시장 구간이었던 것!
RSI의 원래 의도 vs 실제 시장
RSI는 원래 이렇게 해석합니다
| RSI 값 | 일반적 해석 |
|---|---|
| 70 이상 | 과매수 |
| 30 이하 | 과매도 |
👉 “너무 올랐으면 떨어지고, 너무 떨어졌으면 오른다”
즉 평균회귀(Mean Reversion) 전제
buy=60
sell=40
이건 사실상
RSI가 올라가는 중이니 더 오른다 → 추세 추종 전략
왜 반대로 했더니 수익이 좋아졌나?
1️⃣ AAPL은 장기적으로 “완만한 우상향 + 잦은 되돌림” 구조
AAPL 같은 대형주는:
- 급등 → 조정
- 급락 → 반등
이 패턴이 엄청 자주 반복된다.
그래서:
- RSI 60 이상 → 이미 단기 고점 근처
- RSI 40 이하 → 단기 과매도 구간
👉 이 구간에서 사고팔면 평균회귀 수익이 잘 남는다.
2️⃣ RSI는 추세장보다 횡보/완만한 추세에서 강함
RSI는 이런 시장에서 약하다:
- 강한 상승 추세 (RSI가 60~80에 오래 머묾)
- 강한 하락 추세 (20~40에서 머묾)
하지만 AAPL 데이터 구간을 보면:
- RSI가 중앙값(40~60)로 자주 회귀
- 극단값 지속 시간이 짧음
👉 이건 역추세 전략 최적 환경
3️⃣ 수수료(cost=.001) 때문에 더 차이가 커짐
추세 추종 전략은:
- 잦은 추격 매수
- 고점·저점 근처에서 잦은 포지션 변경
👉 수수료에 더 취약
반면 역추세 전략은:
- 비교적 가격 변동폭이 큰 구간에서 진입
- 기대수익 대비 비용 비율이 좋음
✔ RSI는 기본적으로 역추세 지표
✔ buy < sell 이면 평균회귀 전략
✔ buy > sell 이면 추세추종 전략
✔ AAPL + 해당 기간 = 평균회귀가 유리
✔ 그래서 buy/sell을 반대로 했더니 수익률이 좋아진 것
한 단계 더 가면 이렇게 실험
for b, s in [(30,70),(40,60),(45,55)]:
fs.indicator_to_signal(df, 'rsi', buy=b, sell=s)
fs.position(df)
fs.evaluate(df, cost=.001)
print(b, s, df['acc_rtn_dp'].iloc[-1])
👉 RSI 폭이 좁아질수록 트레이드 수↑, 비용↑
👉 어디가 최적점인지 직접 보게 된다!
