cs

Intro. 

작년에는 진짜 하루하루 주식보고 주가보고 분석하고 했었는데,

주식 해보려고 대학교때 부전공도 Finance 골라서 한학기 늦게 졸업하고, 

파이썬, 데이터 분석, 데이터 사이언스 쪽으로 공부하려고 했던 것들도 모두 주식이 시초이고 시작이였는데,

지금은 그저 그냥 먹는게 행복한 미쳐버린 직장인이 되어버렸다. 

아시는 사람들은 알 수 도 있는 포레스트 검프에 옥의티가 있는데, 편지가 도착한 날짜를 보면 1975년 9월 애플에서 편지가 왔지만, 사실 애플은 1976년 4월에 창립되었다. 중위님 어디다가 투자하신겁니까?

 



퀀트 다시 돌려보고싶은데, 슬슬 주식도 보고 이것저것 투자할 때가 왔는데,,  했던 참에 캐글에 마침 또 끄적일게 생겼따. 

 

Apple Stock Data and Key Affiliated Companies

데이터 설명

  • 데이터셋
    깔끔하게 정리가 된 애플 주식의 주가 데이터가 들어있다. 날짜와 시가 종가 볼륨 뭐 이것저것 간단한 컬럼들이 있지만, 귀찮기도 하고 간단하게 그냥 초간단으로 분석해보려고한다. 그리고 애플과 관련된 회사들의 주가 데이터도 함께 첨부가 되어있다. (그냥 하나로 이쁘게 합쳐주지 왜 굳이 나눠놨냥.. )
 

Apple Stock Data and Key Affiliated Companies

Daily stock data for Apple Inc. and key affiliates, for financial analysis.

www.kaggle.com

 

  • 나의 목적:역시나 간단하게 그냥 주가 한번 쓱 보고, 퀀트분석에서도 그냥 초간단으로 계산 가능한 두개의 지표를 통해서 비교하고 수익률도 함 볼꺼다. 그리고 경제 이벤트 상황에 따라 어떻게 주가의 전후 변동이 있었는지 간략하게 볼거다. 다시말한다 초간단버젼으로 볼거다. 귀찮아.

 

EDA

Trend

# Apple 
Apple_df['Date'] = pd.to_datetime(Apple_df['Date'])
Apple_df = Apple_df.sort_values('Date')

# visualization for apple
fig = go.Figure()

# Based on Adjusted Close 
fig.add_trace(go.Scatter(x=Apple_df['Date'], y=Apple_df['Adj Close'], 
                         mode='lines', name='Apple Adj Close'))

fig.update_layout(
    title="Apple Adjusted Close Price Over Time",
    xaxis_title="Date",
    yaxis_title="Adjusted Close Price",
    template="plotly_white"
)

fig.show()

캐글에 코드를 동적 시각화로 tistory에 가지고오려고하면 계속 깨진다..ㅠ

멀리서 볼때 행복한 애플 주가의 흐름이다. 

 

창립 이후부터 그냥 미친 우상향 곡선이다. 

 

코로나때 보이는 미친 하락이 아니라면 크게 멀리서볼땐 아름다워보인다. 

(삼성 뭐하세요?) 

 

 

Quant: Moving Average vs. Momentum

# Moving Avg (S: 20days, L: 120days)
Apple_df['MA20'] = Apple_df['Adj Close'].rolling(window=20).mean()
Apple_df['MA120'] = Apple_df['Adj Close'].rolling(window=120).mean()

# Momentum (14days)
Apple_df['Momentum_14'] = Apple_df['Adj Close'].diff(14)

# Moving Avg Cross (MA20 < MA120, MA20 > MA120 )
Apple_df['MA_Signal'] = 0
Apple_df['Prev_MA20'] = Apple_df['MA20'].shift(1)
Apple_df['Prev_MA120'] = Apple_df['MA120'].shift(1)

