네이버 주식 시가총액 데이터를 자동으로 수집하고 윌리엄스 전략을 적용하여 매수 추천 종목을 선별한 뒤 결과를 구글 시트에 자동 기록하는 프로그램의 전체 구조와 동작 방식에 대하여 알아보겠습니다. 파이썬을 활용해 실시간 데이터 크롤링, 지표 계산, 조건부 필터링, 그리고 구글 시트 API 연동까지 한 번에 처리할 수 있어 이 과정을 통해 반복적인 수작업 없이 효율적인 종목 관리와 매수 신호 기록이 가능해집니다. ▼
구글 시트 확인
바로가기 ▶
추천 종목 추출 프로그램
KOREASTORAGE®️
아래 코드는 네이버 금융에서 주식 데이터를 수집해 ‘윌리엄스 전략’ 매수 신호를 판별하고 조건에 맞는 종목을 구글 시트에 기록하는 전체 자동화 파이프라인입니다. 단계별로 주요 흐름과 각 코드의 역할을 알아봅니다.
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) 라이브러리 및 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 이상)과 기본 지표(PER, 거래량, 등락폭 등)로 추천종목 자동 선별
- 그 결과를 구글 시트에 자동 누적 기록
- 코드 곳곳에 오류/이상 케이스에 대한 예외처리와 상태 출력을 포함
상기 프로그램은 네이버 금융에서 래리 윌리엄스 전략 투자에 적합한 종목을 자동으로 추출하는 파이썬 코드로써, 주식 초보자들이 어떤 종목을 선택할지 아무런 지식이 없을때 참고할 수 있도록 추천해주는 역할을 합니다. 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하이닉스: 기술·펀더멘털 모두 우위 → 주력 매수
- 삼성전자: 회복 기대 + 상승 여력 → 보조 매수 추천
유의사항
- 시장 변동성 존재: 특히 해외 요인, 미국 기술주 흐름, 환율 변동 주의 필요
- 내일 단기 관점 기반 분석이므로, 장기 투자는 다른 시각 필요
- 최종 매매 전, 자신의 매매 전략, 리스크 허용 범위 재확인 권장
이와 같은 방법으로 삼성전자 주식 2주를 샀는데 결과적으로는 오르긴 오른것을 알 수 있습니다. (SK하이닉스는 비싸서 못사고 대신 SK텔레콤 1주를 샀습니다.)
구글 시트는 계속 업데이트하고 있으니 클릭하여 확인해 보세요.
주식 단타 1년에 1,000만 원을 14억으로 만든 레리 윌리엄스 전략
연 30억 매출을 만든 저스틴 웰시의 1인 사업 운영법
'지식정보' 카테고리의 다른 글
민생회복소비쿠폰 전 국민 지급 정부 발표 해설 (2) | 2025.07.15 |
---|---|
카페 창업 유료 콘텐츠 시장 조사에 대한 심층 리서치 (0) | 2025.07.13 |
양자컴퓨터 도입(127큐비트 IBM 시스템) (1) | 2025.07.08 |
껍질 째 먹어야 더 건강한 과일들 (0) | 2025.06.30 |
이재명 정부 시대 완전히 새로워진 노인 복지 정책 10가지 (4) | 2025.06.28 |