나만의 배당주 사이트 만들기) 2-5. 개발 단계 - 주식별 동적인 페이지 만들기, (시총, 주가내역, 배당 내역 등)

2025. 1. 21. 13:00프로젝트

이 전 글들이 궁금하다면 ?

 

0. 사이트를 만드려는 이유

https://hsjoo126.tistory.com/80

 

1-1. 프로젝트 가능성 보기

https://hsjoo126.tistory.com/81

 

pandas 와 jupyter 이용해서 테스트해보기 

https://hsjoo126.tistory.com/82

 

1-2. 기획 단계 - 디자인, 와이어 프레임, ERD 등

https://hsjoo126.tistory.com/83

 

2. 개발 단계 - 계획짜기, 구현해보기

https://hsjoo126.tistory.com/84

 

2-1. 개발 단계 - 배당지불일, 시장별 티커리스트 구하기

https://hsjoo126.tistory.com/85

 

2-2. 개발 단계 - 코드 정리

https://hsjoo126.tistory.com/86

 

2-3. 개발 단계 - 사이트에 적용하기(장고)

https://hsjoo126.tistory.com/87

 

2-4. 개발 단계 - 사이트 로딩 속도 줄이기

https://hsjoo126.tistory.com/88


오늘은 지난 글에도 적어놨다시피

각 주식 별 개인 페이지를 만들고, 디테일을 더 잡아볼 것이다!

할 일
- 주식 개별 페이지 만들기
- views.py 중복 코드 없애기
- 데이터 로딩시간 줄이기
- 티커 나스닥 뿐만아니라 다른 시장도 넣어서 조회하기

 

 

 

1. 주식 개별 페이지 만들기

1-1. 개별 페이지엔 뭐가 들어가면 좋을까!

저번에 만든 디자인을 살펴보면..!

 

- 주식 이름

- 시총

- 주식에 대한 정보

- 배당 내역(배당일, 배당금, 배당률)

 

이렇게 들어가 있는데, 추가로 배당락일, 주가 내역, 주가 그래프?정도 보여주면 될거 같다!

다시 정리해보면! 다음과 같다

개별페이지에 들어갈 것들
- 주식 이름
- 시총
- 주식에 대한 간단 정보
- 배당 내역(배당일, 배당금, 배당률, 배당락일)
- 주가 내역
- 주가 그래프

 

 

1-2. 생각정리

- 사람들이 배당률 페이지에 들어왔을 때, 주식을 클릭하면, 개별 페이지로 넘어가게끔 만들고 싶다.

- 티커별로 페이지들이 만들어질 것이고 내용은 다르겠지만 기본적인 틀은 똑같을 것이다.

- 마치 개인 프로필 페이지가 있는 것처럼, 개별 주식 페이지가 있는 것이다! 

- 한 가지 걱정되는 것은, 데이터 로딩 속도인데, 배당률 페이지처럼 오래걸리면 .. 음.. ㅜㅜ

 

= 일단 해보자!

 

1-3. 구현해보기!

일단 주가 그래프는 공부를 하고 해야할 거 같으니 잠시 미뤄두고, 다른 거 먼저 보도록 하자.

저번에 했던 것처럼, 하나씩 구현을 해보고, 합치는 방식으로 진행을 해야될 거 같다.

 

1-3. 1. 주식이름

배당률 페이지에서 주식을 누르면 해당 주식 페이지로 이동하기

 

middle.html 에서 a 태그를 추가해 주식을 누르면 상세 페이지로 갈 수 있도록 했다.

 

지금은, 이름만 뜨면 되니까, view에서도 간단하게 ticker 이름만 넘겨주었고

#views.py
def detail(request, ticker):
    stock = yf.Ticker(ticker)
    return render(request, "stocks/detail.html", {'stock':stock})

 

html에서도 이름만 뜰 수 있게 구현했다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>상세페이지</title>
</head>
<body>
    <h1>{{stock.ticker}} 상세페이지</h1>
</body>
</html>

 

 

결과는 다음과 같다.