Apple_df.loc[(Apple_df['MA20'] > Apple_df['MA120']) & (Apple_df['Prev_MA20'] <= Apple_df['Prev_MA120']), 'MA_Signal'] = 1  
Apple_df.loc[(Apple_df['MA20'] < Apple_df['MA120']) & (Apple_df['Prev_MA20'] >= Apple_df['Prev_MA120']), 'MA_Signal'] = -1 

# Momentum cross (before momentum < 0, currunt momentum > 0 )
Apple_df['Momentum_Signal'] = 0
Apple_df['Prev_Momentum'] = Apple_df['Momentum_14'].shift(1)

Apple_df.loc[(Apple_df['Momentum_14'] > 0) & (Apple_df['Prev_Momentum'] <= 0), 'Momentum_Signal'] = 1  
Apple_df.loc[(Apple_df['Momentum_14'] < 0) & (Apple_df['Prev_Momentum'] >= 0), 'Momentum_Signal'] = -1 

# calculating returns of MA
Apple_df['MA_Strategy_Returns'] = Apple_df['Adj Close'].pct_change() * Apple_df['MA_Signal'].shift(1)

# calculating returns of Momentum
Apple_df['Momentum_Strategy_Returns'] = Apple_df['Adj Close'].pct_change() * Apple_df['Momentum_Signal'].shift(1)

# Cumulative Returns 
Apple_df['MA_Cumulative_Returns'] = (1 + Apple_df['MA_Strategy_Returns']).cumprod()
Apple_df['Momentum_Cumulative_Returns'] = (1 + Apple_df['Momentum_Strategy_Returns']).cumprod()


Apple_quant_df = Apple_df[['Date', 'Adj Close', 'MA20', 'MA120', 'Momentum_14', 'MA_Signal', 'Momentum_Signal', 'MA_Strategy_Returns', 'Momentum_Strategy_Returns', 'MA_Cumulative_Returns', 'Momentum_Cumulative_Returns']]
Apple_quant_df

 

가끔 서점가면, 무슨 이평선 투자 분석이 만능인것처럼 써놓은 책들이 있는데,,, 

 

그렇게 말하지 마셔요 제발, 투자지표가 세상에 몇개인데, 만능키라는거 없습니다. 

 

상황과, 주식과 환경과 모든 변수가 다 동일할 수 없지 않습니까? 

 

암튼,, 

 

그래서 이평선 투자를 가지고 온건 아니지만, 일단 이평선과 내가 조금 선호하는 모멘텀 전략으로 한번 비교를 해보고 하나의 퀀트 투자 방식을 조금 더 딥하게 보려고한다.

이미지가 짤려서 모든 컬럼을 보여주긴 힘들지만, 

 

우리게 중요한건 뭐다? 수익률이다. 

 

보시면 모멘텀의 누적수익률이 10.36이 나왔다. 1000%라는 뜻이다. 10배이죠. 

 

 

조금 더 이쁘게 함 봐보쟈.

fig = go.Figure()

# MA
fig.add_trace(go.Scatter(x=Apple_df['Date'], y=Apple_df['MA_Cumulative_Returns'], mode='lines', name='MA Cumulative Returns'))

# Momentum
fig.add_trace(go.Scatter(x=Apple_df['Date'], y=Apple_df['Momentum_Cumulative_Returns'], mode='lines', name='Momentum Cumulative Returns'))


fig.update_layout(
    title="Cumulative Returns: Moving Average Cross vs Momentum Cross",
    xaxis_title="Date",
    yaxis_title="Cumulative Returns",
    template="plotly_white"
)

fig.show()

나도 저런 수익률 그리는 주식 10만주정도 있음 좋겠다. 

 

저것만 슥 보면, 모멘텀 투자가 완전 우상향이고 이평선 투자보다 좋다라고 단순히 판단은 할 수 있겠지만, 

 

변동폭같은걸 계산하지 않았지만, 계산하게 된다면 변동성이 너무크기 때문에 실제로투자할때는 저 변동성을 모두 견디고?감수해야한다. 

 

