다크 모드
본문 바로가기

주식 자동화 프로그램 추천종목 네이버 데이터부터 구글 시트까지

by 순이하우스 2025. 7. 16.

네이버 주식 시가총액 데이터를 자동으로 수집하고 윌리엄스 전략을 적용하여 매수 추천 종목을 선별한 뒤 결과를 구글 시트에 자동 기록하는 프로그램의 전체 구조와 동작 방식에 대하여 알아보겠습니다. 파이썬을 활용해 실시간 데이터 크롤링, 지표 계산, 조건부 필터링, 그리고 구글 시트 API 연동까지 한 번에 처리할 수 있어 이 과정을 통해 반복적인 수작업 없이 효율적인 종목 관리와 매수 신호 기록이 가능해집니다. ▼

MD

구글 시트 확인

바로가기 ▶

 

추천 종목 추출 프로그램

KOREASTORAGE®️

 

아래 코드는 네이버 금융에서 주식 데이터를 수집해 ‘윌리엄스 전략’ 매수 신호를 판별하고 조건에 맞는 종목을 구글 시트에 기록하는 전체 자동화 파이프라인입니다. 단계별로 주요 흐름과 각 코드의 역할을 알아봅니다.

Code block
🗹
import gspread
from google.oauth2.service_account import Credentials
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
from datetime import datetime
from gspread_formatting import *

# 1) 네이버 시총 페이지에서 기본 데이터 수집
url = "https://finance.naver.com/sise/sise_market_sum.naver?sosok=0&page=1"
headers = {'User-Agent': 'Mozilla/5.0'}
res = requests.get(url, headers=headers)
res.encoding = 'euc-kr'

soup = BeautifulSoup(res.text, "html.parser")
table = soup.find("table", class_="type_2")
df = pd.read_html(str(table))[0]

df = df.dropna(how='all')
df = df[df['종목명'].notnull()]
df['거래량'] = pd.to_numeric(df['거래량'].astype(str).str.replace(',', ''), errors='coerce').fillna(0).astype(int)

for col in ['PER', 'ROE']:
    df[col] = pd.to_numeric(df[col], errors='coerce')
    df[col] = df[col].replace([np.inf, -np.inf], np.nan).fillna(0)
    df[col] = df[col].clip(-1e6, 1e6)

df['전일비_숫자'] = df['전일비'].astype(str).str.extract(r'([-+]?[0-9,]+)').fillna('0').replace(',', '', regex=True)
df['전일비_숫자'] = pd.to_numeric(df['전일비_숫자'], errors='coerce').fillna(0)
df['등락폭'] = df['전일비_숫자'].abs()

# 2) 종목 코드 크롤링
codes = []
for a in soup.select("table.type_2 tbody tr > td > a.tltle"):
    href = a.get('href')
    if href and 'code=' in href:
        code = href.split('code=')[1]
        codes.append(code)

if len(codes) == len(df):
    df['종목코드'] = codes
else:
    print(f"종목코드 개수: {len(codes)}, 데이터프레임 행 수: {len(df)}")
    print("종목코드 수와 데이터프레임 행 수가 맞지 않아 종목코드 없이 진행합니다.")

# 3) 전일 고가/저가 크롤링 함수 정의
def get_prev_high_low(stock_code):
    try:
        url = f'https://finance.naver.com/item/sise_day.nhn?code={stock_code}&page=1'
        res = requests.get(url, headers=headers)
        res.encoding = 'euc-kr'
        soup = BeautifulSoup(res.text, 'html.parser')
        table = soup.find('table', class_='type2')
        df_hist = pd.read_html(str(table))[0]
        df_hist = df_hist.dropna(how='all')
        if len(df_hist) > 1:
            prev_day = df_hist.iloc[1]
            high = float(str(prev_day['고가']).replace(',', ''))
            low = float(str(prev_day['저가']).replace(',', ''))
            return high, low
    except Exception as e:
        print(f"{stock_code} 데이터 조회 오류:", e)
    return np.nan, np.nan

# 4) 전일 고가/저가, 범위, 절반 범위, 윌리엄스 매수 조건 칼럼 추가
highs, lows, ranges, half_ranges, william_buy = [], [], [], [], []