a태그 추가!
이름에 맞게 변함!

 

1-3. 2. 시총

두번째로는 시총이다. 

이건 배당률 페이지에도 구현을 해봤으니 빠르게 해보자!

#views.py
def detail(request, ticker):
    stock = yf.Ticker(ticker)
    info = stock.info
    
    market_cap = info.get('marketCap', '정보 없음')
        context = {
        'stock':stock,
    }
    return render(request, "stocks/detail.html", context)
    
#detail.html
<p>시가총액: {{ market_cap }} USD</p>

 

 

1-3. 3. 주식에 대한 간단 정보

코드는... 간단하게 넣었는데 아니 세상에 ㅋㅋㅋㅋㅋㅋㅋ 영어로 나오네 .. ?

어캄 ;;; 

알아보니까, 대부분의 번역api 돈을 내야한다..

"어... 우리 사이트는 최대한 무료로 굴리고 싶은데요,, "

오케 일단 저렇게 해두고, 주변 의견을 받아서 나중에 수정해야겠다!!

 

 

1-3. 3. 배당내역

배당내역은 3년 이내로 보여주면 되지 않을까 싶다!

배당일, 배당금, 배당률, 배당락일

 

...

 

계속 알아보고 적용도 해봤는데, yfinance 에선 배당일, 배당금 만 내역을 보여주고

배당률, 배당락일은 내역을 제공하지 않는다.

게다가 배당일은 배당락일로 보여줌... 실화냐..

크흡 ㅠ 일단은, 나오는 대로만... 배당 내역을 구성하자 하..