암튼, 모멘텀이 좀 높게 나왔으니 

 

모멘텀 전략의 매수 매도 타이밍이 어떤지 함 봐보자. 

 

fig = go.Figure()

fig.add_trace(go.Scatter(x=Apple_quant_df['Date'], y=Apple_quant_df['Adj Close'], 
                         mode='lines', name='Apple Adj Close'))

# Buy Signal
buy_signals = Apple_quant_df[Apple_quant_df['Momentum_Signal'] == 1]
fig.add_trace(go.Scatter(x=buy_signals['Date'], y=buy_signals['Adj Close'], 
                         mode='markers', name='Buy Signal (Momentum)', marker=dict(color='green', symbol='triangle-up', size=10)))

# Sell Signal
sell_signals = Apple_quant_df[Apple_quant_df['Momentum_Signal'] == -1]
fig.add_trace(go.Scatter(x=sell_signals['Date'], y=sell_signals['Adj Close'], 
                         mode='markers', name='Sell Signal (Momentum)', marker=dict(color='red', symbol='triangle-down', size=10)))

# Slider for date
fig.update_layout(
    title="Apple Stock Price with Buy/Sell Signals (Momentum)",
    xaxis_title="Date",
    yaxis_title="Adjusted Close Price",
    template="plotly_white",
    xaxis=dict(rangeslider=dict(visible=True))  # range slider 추가
)

fig.show()

가장 최근으로 좀 줌해서 이미지를 가지고 왔다. 저렇게 그래프에서만 보여지는건 좀 이해가 안가니까 통계적인걸 함께 추출해서 봐보자. 

# Stats..
# Index
buy_dates = Apple_df[Apple_df['Momentum_Signal'] == 1]['Date']
sell_dates = Apple_df[Apple_df['Momentum_Signal'] == -1]['Date']

# 1. Buy
buy_count = len(buy_dates)

# 2. Sell
sell_count = len(sell_dates)

# 3. avg date for sell after buy.
if len(buy_dates) > 0 and len(sell_dates) > 0:
    buy_to_sell_periods = []
    for i in range(min(len(buy_dates), len(sell_dates))):
        buy_to_sell_period = (sell_dates.iloc[i] - buy_dates.iloc[i]).days
        buy_to_sell_periods.append(buy_to_sell_period)
    avg_buy_to_sell_period = np.mean(buy_to_sell_periods)
else:
    avg_buy_to_sell_period = None

# 4. avg date for buy after sell.
if len(buy_dates) > 0 and len(sell_dates) > 0:
    sell_to_buy_periods = []
    for i in range(1, min(len(buy_dates), len(sell_dates))):
        sell_to_buy_period = (buy_dates.iloc[i] - sell_dates.iloc[i-1]).days
        sell_to_buy_periods.append(sell_to_buy_period)
    avg_sell_to_buy_period = np.mean(sell_to_buy_periods)
else:
    avg_sell_to_buy_period = None

# 5. avg return sell after buy
if len(buy_dates) > 0 and len(sell_dates) > 0:
    buy_to_sell_returns = []
    for i in range(min(len(buy_dates), len(sell_dates))):
        buy_price = Apple_df.loc[Apple_df['Date'] == buy_dates.iloc[i], 'Adj Close'].values[0]
        sell_price = Apple_df.loc[Apple_df['Date'] == sell_dates.iloc[i], 'Adj Close'].values[0]
        buy_to_sell_return = (sell_price - buy_price) / buy_price
        buy_to_sell_returns.append(buy_to_sell_return)
    avg_buy_to_sell_return = np.mean(buy_to_sell_returns)
else:
    avg_buy_to_sell_return = None