for idx, row in df.iterrows():
    if '종목코드' in df.columns:
        code = row['종목코드']
        high, low = get_prev_high_low(code)
    else:
        high, low = np.nan, np.nan

    highs.append(high)
    lows.append(low)
    if pd.notna(high) and pd.notna(low):
        r = high - low
        hr = r / 2
    else:
        r = np.nan
        hr = np.nan
    ranges.append(r)
    half_ranges.append(hr)

    current_price = row['현재가']
    buy_flag = '매수 추천' if pd.notna(current_price) and pd.notna(low) and current_price >= (low + hr) else '사양'
    william_buy.append(buy_flag)

df['전일고가'] = highs
df['전일저가'] = lows
df['범위'] = ranges
df['범위_절반'] = half_ranges
df['윌리엄스_매수'] = william_buy

# 5) 사양여부 업데이트
df['사양여부'] = np.where(df['윌리엄스_매수'] == '매수 추천', '추천', '사양')

# 6) 필터링 조건 완화
filtered_df = df[
    (df['PER'] > 0) & (df['PER'] <= 10) &  # PER 범위 확대
    (df['거래량'] >= 1000000) &             # 거래량 조건 완화
    (df['등락폭'] >= 500) &                # 등락폭 조건 완화
    (df['윌리엄스_매수'] == '매수 추천')
].copy()

print(f"필터링된 종목 수: {len(filtered_df)}")
print("전일고가, 전일저가 샘플:\n", df[['전일고가', '전일저가']].head())
print("윌리엄스 매수 플래그 샘플:\n", df['윌리엄스_매수'].value_counts())
print(df.head())
print(filtered_df.head())
print(f"필터링된 종목 수: {len(filtered_df)}")
print("윌리엄스_매수 컬럼 값 분포:")
print(df['윌리엄스_매수'].value_counts(dropna=False))

filtered_df = df[df['윌리엄스_매수'] == '매수 추천'].copy()
print(f"윌리엄스 매수 추천 종목 수: {len(filtered_df)}")
print(filtered_df[['종목명', '현재가', '전일저가', '범위_절반', '윌리엄스_매수']])




if len(filtered_df) == 0:
    print("기록할 데이터가 없습니다.")
else:
    now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    filtered_df['기록시간'] = now_str

    SERVICE_ACCOUNT_FILE = 'promising-era-465315-j2-787bafb697f2.json'
    SPREADSHEET_KEY = '13paom2FZDc745APD8w_7fB1x6THZyPcTxuFtt8opXnY'

    scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive']
    creds = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=scope)
    gc = gspread.authorize(creds)
    sh = gc.open_by_key(SPREADSHEET_KEY)
    worksheet = sh.sheet1

    headers = filtered_df.columns.tolist()
    existing = worksheet.get_all_values()

    if len(existing) == 0:
        worksheet.insert_row(headers, 1)

    start_row = len(existing) + 1

    idx = filtered_df.columns.get_loc('사양여부')

    for i, row in enumerate(filtered_df.values.tolist(), start=start_row):
        worksheet.append_row([str(x) for x in row])
        if row[idx] == '사양':
            last_col = chr(ord('A') + len(row) - 1)
            fmt = CellFormat(textFormat=TextFormat(foregroundColor=color(1, 0, 0)))
            format_cell_range(worksheet, f"A{i}:{last_col}{i}", fmt)

    print("윌리엄스 전략 조건에 따른 추천/사양 종목 구글 시트 누적 기록 완료!")

 

실제 투자 실무 자동화에 쓸 수 있는 수준의 Python 크롤링/분석/기록 자동화 코드입니다. 각 단계마다 데이터 전처리, 조건 필터링, 자동화된 구글시트 기록 등 실전에서 요구되는 절차가 모두 구현되어 있습니다. 코드를 활용할 때, 서비스 계정 키와 스프레드시트 키는 본인의 것으로 변경해야 정상 동작합니다.

 

주식 자동화 프로그램 해설

 

1. 매커니즘

