pykrx get_market_ohlcv_by_date: Complete Guide with Examples

What is get_market_ohlcv_by_date? get_market_ohlcv_by_date is one of the most commonly used functions in the pykrx library. It retrieves OHLCV (Open, High, Low, Close, Volume) data for a specific Korean stock ticker over a date range. Installation pip install pykrx Basic Syntax from pykrx import stock df = stock.get_market_ohlcv_by_date(fromdate, todate, ticker) Parameters: fromdate — Start date in YYYYMMDD format (string) todate — End date in YYYYMMDD format (string) ticker — Korean stock ticker (e.g., "005930" for Samsung Electronics) Basic Example from pykrx import stock # Get Samsung Electronics (005930) data for 2024 df = stock.get_market_ohlcv_by_date("20240101", "20241231", "005930") print(df.head()) Output: ...

July 9, 2026 · Phillip

pykrx Tutorial: 10 Real Examples for Korean Stock Data (2026)

Introduction pykrx is the easiest way to get Korean stock market data in Python. No API key needed, no account required — just install and start pulling data. This guide covers 10 real-world examples from basic price data to advanced screening. Setup pip install pykrx pandas from pykrx import stock import pandas as pd from datetime import datetime, timedelta # Helper: today's date TODAY = datetime.now().strftime("%Y%m%d") MONTH_AGO = (datetime.now() - timedelta(days=30)).strftime("%Y%m%d") YEAR_AGO = (datetime.now() - timedelta(days=365)).strftime("%Y%m%d") Example 1: Get Stock Price History from pykrx import stock # Samsung Electronics (005930) df = stock.get_market_ohlcv_by_date("20240101", "20241231", "005930") df.columns = ["Open", "High", "Low", "Close", "Volume"] print(df.tail()) Example 2: Get All KOSPI Tickers from pykrx import stock kospi = stock.get_market_ticker_list(market="KOSPI") kosdaq = stock.get_market_ticker_list(market="KOSDAQ") print(f"KOSPI stocks: {len(kospi)}") print(f"KOSDAQ stocks: {len(kosdaq)}") # Get company name name = stock.get_market_ticker_name("005930") print(f"005930 = {name}") # 삼성전자 Example 3: Market Cap Rankings from pykrx import stock # Top 10 KOSPI by market cap df = stock.get_market_cap_by_ticker(TODAY, market="KOSPI") top10 = df.sort_values("시가총액", ascending=False).head(10) for ticker, row in top10.iterrows(): name = stock.get_market_ticker_name(ticker) market_cap_trillion = row["시가총액"] / 1e12 print(f"{name}: {market_cap_trillion:.1f}T KRW") Example 4: Fundamental Data (PER, PBR, Dividend) from pykrx import stock # Get fundamentals for all KOSPI stocks df = stock.get_market_fundamental_by_ticker(TODAY, market="KOSPI") # Find undervalued stocks (low PER, low PBR) undervalued = df[ (df["PER"] > 0) & (df["PER"] < 10) & (df["PBR"] > 0) & (df["PBR"] < 1.0) ].copy() undervalued["name"] = [stock.get_market_ticker_name(t) for t in undervalued.index] print(undervalued[["name", "PER", "PBR", "DIV"]].sort_values("PER").head(10)) Example 5: KOSPI Index Data from pykrx import stock # Get KOSPI index history # "1001" = KOSPI, "2001" = KOSDAQ kospi_index = stock.get_index_ohlcv_by_date("20240101", "20241231", "1001") print(kospi_index.tail()) # Year high/low print(f"2024 KOSPI High: {kospi_index['고가'].max():,}") print(f"2024 KOSPI Low: {kospi_index['저가'].min():,}") Example 6: Foreign Investor Trading Data from pykrx import stock # Foreign net buying/selling for Samsung df = stock.get_market_trading_volume_by_date( "20240101", "20241231", "005930" ) print(df.tail()) # Days with heavy foreign buying foreign_buying = df[df["외국인"] > 1000000] print(f"Heavy foreign buying days: {len(foreign_buying)}") Example 7: Sector Performance from pykrx import stock # Get sector (theme) data # Major KOSPI sector tickers sectors = { "1001": "KOSPI", "1028": "KOSPI200", "2001": "KOSDAQ", "1163": "KOSPI IT", "1150": "KOSPI Finance" } for code, name in sectors.items(): df = stock.get_index_ohlcv_by_date(MONTH_AGO, TODAY, code) if not df.empty: start = df["종가"].iloc[0] end = df["종가"].iloc[-1] change = (end - start) / start * 100 print(f"{name}: {change:+.2f}%") Example 8: Volume Surge Detector from pykrx import stock import pandas as pd def find_volume_surges(market="KOSPI", multiplier=3.0): """Find stocks with volume 3x above their 20-day average""" tickers = stock.get_market_ticker_list(market=market) surges = [] for ticker in tickers[:50]: # Limit for demo try: df = stock.get_market_ohlcv_by_date(MONTH_AGO, TODAY, ticker) if len(df) < 20: continue avg_vol = df["거래량"].iloc[:-1].mean() today_vol = df["거래량"].iloc[-1] if today_vol > avg_vol * multiplier: name = stock.get_market_ticker_name(ticker) surges.append({ "ticker": ticker, "name": name, "volume_ratio": today_vol / avg_vol, "close": df["종가"].iloc[-1] }) except: continue return sorted(surges, key=lambda x: x["volume_ratio"], reverse=True) surges = find_volume_surges() for s in surges[:5]: print(f"{s['name']}: {s['volume_ratio']:.1f}x average volume") Example 9: Simple Backtesting from pykrx import stock import pandas as pd def backtest_moving_average(ticker, short=5, long=20): """Simple moving average crossover backtest""" df = stock.get_market_ohlcv_by_date("20230101", "20241231", ticker) df.columns = ["Open", "High", "Low", "Close", "Volume"] df[f"MA{short}"] = df["Close"].rolling(short).mean() df[f"MA{long}"] = df["Close"].rolling(long).mean() # Signal: 1 = buy, -1 = sell df["signal"] = 0 df.loc[df[f"MA{short}"] > df[f"MA{long}"], "signal"] = 1 df.loc[df[f"MA{short}"] < df[f"MA{long}"], "signal"] = -1 # Returns df["returns"] = df["Close"].pct_change() df["strategy"] = df["signal"].shift(1) * df["returns"] total_return = (1 + df["strategy"].dropna()).prod() - 1 buy_hold = (df["Close"].iloc[-1] - df["Close"].iloc[0]) / df["Close"].iloc[0] print(f"Strategy return: {total_return:.2%}") print(f"Buy & hold return: {buy_hold:.2%}") return df result = backtest_moving_average("005930") Example 10: Export to Excel from pykrx import stock import pandas as pd # Get data for multiple stocks watchlist = { "005930": "Samsung Electronics", "000660": "SK Hynix", "373220": "LG Energy Solution", "005380": "Hyundai Motor", "035420": "NAVER" } with pd.ExcelWriter("korean_stocks.xlsx") as writer: for ticker, name in watchlist.items(): df = stock.get_market_ohlcv_by_date("20240101", "20241231", ticker) df.columns = ["Open", "High", "Low", "Close", "Volume"] df.to_excel(writer, sheet_name=name[:30]) print(f"Saved {name}") print("Excel file created: korean_stocks.xlsx") Common Mistakes Mistake Fix Date with dashes "2024-01-01" Remove dashes: "20240101" Using company name as ticker Use 6-digit number: "005930" Calling too frequently Add time.sleep(0.5) between calls Empty result on weekends KRX is closed Sat/Sun Key Takeaways pykrx is free and requires no API key Date format is always YYYYMMDD Column names default to Korean — rename for easier use Add delays between multiple API calls to avoid rate limiting For real-time data and trading, use KIS API instead Related Guides pykrx get_market_ohlcv_by_date: Complete Guide Build a Korean Stock Screener with pykrx KIS API vs pykrx: Which Should You Use?

