```python
import sys
import pandas as pd
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QTextEdit, QPushButton
from pykrx import stock
import talib
class StockFilterApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Stock Filter')
layout = QVBoxLayout()
self.per_input = QLineEdit(self)
self.per_input.setPlaceholderText('PER 입력 (예: 10)')
self.div_input = QLineEdit(self)
self.div_input.setPlaceholderText('DIV 입력 (예: 2)')
self.result_output = QTextEdit(self)
self.result_output.setReadOnly(True)
self.search_button = QPushButton('주식 검색 실행', self)
self.search_button.clicked.connect(self.search_stocks)
layout.addWidget(self.per_input)
layout.addWidget(self.div_input)
layout.addWidget(self.search_button)
layout.addWidget(self.result_output)
self.setLayout(layout)
self.show()
def search_stocks(self):
per_value = float(self.per_input.text())
div_value = float(self.div_input.text())
# 코스피 200 종목 리스트 구하기
kospi_200 = stock.get_index_portfolio_deposit_file("1028") # 코스피 200 지수 코드
result = []
for ticker in kospi_200:
try:
# 1년 간의 OHLCV 데이터
ohlcv = stock.get_market_ohlcv_by_date(fromdate='20230901', todate='20240831', ticker=ticker)
if ohlcv.empty or len(ohlcv) < 60: # 최소 60일의 데이터가 필요함
continue # 데이터가 비어있거나 부족하면 다음 종목으로
# 펀더멘털 데이터
fundamentals = stock.get_market_fundamental("20230831", "20230831", ticker)
if fundamentals.empty:
continue # 펀더멘털 데이터가 비어있으면 다음 종목으로
fundamentals = fundamentals.iloc[0]
per = fundamentals['PER']
div = fundamentals['DIV']
# 조건 1: PER 및 DIV 필터
if per >= per_value and div >= div_value:
close_prices = ohlcv['종가']
# 이동평균선 구하기
ma_5 = talib.SMA(close_prices, timeperiod=5)
ma_20 = talib.SMA(close_prices, timeperiod=20)
ma_60 = talib.SMA(close_prices, timeperiod=60)
# 최신 데이터 확인을 위한 유효성 검사
if len(ma_5) < 1 or len(ma_20) < 1 or len(ma_60) < 1:
continue
# 조건 2: 이동평균선의 정배열
if ma_5.iloc[-1] > ma_20.iloc[-1] > ma_60.iloc[-1]:
upper, middle, lower = talib.BBANDS(close_prices, timeperiod=20)
# 볼린저 밴드 데이터 유효성 검사
if len(middle) < 1 or len(lower) < 1:
continue
# 조건 3: 볼린저 밴드 조건
if middle.iloc[-1] > close_prices.iloc[-1] > lower.iloc[-1]:
name = stock.get_market_ticker_name(ticker)
result.append(f"{ticker} - {name}")
except Exception as e:
print(f"Error processing ticker {ticker}: {e}")
# 결과 출력
self.result_output.setPlainText("\n".join(result))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = StockFilterApp()
sys.exit(app.exec_())
```