1) 라이브러리 및 API 인증

  • gspread, google.oauth2.service_account : 구글 시트 연동용
  • pandas, numpy: 데이터프레임, 수치 연산
  • requests, BeautifulSoup: 네이버 금융 웹페이지 크롤링
  • datetime : 기록 시간 관리
  • gspread_formatting : 구글 시트 셀 서식 지정용

2) 네이버 시가총액 페이지 크롤링 및 데이터프레임 생성

  • 네이버 시총 페이지의 첫 페이지(page=1)에서 표 데이터를 가져옴
    https://finance.naver.com/sise/sise_market_sum.naver?sosok=0&page=1
  • User-Agent 지정 후 GET 요청하여 HTML을 받아오고, BeautifulSoup으로 파싱
  • 주식 리스트가 들어 있는 <table class="type_2">만 추출
  • pandas.read_html()로 표 전체를 데이터프레임으로 변환
  • 전처리:
    결측 행/열 제거
    ‘종목명’ 없는 행 제거
    ‘거래량’ 컬럼의 문자열 쉼표 제거 후 숫자형 변환
    PER, ROE는 숫자 변환 후 무한대 값 처리 및 값 제한
    ‘전일비’ 값에서 숫자만 추출, 절대값으로 ‘등락폭’ 계산

3) 종목코드 크롤링

  • 종목코드는 표에서 바로 나오지 않아, <a class="tltle">의 href에서 추출
  • href에서 'code=' 뒷부분만 따서 리스트로 저장
  • 종목코드 개수와 데이터프레임 행 수가 일치하면 컬럼으로 추가, 아니면 경고 출력

4) 전일 고가/저가 크롤링 함수 정의

get_prev_high_low(stock_code)

  • 각 종목의 일봉(시세) 데이터 페이지에서 ‘고가’, ‘저가’ 추출
  • 표 데이터에서 두 번째(전일) 행의 고가/저가 가져옴
  • 숫자형 변환, 오류 시 NaN 반환

5) 전일 고가/저가, 범위, 절반범위, 매수조건 계산

각 종목별로

  • 전일 고가/저가를 가져와 리스트로 축적
  • 범위(고가-저가), 범위의 절반 계산
  • 현재가가 (전일 저가 + 절반범위) 이상이면 ‘매수 추천’, 아니면 ‘사양’으로 플래그 설정

결과를 데이터프레임에 새로운 컬럼으로 저장

6) 사양여부 플래그 추가

‘윌리엄스_매수’가 ‘매수 추천’이면 ‘추천’, 아니면 ‘사양’으로 표시

7) 필터링(조건부 선별)

아래 조건에 모두 부합하는 종목만 filtered_df로 따로 저장

  • PER: 0 < PER ≤ 10
  • 거래량: 1,000,000 이상
  • 등락폭: 500 이상
  • 윌리엄스 매수 추천(‘매수 추천’)

8) 필터링된 결과/통계 출력

필터링된 종목 수, 전일고가/저가 샘플, 매수 플래그 분포 등 콘솔 출력

9) 구글 시트 기록

필터링된 종목이 1개 이상이면,

  • 기록 시간 컬럼 추가
  • 서비스 계정 키로 구글 시트 인증 후, 시트 열기
  • 데이터프레임 헤더 및 값 행별로 시트에 기록
  • ‘사양’인 행은 서식을 빨간 글씨로 변경
  • 완료 메시지 출력
2. 전체 요약
  • 네이버 시총표/개별 종목페이지에서 실시간 데이터를 수집
  • 윌리엄스 매수 전략(현재가가 전일 저가 + (고가-저가)/2 이상)과 기본 지표(PER, 거래량, 등락폭 등)로 추천종목 자동 선별
  • 그 결과를 구글 시트에 자동 누적 기록
  • 코드 곳곳에 오류/이상 케이스에 대한 예외처리와 상태 출력을 포함
3. 실전 활용 방법

상기 프로그램은 네이버 금융에서 래리 윌리엄스 전략 투자에 적합한 종목을 자동으로 추출하는 파이썬 코드로써, 주식 초보자들이 어떤 종목을 선택할지 아무런 지식이 없을때 참고할 수 있도록 추천해주는 역할을 합니다. ChatGPT로 만들어서 테스트 삼아 활용하고 있으며 사용방법은 아래와 같습니다.