# 6. avg return buy after sell
if len(buy_dates) > 0 and len(sell_dates) > 0:
    sell_to_buy_returns = []
    for i in range(1, min(len(buy_dates), len(sell_dates))):
        sell_price = Apple_df.loc[Apple_df['Date'] == sell_dates.iloc[i-1], 'Adj Close'].values[0]
        buy_price = Apple_df.loc[Apple_df['Date'] == buy_dates.iloc[i], 'Adj Close'].values[0]
        sell_to_buy_return = (buy_price - sell_price) / sell_price
        sell_to_buy_returns.append(sell_to_buy_return)
    avg_sell_to_buy_return = np.mean(sell_to_buy_returns)
else:
    avg_sell_to_buy_return = None

# Stats
print("Momentum Buy Signal Frequency:", buy_count)
print("Momentum Sell Signal Frequency:", sell_count)
print("Average Duration from Buy to Sell (days):", avg_buy_to_sell_period)
print("Average Duration from Sell to Buy (days):", avg_sell_to_buy_period)
print("Average Return from Buy to Sell:", avg_buy_to_sell_return)
print("Average Return from Sell to Buy:", avg_sell_to_buy_return)

 

총 1110번정도의 매수매도가 있었고 (매수 603, 매도 597)

 

평균적으로 매수 후에 매도가 일어나는 기간이 110일 후다.. 많이 견뎌라 

그리고 매도 후에 다시 매수하는 기간은 보통 83일정도 걸리나보다 (왜 마이너스냐 하믄 저거 반대로 뺏어서? 코드 수정해야할것같은데..? 나중에 다시 확인해봐야겠음..)

 

그리고 평균적으로 모맨텀 전략을 통해서

매수 후 매도 시점까지 평균적으로 약 10.37%의 수익이 발생했다. 즉, 매수 후 매도 시점까지의 투자에서 평균적으로 10.37%의 이익을 본거고,

매도 후 다시 매수할 때까지 평균적으로 약 -3.19%의 손실이 발생한거다. 매도 후 다시 매수할 때 주가가 하락하는 경향이 있었음을 의미 하니까 뭐 나름 시그널이 좀 잘 해줫다?라고 본다. 

 

Before and After: Financial Events 

애플은 과연 주요 경제 이벤트(이슈) 전후로 어떤 변화가 있었는지 보고싶었다. 

경제 이벤트는 그냥 내가 임의로 지정했다. 

# Key Events for Economics
events = {
    'iPhone Launch': '2007-06-29',
    'Financial Crisis': '2008-09-15',
    'Steve Jobs Resignation': '2011-08-24',
    'COVID-19 Pandemic': '2020-03-11',
    'Apple Silicon Launch': '2020-11-10',
    'Black Monday': '1987-10-19',
    'Soviet Union Collapse': '1991-12-26',
    'Asian Financial Crisis': '1997-07-02',
    'Dot-com Bubble Burst': '2000-03-10',
    '9/11 Attacks': '2001-09-11',
    'Iraq War Start': '2003-03-20',
    'Lehman Brothers Collapse': '2008-09-15',
    'European Debt Crisis': '2010-04-23',
    'U.S. Credit Rating Downgrade': '2011-08-05',
    'Brexit Vote': '2016-06-23',
    'U.S.-China Trade War': '2018-07-06',
    'Global Chip Shortage': '2020-12-01',
    'Russian Invasion of Ukraine': '2022-02-24',
    'Silicon Valley Bank Collapse': '2023-03-10'
}

그나마 좀 최근 이벤트로 가지고 와보려고했는데,, 조금만 할라했는데 ㅠ 많아졌다.. 

 

뭐 굳이 어떤건지 하나씩 설명 안하겠다. 궁금하면 야후 파이낸스 검색 고고.

 

이벤트를 지정하구나서, 전후로 한달정도 주가를 보여주기로하고, 선형그래프를 그려서 어떤 변화가 있었는지 그리고 평균적인 편화율도 보여주고싶었다. 

코드가 너무 길어서 생략하겠다. (캐글가서 보세용)

시각화를 보여주기전에 표로 먼저 보면

 