July 8, 2026 · Phillip

pykrx vs FinanceDataReader: Which is Better for Korean Stocks?

Overview When building a Korean stock data pipeline in Python, you’ll encounter two popular libraries: pykrx and FinanceDataReader. Both are free and open-source, but they have different strengths. What is pykrx? pykrx is a Python library that pulls data directly from the KRX (Korea Exchange) website. It is focused exclusively on Korean markets. Install: pip install pykrx What is FinanceDataReader? FinanceDataReader (FDR) is a broader financial data library that supports Korean stocks, US stocks, ETFs, crypto, and more — all through a unified API. ...

July 7, 2026 · Phillip

KIS API Setup Guide: Step-by-Step for Beginners (2026)

What is the KIS API? The KIS API (Korea Investment & Securities API) is a REST/WebSocket API that allows developers to: Get real-time stock quotes Place buy/sell orders programmatically Access account balance and portfolio data Stream real-time market data via WebSocket Prerequisites A Korea Investment & Securities brokerage account KIS API access approval Python 3.8+ installed Step 1: Open a KIS Account Visit the Korea Investment & Securities website and apply for an account. Foreigners can apply online in many cases. ...

June 21, 2026 · Phillip

How to Get Your KIS API Key — Complete Guide (2026)

Overview Getting a KIS API key requires a Korea Investment & Securities account. This guide walks you through the entire process. Requirements Valid ID (passport for foreigners) Korean phone number OR Korea-based identity verification Bank account for funding Step 1: Create KIS Account Visit the Korea Investment & Securities website and select non-face-to-face account opening. For foreigners: Prepare your passport You may need to visit a branch in person depending on your nationality Some nationalities can complete the process online Step 2: Enable API Trading Log into HTS or the mobile app Go to the API application menu Agree to terms and conditions Select API type: Real trading or Paper trading (모의투자) Tip: Start with Paper trading to test your code before using real money. ...