예를들어

프로그램이 아래와 같은 종목을 추천했다면

 

삼성전자,SK하이닉스,KB금융,삼성전자우,두산에너빌리티,한화에어로스페이스,셀트리온,NAVER,HD현대중공업,신한지주,삼성물산,하나금융지주,HMM,POSCO홀딩스,한화오션,한국전력,HD한국조선해양,메리츠금융지주,현대로템,우리금융지주,기업은행,HD현대일렉트릭,SK,삼성중공업,KT,삼성SDI,삼성에스디에스,LIG넥스원,미래에셋증권,삼양식품,HD현대

추천 종목중에서 애널리스트나 주식 전문가가 평가한 데이터를 기반으로 내일 오를만한 주식을 추천해줘..

라고 ChatGPT에게 질문을 하면 다음과 같이 알려줍니다.

📈 추천 종목

1. 삼성전자 (005930.KS)

  • 애널리스트 평균 목표가: ₩73,200대
    이는 현재가 ₩63,700 대비 약 +15 % 상승 여력 .
  • 애널리스트 의견 요약: 투자자 다수가 매수(Buy) 의견을 제시 .
  • 현안 리스크: Q2 영업이익은 기대치를 크게 하회했으나(–56 %) ,
    – AI용 HBM 공급 이슈로 SK하이닉스·Micron에 시장 일부 내줌
    – 그러나 신제품 출시, 폴더블폰 강화 전략, 주식 자사주 매입 계획 등 단기 모멘텀이 존재 .

다소 불안 요소 있으나 단기 회복 기대 + 목표 상승 여력 고려 시 비중 있게 고려 가능합니다.

2. SK하이닉스 (000660.KS)

  • 애널리스트 평균 목표가: 약 ₩306,000 ~ ₩318,000
    현재 ₩298,500 대비 +3 ~ +6 % 상승 여력 .
  • 평균 평가: 강력한 매수(Strong Buy) 등급 다수 .
  • 기술적 분석: 단기 및 장기 이동평균선 기반 매수 신호 포착,
    MACD 피봇 상향 전환 시 강한 반등 가능성 .
  • 펀더멘털: AI 데이터센터용 HBM 수요 급증으로 실적 강세 지속 .

기술적·기본적 긍정 신호 동시 확인되며, 내일 단기 상승에 적합한 종목으로 보입니다.

종합 판단

종목 상승 요인 반영된 리스크
삼성전자 목표가 +15 %, 자사주 매입、신제품 모멘텀 Q2 실적 부진, 믹스 개선 필요
SK하이닉스 HBM 수요강세, Strong Buy와 기술적 지지 단기 기술적 조정 가능성 존재
 

단기 추천:

  • SK하이닉스: 기술·펀더멘털 모두 우위 → 주력 매수
  • 삼성전자: 회복 기대 + 상승 여력 → 보조 매수 추천

유의사항

  1. 시장 변동성 존재: 특히 해외 요인, 미국 기술주 흐름, 환율 변동 주의 필요
  2. 내일 단기 관점 기반 분석이므로, 장기 투자는 다른 시각 필요
  3. 최종 매매 전, 자신의 매매 전략, 리스크 허용 범위 재확인 권장

 

이와 같은 방법으로 삼성전자 주식 2주를 샀는데 결과적으로는 오르긴 오른것을 알 수 있습니다. (SK하이닉스는 비싸서 못사고 대신 SK텔레콤 1주를 샀습니다.)

키움증권

구글 시트는 계속 업데이트하고 있으니 클릭하여 확인해 보세요.

 

 

 

 

함께읽으면좋아요!

 

주식 단타 1년에 1,000만 원을 14억으로 만든 레리 윌리엄스 전략

연 30억 매출을 만든 저스틴 웰시의 1인 사업 운영법

절대 망하지 않는 사업 아이템 7

 

 

 

 

맨 위로 ▲

반응형

이 광고는 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.


home top bottom