가장 변동이 컸던건 Black Monday다.. 그냥 아주 박살이 나버렸다. 

나무위키를 좀 참조하자면, 

1987년 10월 19일 월요일 다우 존스 산업평균지수(DJIA)가 하루만에 508포인트, 즉 22.6%나 떨어졌다. 이는 DJIA 역사상 단일 하루 최대 하락률이었다. 미국뿐만 아니라 전 세계 시장도 큰 타격을 입었고, 블랙먼데이 이전의 주가를 회복하는 데는 2년이 걸렸다.

붕괴의 원인은 주가 고평가, 금리 상승 등 여러 가지가 있었다. 그 중 큰 주목을 받은 것은 시장이 하락세를 보이기 시작할 때 대규모 매도를 촉발시킨 컴퓨터 기반 거래 프로그램의 도입이었다. 이로 인해 일종의 도미노 효과가 발생해 상황이 아주 빠르게 통제 불능 상태로 빠졌다.
.... 

 

물론 그당시 상황은 내가 모르지만, 내가 지정한 어떠한 이벤트보다 전후로 크게 변동이 있었다... 

 

(리만브라더스 사태를 그냥 Financial Crisis라고 지정해놨는데 또 그냥 적어버렸네,, )
암튼 두번째 타격이 큰건 누구나 아는 리만브라더스 사태이다... 

 

아오 슬프니까 상승한걸로만 좀 봐볼까?

 

소련 붕괴하니까, 대항마가 없는 미국의 모든 주가가 상승할때 함께 애플도 날라가고,

아이폰이 런칭되고 세계의 모바일 시장이 바뀌는 이런 긍정적인 이벤트에서는 주가가 크게 상승해버렸다. 

 

 

Before and After: Financial Events compare with other Companies

그럼 저런 주요 이벤트때 다른 회사들의 주식들은 어떻게 변동했고, 비교했을때 애플은 과연 다른 주식들보다 안전했는지도 확인해보자. 

시각화를 위해서 조금 더 나은 비교를 위해서 정규화를 하고 진행했따.

(주요 코드는 캐글에서)

 

리만브라더스 사태와, 아이폰 런칭 했을때를 한번 봐보쟝.

 

리만 전후로 비교했을때 당시 주가가 있었던 대부분의 주식들이 하락했다. 

근데? 

삼성 뭐야 왜 크게 변동 없어보여? 

 

리만이 터지고 당시에는 많은 하락이 있었지만, 10월 쯤에 다른 주식들보다 더 빠르게 회복을 했다. 

(빨리 회복하면 뭐하냐, 지금 뭐하냐고 삼성아..)

 

자, 아이폰 런칭때는 어땠을까? 

역시나 아이폰이 새로나와서 그런가, 

시장이 변동되고 (긍정적으로) 혁신이 탄생하는 날이라 그런가 

대부분의 시장의 IT 회사들이 모두 함께 상승한걸로 해석이 된다. 

 

뭐 더 다른 많은 이벤트 전후비교 자료는 캐글에서 구경하셔요. 

 

https://www.kaggle.com/code/sungbos/apple-analysis-trend-simple-quant-events

 

Apple Analysis: Trend, Simple Quant, Events

Explore and run machine learning code with Kaggle Notebooks | Using data from Apple Stock Data and Key Affiliated Companies

www.kaggle.com

 

 

마무리

그냥 주가 정리된거 있길래 끄적인거고, 퀀트도 간단한거 다시해보고 했다. 

다시 주식 퀀트투자 하는거 시작하기에 좀 좋은 동기부여였따?

라고 하기엔 너무 대충함

너무 바쁘고 다른거 하느라, 주식을 못보고있었는데.. 나중엔 캐글 말고 내가 직접 수집한 주가가지고 좀 퀀트 활용해보자.

닫시 퀀트투자 해야지...(아직 트래이딩 뷰도 살아있어)

+ Recent posts