June 20, 2026 · Phillip

pykrx Tutorial: Pull Korean Stock Data with Python (2026)

What is pykrx? pykrx is an open-source Python library that pulls data from the KRX website. It is the easiest way to get Korean stock market data without needing a paid API. Installation pip install pykrx Basic Usage Get Stock Price History from pykrx import stock # Get Samsung Electronics (005930) price history df = stock.get_market_ohlcv_by_date("20240101", "20241231", "005930") print(df.head()) Get All KOSPI Tickers from pykrx import stock # Get all KOSPI tickers tickers = stock.get_market_ticker_list(market="KOSPI") print(f"Total KOSPI stocks: {len(tickers)}") # Get company name from ticker name = stock.get_market_ticker_name("005930") print(f"005930 = {name}") # Samsung Electronics Get Market Cap Data # Get market cap for all KOSPI stocks df = stock.get_market_cap_by_ticker("20241231", market="KOSPI") print(df.sort_values("시가총액", ascending=False).head(10)) Get Fundamental Data # Get PER, PBR, dividend yield df = stock.get_market_fundamental_by_ticker("20241231", market="KOSPI") print(df[["PER", "PBR", "DIV"]].head()) Building a Simple Screener from pykrx import stock def screen_low_per_stocks(market="KOSPI", max_per=10): today = "20241231" fundamentals = stock.get_market_fundamental_by_ticker(today, market=market) low_per = fundamentals[ (fundamentals["PER"] > 0) & (fundamentals["PER"] < max_per) ] low_per["name"] = [stock.get_market_ticker_name(t) for t in low_per.index] return low_per[["name", "PER", "PBR", "DIV"]].sort_values("PER") results = screen_low_per_stocks() print(results.head(20)) pykrx vs KIS API Comparison Feature pykrx KIS API Real-time data No Yes Historical data Yes Yes Order placement No Yes Cost Free Free (with account) Best for Research, backtesting Live trading

June 19, 2026 · Phillip

Build a Korean Stock Screener with pykrx (Python Tutorial)

What We’re Building A Python-based Korean stock screener that: Pulls data from KRX via pykrx Filters stocks by multiple criteria (PER, PBR, volume) Exports results to CSV Can be automated with GitHub Actions Setup pip install pykrx pandas Complete Screener Code from pykrx import stock import pandas as pd from datetime import datetime, timedelta class KoreanStockScreener: def __init__(self, market="KOSPI"): self.market = market self.today = datetime.now().strftime("%Y%m%d") def get_all_data(self): fundamentals = stock.get_market_fundamental_by_ticker( self.today, market=self.market ) market_cap = stock.get_market_cap_by_ticker( self.today, market=self.market ) df = pd.concat([fundamentals, market_cap[["시가총액", "거래량"]]], axis=1) df["name"] = [stock.get_market_ticker_name(t) for t in df.index] return df def screen(self, max_per=15, max_pbr=1.5, min_div=2.0, min_volume=100000): df = self.get_all_data() filtered = df[ (df["PER"] > 0) & (df["PER"] < max_per) & (df["PBR"] > 0) & (df["PBR"] < max_pbr) & (df["DIV"] > min_div) & (df["거래량"] > min_volume) ] return filtered[["name", "PER", "PBR", "DIV", "시가총액", "거래량"]] def export(self, df, filename="screener_results.csv"): df.to_csv(filename, encoding="utf-8-sig") print(f"Saved {len(df)} stocks to {filename}") # Run screener screener = KoreanStockScreener(market="KOSPI") results = screener.screen(max_per=12, max_pbr=1.2, min_div=3.0) print(results.head(20)) screener.export(results) Automating with GitHub Actions Create .github/workflows/screener.yml: ...

June 18, 2026 · Phillip

Automate Korean Stock Alerts with GitHub Actions