def detail(request, ticker):
    stock = yf.Ticker(ticker)
    info = stock.info
    
    # 배당 내역
    divi = stock.dividends
    # 배당 내역이 비어있는지 확인
    if divi.empty:
        dividend_data = "배당 내역이 없습니다."  # 배당 내역이 없으면 메시지 반환
    else:
        # 최근 3년 기준 날짜 계산
        three_years_ago = timezone.now() - timedelta(days=3*365)
        
        # 최근 3년 데이터 필터링 후 인덱스를 리셋하고 'Date' 컬럼을 날짜로 변환
        dividend_data = divi[divi.index >= three_years_ago].reset_index()
        dividend_data['date'] = dividend_data['Date'].dt.date  # 날짜만 추출
        
        # 배당금과 날짜만 선택하여 리스트로 변환
        dividend_list = dividend_data[['date', 'Dividends']].to_dict(orient='records')
    

    context = {
        'stock':stock,
        'dividend_list': dividend_list,
    }
    return render(request, "stocks/detail.html", context)
    <h2>배당 내역 (최근 3년)</h2>
    <table>
        <thead>
            <tr>
                <th>배당일</th>
                <th>배당금</th>
            </tr>
        </thead>
        <tbody>
            {% for dividend in dividend_list %}
            <tr>
                <td>{{ dividend.date }}</td>
                <td>{{ dividend.Dividends }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

여러 시행착오를 거친 끝에, 배당내역을 구했다.

 

 

1-3. 4. 주가내역

그 다음은 주가 내역을 구해보자!

    # 주가 내역 (최근 3개월)
    stock_history = stock.history(interval='1d', period='1y', auto_adjust=False)
    # 'Date' 열을 Datetime 형식으로 변환하고, 날짜만 출력
    stock_history['date'] = stock_history.index.date
    # 필요한 열만 선택
    stock_history_selected = stock_history[['date','Open', 'High', 'Low', 'Close', 'Volume']]
    # 데이터를 템플릿에 전달
    stock_history_list = stock_history_selected.to_dict(orient='records')
    
    context = {
        'stock':stock,
        'stock_history_list': stock_history_list,
    }
    <h2>주가 내역 (최근1년)</h2>
    <table border="1">
        <thead>
            <tr>
                <th>Date</th>
                <th>Open</th>
                <th>High</th>
                <th>Low</th>
                <th>Close</th>
                <th>Volume</th>
            </tr>
        </thead>
        <tbody>
            {% for stock in stock_history_list %}
            <tr>
                <td>{{ stock.date }}</td>
                <td>{{ stock.Open }}</td>
                <td>{{ stock.High }}</td>
                <td>{{ stock.Low }}</td>
                <td>{{ stock.Close }}</td>
                <td>{{ stock.Volume }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

생각보다 주가 내역은 하기 수월했다 

자료도 많았어서 꽤 빨리 구현할 수 있었다.

 

1-4. 최종코드

최종코드는 다음과 같다.

#views.py
def detail(request, ticker):
    stock = yf.Ticker(ticker)
    info = stock.info
    
    #시총
    market_cap = info.get('marketCap', '정보 없음')
    
    #주식 간단 정보
    summary = info.get('longBusinessSummary', '정보 없음')
    
    # 배당 내역
    divi = stock.dividends
    # 배당 내역이 비어있는지 확인
    if divi.empty:
        dividend_data = "배당 내역이 없습니다."  # 배당 내역이 없으면 메시지 반환
    else:
        # 최근 3년 기준 날짜 계산
        three_years_ago = timezone.now() - timedelta(days=3*365)
        
        # 최근 3년 데이터 필터링 후 인덱스를 리셋하고 'Date' 컬럼을 날짜로 변환
        dividend_data = divi[divi.index >= three_years_ago].reset_index()
        dividend_data['date'] = dividend_data['Date'].dt.date  # 날짜만 추출
        
        # 배당금과 날짜만 선택하여 리스트로 변환
        dividend_list = dividend_data[['date', 'Dividends']].to_dict(orient='records')
    
    # 주가 내역 (최근 3개월)
    stock_history = stock.history(interval='1d', period='1y', auto_adjust=False)
    # 'Date' 열을 Datetime 형식으로 변환하고, 날짜만 출력
    stock_history['date'] = stock_history.index.date
    # 필요한 열만 선택
    stock_history_selected = stock_history[['date','Open', 'High', 'Low', 'Close', 'Volume']]
    # 데이터를 템플릿에 전달
    stock_history_list = stock_history_selected.to_dict(orient='records')


    context = {
        'stock':stock,
        'market_cap': market_cap,
        'summary': summary,
        'dividend_list': dividend_list,
        'stock_history_list': stock_history_list,
    }
    return render(request, "stocks/detail.html", context)
#detail.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ stock_name }} 정보</title>
</head>
<body>
    <h1>{{stock.ticker}} 상세페이지</h1>
    <p>시가총액: {{ market_cap }} USD</p>
    <p>{{ summary }}</p>
    <h2>배당 내역 (최근 3년)</h2>
    <table>
        <thead>
            <tr>
                <th>배당일</th>
                <th>배당금</th>
            </tr>
        </thead>
        <tbody>
            {% for dividend in dividend_list %}
            <tr>
                <td>{{ dividend.date }}</td>
                <td>{{ dividend.Dividends }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <h2>주가 내역 (최근1년)</h2>
    <table border="1">
        <thead>
            <tr>
                <th>Date</th>
                <th>Open</th>
                <th>High</th>
                <th>Low</th>
                <th>Close</th>
                <th>Volume</th>
            </tr>
        </thead>
        <tbody>
            {% for stock in stock_history_list %}
            <tr>
                <td>{{ stock.date }}</td>
                <td>{{ stock.Open }}</td>
                <td>{{ stock.High }}</td>
                <td>{{ stock.Low }}</td>
                <td>{{ stock.Close }}</td>
                <td>{{ stock.Volume }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table> 
</body>
</html>

 

오늘 개별 페이지 만드는데도 시간이 굉장히 많이 흘렀다 ... 

그러므로...

할 일
- 주식 개별 페이지 만들기
- views.py 중복 코드 없애기
- 데이터 로딩시간 줄이기
- 티커 나스닥 뿐만아니라 다른 시장도 넣어서 조회하기

이 중에서 나머지 3가지 항목은 다음 글에서 하도록 하겠다!!