Overview In this guide, we’ll build a free automated stock alert system that: Runs every day at market open (9 AM KST) Screens Korean stocks using pykrx Sends alerts via Telegram Requires zero server infrastructure (GitHub Actions is free) Prerequisites GitHub account Telegram account Basic Python knowledge Step 1: Create a Telegram Bot Open Telegram and search for @BotFather Send /newbot command Choose a name and username for your bot Save the API token you receive Step 2: Get Your Chat ID Send a message to your new bot Visit: https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates Find your chat_id in the response Step 3: Create the Alert Script # alert.py import requests from pykrx import stock from datetime import datetime import os TELEGRAM_TOKEN = os.environ["TELEGRAM_TOKEN"] TELEGRAM_CHAT_ID = os.environ["TELEGRAM_CHAT_ID"] def send_telegram(message): url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage" payload = {"chat_id": TELEGRAM_CHAT_ID, "text": message, "parse_mode": "HTML"} requests.post(url, json=payload) def get_top_movers(): today = datetime.now().strftime("%Y%m%d") df = stock.get_market_ohlcv_by_ticker(today, market="KOSPI") df["change_pct"] = (df["종가"] - df["시가"]) / df["시가"] * 100 top_gainers = df.nlargest(5, "change_pct") return top_gainers def main(): movers = get_top_movers() message = "<b>Korean Market Alert - Top Movers Today</b>\n\n" for ticker, row in movers.iterrows(): name = stock.get_market_ticker_name(ticker) message += f"{name} ({ticker}): +{row['change_pct']:.1f}%\n" send_telegram(message) if __name__ == "__main__": main() Step 4: GitHub Actions Workflow Create .github/workflows/alert.yml: ...

June 17, 2026 · Phillip

KIS API vs pykrx: Which Should You Use for Korean Stock Trading?

Overview If you’re building a Korean stock trading system in Python, you’ll encounter two main tools: KIS API and pykrx. Here’s a detailed breakdown of when to use each. What is pykrx? pykrx is an open-source library that scrapes publicly available data from the KRX website. It requires no account or API key. Best for: Historical data research Backtesting trading strategies Stock screening and analysis Learning and prototyping What is KIS API? KIS API is the official API from Korea Investment & Securities. It requires a brokerage account and API approval. ...

June 16, 2026 · Phillip

How I Built an Automated Korean Stock Trading Bot (KIS API + Python)

Background I’ve been actively trading Korean stocks on the KOSPI and KOSDAQ for years. After spending too many hours watching charts, I decided to automate part of my trading strategy using the KIS API. This post shares what I built, what worked, and what I learned — including mistakes. The Strategy My bot focuses on momentum scalping on KOSPI stocks: Screen for stocks with high volume breakouts in the first 30 minutes Enter positions with defined risk (1-2% of account per trade) Exit on target profit or stop loss Maximum 3 concurrent positions System Architecture GitHub Actions (scheduler) ↓ Python Script ↓ ↓ ↓ KIS API pykrx Telegram Bot (trading) (data) (alerts) Core Components 1. Market Scanner from pykrx import stock import pandas as pd def scan_breakouts(min_volume_ratio=2.0): """Find stocks with unusual volume""" today = stock.get_market_ticker_list(market="KOSPI") breakouts = [] for ticker in today[:100]: # Limit for demo try: df = stock.get_market_ohlcv_by_date( prev_date, today_date, ticker ) if len(df) < 20: continue avg_volume = df["거래량"].mean() current_volume = df["거래량"].iloc[-1] if current_volume > avg_volume * min_volume_ratio: breakouts.append({ "ticker": ticker, "volume_ratio": current_volume / avg_volume }) except: continue return sorted(breakouts, key=lambda x: x["volume_ratio"], reverse=True) 2. Order Execution (KIS API) def place_market_order(ticker, quantity, order_type="buy", token=None): url = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/trading/order-cash" tr_id = "TTTC0802U" if order_type == "buy" else "TTTC0801U" headers = { "authorization": f"Bearer {token}", "appkey": APP_KEY, "appsecret": APP_SECRET, "tr_id": tr_id } body = { "CANO": ACCOUNT_NO, "ACNT_PRDT_CD": "01", "PDNO": ticker, "ORD_DVSN": "01", # Market order "ORD_QTY": str(quantity), "ORD_UNPR": "0" } res = requests.post(url, headers=headers, json=body) return res.json() Key Lessons Learned What Worked Automating the scanning phase saved significant time Telegram alerts for signals I review manually before execution Strict position sizing rules enforced by code What Did Not Work Fully automated execution without human review (too many false signals) Running during the first 5 minutes of market open (too volatile) Ignoring market regime (bot designed for trending markets struggled in choppy conditions) Risk Management Rules Never risk more than 2% of account per trade Maximum 3 concurrent positions Hard daily loss limit of 5% — bot stops automatically No trading during major news events Current Status The bot currently runs in semi-automated mode: it scans and sends signals via Telegram, but I manually approve each trade before execution. This hybrid approach has been more profitable than either full automation or pure manual trading.

June 10, 2026 · Phillip