flowchart TD
A[<b>1. Data Fetching</b><br/>ดึงข้อมูลผ่าน API/Web Scraping] --> B[<b>2. Cleaning</b><br/>จัดการค่าว่างและ Outliers]
B --> C[<b>3. Transformation</b><br/>Log Transform / Seasonal Adjustment]
C --> D[<b>4. Analysis & Modeling</b><br/>ทดสอบสมมติฐานทางเศรษฐมิติ]
D --> E[<b>5. Communication</b><br/>สร้าง Visualisation เพื่อการตัดสินใจ]
style A fill:#e1f5fe,stroke:#01579b
style E fill:#fff3e0,stroke:#e65100
6 การจัดการข้อมูลจริงและการเชื่อมต่อแหล่งข้อมูลภายนอก
Python for Economics, Computational Economics, Applied Econometrics, Python สำหรับเศรษฐศาสตร์, เศรษฐศาสตร์คำนวณ, เศรษฐมิติเชิงประยุกต์
ในบทก่อนหน้า เราได้เรียนรู้การจัดการข้อมูลด้วย Pandas ผ่านชุดข้อมูลตัวอย่างที่ถูกคัดสรรมาอย่างดี อย่างไรก็ตาม ในการทำงานจริง นักเศรษฐศาสตร์ไม่ได้เริ่มต้นจากข้อมูลที่ “สะอาดและพร้อมใช้งาน” เสมอไป
❗ The 80/20 Rule of Data Science: นักเศรษฐศาสตร์ส่วนใหญ่มักใช้เวลาถึง 80% ของโครงการไปกับการดึงข้อมูลและทำความสะอาดข้อมูล (Data Cleaning) และเหลือเวลาเพียง 20% สำหรับการวิเคราะห์เชิงลึก
6.1 แหล่งที่มาของข้อมูลทางเศรษฐศาสตร์ในยุคดิจิทัล
ข้อมูลทางเศรษฐศาสตร์และการเงินในปัจจุบันไม่ได้จำกัดอยู่เพียงแค่ไฟล์ Excel ในรายงานประจำปี แต่กระจายตัวอยู่ในรูปแบบที่หลากหลาย:
สถาบันระดับมหภาค: ข้อมูล GDP, อัตราเงินเฟ้อ และนโยบายการเงิน จากธนาคารแห่งประเทศไทย (BOT), สำนักงานสภาพัฒนาการเศรษฐกิจและสังคมแห่งชาติ (สศช.), หรือระดับโลกอย่าง World Bank และ IMF
ตลาดการเงินและสินทรัพย์ดิจิทัล: ข้อมูลราคาหุ้นรายนาที, ดัชนีความผันผวน (VIX), หรือแม้แต่อัตราแลกเปลี่ยนสกุลเงินดิจิทัล ซึ่งเข้าถึงได้ผ่าน API (Application Programming Interface)
Alternative Data: ข้อมูลทางเลือกใหม่ๆ เช่น ดัชนีราคาจากเว็บบอร์ดค้าปลีก, ข้อมูลการเคลื่อนย้ายประชากร หรือข้อมูลจากดาวเทียมที่สะท้อนกิจกรรมทางเศรษฐกิจ
6.1.1 ลักษณะและข้อจำกัดของข้อมูลในโลกของการทำงานจริง
ก่อนจะเริ่มเขียนโค้ดบรรทัดแรก นักเศรษฐศาสตร์ต้องตระหนักถึง “ธรรมชาติ” ของข้อมูลจริง ซึ่งมักจะมีลักษณะดังนี้:
ความไม่สมบูรณ์ (Missingness): ข้อมูลบางช่วงอาจหายไปเนื่องจากวันหยุดทำการของตลาด หรือความล่าช้าในการรายงานผลของหน่วยงาน
ความไม่สอดคล้อง (Inconsistency): เช่น ข้อมูลรายได้สะสมถูกรายงานเป็นรายไตรมาส แต่ข้อมูลราคาหุ้นถูกรายงานรายวัน การนำมารวมกันต้องใช้เทคนิคการปรับความถี่ (Resampling)
ปัญหาด้านมาตราส่วน (Scale Issues): ตัวแปรหนึ่งอาจมีหน่วยเป็น “ล้านล้านบาท” (GDP) ในขณะที่อีกตัวแปรมีหน่วยเป็น “เปอร์เซ็นต์” (Interest Rate) การจัดการ Scale จึงสำคัญมากต่อความแม่นยำของแบบจำลอง
6.1.2 จากข้อมูลดิบสู่บทสรุปทางนโยบาย: Pipeline การทำงาน
กระบวนการทำงานจริงของนักเศรษฐศาสตร์สมัยใหม่สามารถสรุปเป็นลำดับขั้นตอน (Workflow) ที่เป็นระบบได้ดังนี้:
6.2 yfinance: ประตูสู่ฐานข้อมูลการเงินระดับโลก
ในบทก่อนหน้า เราได้ทำความรู้จักกับโครงสร้างข้อมูลและการจัดการ DataFrame ไปแล้ว แต่คำถามสำคัญสำหรับนักเศรษฐศาสตร์คือ “เราจะเอาข้อมูลจริงจำนวนมหาศาลเหล่านั้นมาใส่ใน Python ได้อย่างไรโดยไม่ต้องนั่งพิมพ์เอง?”
คำตอบที่เป็นมาตรฐานสากลสำหรับผู้เริ่มต้นจนถึงระดับมืออาชีพคือการใช้ไลบรารี yfinance ครับ
6.2.1 yfinance คืออะไร?
yfinance เป็น Open-source Library ที่ทำหน้าที่เป็น “สะพานเชื่อม” (API Wrapper) ระหว่าง Python กับฐานข้อมูลมหาศาลของ Yahoo Finance ซึ่งครอบคลุมข้อมูลสินทรัพย์เกือบทุกประเภททั่วโลก
สิ่งที่นักเศรษฐศาสตร์จะได้รับจากเครื่องมือนี้: * Historical Data: ราคาเปิด-ปิด (Open/Close), ราคาสูงสุด-ต่ำสุด (High/Low) และราคาที่ปรับปรุงแล้ว (Adjusted Close) ซึ่งสำคัญมากในการคำนวณผลตอบแทนที่แท้จริง
Global Coverage: ไม่ใช่แค่หุ้นในสหรัฐฯ แต่รวมถึงหุ้นในตลาดหลักทรัพย์แห่งประเทศไทย (เช่น
PTT.BK), อัตราแลกเปลี่ยน (USDTHB=X), และดัชนีระดับโลก เช่น S&P 500 (^GSPC)Financial Fundamentals: ข้อมูล งบการเงิน, งบกระแสเงินสด และอัตราส่วนทางการเงินเบื้องต้น
6.2.2 ทำไมต้องใช้ yfinance ในงานวิจัยเศรษฐศาสตร์?
นักเศรษฐศาสตร์ยุคใหม่ใช้ yfinance ในสถานการณ์ที่ต้องการ ความรวดเร็วและความแม่นยำ (Efficiency & Precision):
การวิเคราะห์ผลตอบแทน (Return Analysis): เพื่อศึกษาความสัมพันธ์ระหว่างนโยบายการเงินกับราคาหลักทรัพย์
การศึกษาความผันผวน (Volatility Study): เช่น การประเมินความเสี่ยงในช่วงวิกฤตเศรษฐกิจ หรือช่วงที่มีการเปลี่ยนแปลงทางการเมือง
การสร้างพอร์ตโฟลิโอจำลอง (Portfolio Optimization): เพื่อทดสอบทฤษฎีการลงทุนด้วยข้อมูลจริงย้อนหลังหลายสิบปี
6.2.3 บทบาทของ yfinance ในการทำงานอัตโนมัติ (Automation Workflow)
หนึ่งในจุดเด่นที่อาจารย์ควรเน้นย้ำคือนักศึกษาจะไม่ได้แค่ “ดึงข้อมูล” แต่กำลังสร้าง “ท่อส่งข้อมูล” (Data Pipeline):
flowchart TD
A[Yahoo Finance Database] -- "yfinance.download()" --> B{Python Environment}
B --> C[<b>Pandas DataFrame</b><br/>จัดระเบียบข้อมูล]
C --> D[<b>Analysis</b><br/>คำนวณ Return / Risk]
D --> E[<b>Visualization</b><br/>สร้างกราฟเทรนด์เศรษฐกิจ]
style B fill:#f9f,stroke:#333
style C fill:#e1f5fe,stroke:#01579b
6.2.4 การปฏิวัติกระบวนการทำงาน: จาก Manual สู่ Programmatic
งความแตกต่างระหว่าง “นักเศรษฐศาสตร์ยุคเก่า” กับ “นักเศรษฐศาสตร์ยุคใหม่” ได้
| ลักษณะการทำงาน | วิธีแบบเดิม (Traditional) | วิธีแบบใหม่ (Modern) |
|---|---|---|
| การดึงข้อมูล | เข้าเว็บ -> กดโหลด CSV -> เซฟลงเครื่อง | เขียนโค้ด 1 บรรทัดดึงเข้าเมมโมรี่ทันที |
| ความต่อเนื่อง | ข้อมูลจบที่วันที่โหลด ต้องโหลดใหม่เพื่ออัปเดต | รันสคริปต์เดิม ข้อมูลจะอัปเดตถึงวันล่าสุดอัตโนมัติ |
| ความผิดพลาด | อาจคัดลอกผิด (Human Error) | ข้อมูลส่งตรงจาก Server แม่นยำตามแหล่งข่าว |
| การส่งต่องาน | ต้องส่งไฟล์ Excel หลายๆ ไฟล์ | ส่งแค่สคริปต์ Python ไฟล์เดียว เพื่อนรันได้ผลเหมือนกัน |
6.3 การดึงข้อมูลหุ้น (Download Financial Data)
หัวใจสำคัญของการวิเคราะห์เศรษฐศาสตร์การเงินคือการเข้าถึงข้อมูลที่แม่นยำ ในส่วนนี้เราจะเปลี่ยนจากการใช้ข้อมูลสมมติ มาเป็นการดึง “ข้อมูลจริงจากตลาดโลก” โดยใช้เทคนิคการดึงข้อมูลผ่าน Ticker Symbol
6.3.1 โจทย์ทางเศรษฐศาสตร์: การศึกษาพฤติกรรมราคาสินทรัพย์
ในทางเศรษฐศาสตร์ เรามักตั้งคำถามว่า: > “ปัจจัยภายนอก (เช่น นโยบายดอกเบี้ย) ส่งผลต่อราคาหุ้น Apple (AAPL) อย่างไรในช่วง 5 ปีที่ผ่านมา?”
ก่อนจะตอบคำถามนั้นได้ เราต้องมีชุดข้อมูล Time Series ที่สมบูรณ์เสียก่อน
6.3.2 เจาะลึกองค์ประกอบของ Financial DataFrame
ข้อมูลที่ yfinance ส่งกลับมานั้นไม่ใช่แค่ตารางธรรมดา แต่เป็น Multi-column Time Series ที่มีโครงสร้างดังนี้:
| คอลัมน์ | คำอธิบายเชิงเศรษฐศาสตร์ |
|---|---|
| Open / Close | ราคาเปิดและปิดตลาด สะท้อนการประมวลผลข้อมูลของนักลงทุนในช่วงเริ่มต้นและสิ้นสุดวัน |
| High / Low | ราคาสูงสุดและต่ำสุด สะท้อนความผันผวน (Volatility) และช่วงการซื้อขาย (Trading Range) |
| Adj Close | ราคาปิดที่ปรับปรุงแล้ว (Adjusted Close) คือคอลัมน์ที่สำคัญที่สุดสำหรับนักเศรษฐศาสตร์ เพราะมีการปรับมูลค่าจากการแตกหุ้น (Stock Splits) และการจ่ายปันผล (Dividends) แล้ว |
| Volume | ปริมาณการซื้อขาย สะท้อนสภาพคล่อง (Liquidity) และความเชื่อมั่นของตลาด |
6.3.3 การจัดการข้อมูลหลายชุด (Multiple Tickers)
ในการวิเคราะห์เปรียบเทียบ (Comparative Analysis) เช่น การศึกษาความสัมพันธ์ระหว่างหุ้นกลุ่มเทคโนโลยี เราสามารถดึงข้อมูลพร้อมกันได้:
คลิกเพื่อดูโค้ดไพธอน
import yfinance as yf
assets = ["AAPL", "MSFT"]
# เพิ่ม auto_adjust=False เพื่อให้แสดงคอลัมน์ Adj Close แยกออกมาชัดเจน
data_multi = yf.download(assets, start="2020-01-01", auto_adjust=False)
# ลองตรวจสอบชื่อคอลัมน์ทั้งหมดก่อน
print(data_multi.columns)
# เรียกใช้ Adj Close
display(data_multi['Adj Close'].head())MultiIndex([('Adj Close', 'AAPL'),
('Adj Close', 'MSFT'),
( 'Close', 'AAPL'),
( 'Close', 'MSFT'),
( 'High', 'AAPL'),
( 'High', 'MSFT'),
( 'Low', 'AAPL'),
( 'Low', 'MSFT'),
( 'Open', 'AAPL'),
( 'Open', 'MSFT'),
( 'Volume', 'AAPL'),
( 'Volume', 'MSFT')],
names=['Price', 'Ticker'])
| Ticker | AAPL | MSFT |
|---|---|---|
| Date | ||
| 2020-01-02 | 72.400513 | 152.158386 |
| 2020-01-03 | 71.696648 | 150.263733 |
| 2020-01-06 | 72.267944 | 150.652145 |
| 2020-01-07 | 71.928062 | 149.278549 |
| 2020-01-08 | 73.085106 | 151.656281 |
โครงสร้างข้อมูลที่ควรสังเกต
graph TD
A[<b>Datetime Index</b><br/>วันที่ที่ตลาดเปิดทำการ] --- B[<b>Ticker 1: AAPL</b><br/>Open, Close, Adj Close...]
A --- C[<b>Ticker 2: MSFT</b><br/>Open, Close, Adj Close...]
style A fill:#fff3e0,stroke:#e65100
style B fill:#e1f5fe,stroke:#01579b
style C fill:#e1f5fe,stroke:#01579b
6.4 การดึงข้อมูลหลายประเภท (Ticker Symbols)
หัวใจของการใช้ yfinance คือการรู้จักรหัส (Ticker) ของสิ่งที่เราต้องการ นักเศรษฐศาสตร์มักใช้รหัสมาตรฐานดังนี้:
หุ้นไทย: ชื่อหุ้นตามด้วย
.BKเช่นPTT.BK,CPALL.BKอัตราแลกเปลี่ยน:
USDTHB=X(ดอลลาร์เทียบเงินบาท)สินค้าโภคภัณฑ์:
CL=F(น้ำมันดิบ Crude Oil),GC=F(ราคาทองคำ)ดัชนีตลาด:
^SET.BK(ดัชนีตลาดหุ้นไทย),^GSPC(S&P 500)
6.4.1 การดึงข้อมูลหลายหลักทรัพย์ (Multi-Asset Analysis)
การวิเคราะห์ความสัมพันธ์ระหว่างตัวแปร เช่น ผลกระทบของราคาน้ำมันต่อค่าเงินบาท หรือดัชนีตลาดหุ้นต่างประเทศ
Argument ที่สำคัญ:
tickers: ใส่เป็น List ของรหัสที่ต้องการperiod: กำหนดช่วงเวลาย้อนหลัง (เช่น2y)group_by: ตั้งเป็น'column'(ค่าเริ่มต้น) เพื่อให้ได้ตารางที่เปรียบเทียบราคาปิดของทุกตัวได้ง่าย
คลิกเพื่อดูโค้ดไพธอน
import yfinance as yf
import pandas as pd
# ดึงข้อมูลราคาน้ำมันโลก (CL=F), ดัชนีหุ้นสหรัฐฯ (^GSPC) และหุ้นไทย (PTT.BK)
assets = ["CL=F", "^GSPC", "PTT.BK"]
df = yf.download(tickers=assets, period="2y")
# เลือกเฉพาะราคาปิด (Close) มาแสดงผล
display(df['Close'].tail())| Ticker | CL=F | PTT.BK | ^GSPC |
|---|---|---|---|
| Date | |||
| 2026-04-23 | 95.849998 | 35.00 | 7108.399902 |
| 2026-04-24 | 94.400002 | 34.75 | 7165.080078 |
| 2026-04-27 | 96.370003 | 35.25 | 7173.910156 |
| 2026-04-28 | 99.930000 | 35.25 | 7138.799805 |
| 2026-04-29 | 105.019997 | 35.25 | 7140.470215 |
6.4.2 การกำหนดช่วงเวลาแบบเจาะจง (Event Study)
ใช้เมื่อต้องการวิเคราะห์เหตุการณ์เฉพาะช่วง เช่น วิกฤตการณ์เศรษฐกิจ หรือช่วงที่มีนโยบายสำคัญ
Argument ที่สำคัญ:
startและend: กำหนดวันที่เริ่มต้นและสิ้นสุดในรูปแบบYYYY-MM-DD
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลดัชนี SET ช่วงปี 2023 เพื่อวิเคราะห์ความผันผวน
df_event = yf.download(
tickers="^SET.BK",
start="2023-01-01",
end="2023-12-31")
display(df_event.head())| Price | Close | High | Low | Open | Volume |
|---|---|---|---|---|---|
| Ticker | ^SET.BK | ^SET.BK | ^SET.BK | ^SET.BK | ^SET.BK |
| Date | |||||
| 2023-01-03 | 1678.969971 | 1683.380005 | 1673.290039 | 1675.699951 | 4618100 |
| 2023-01-04 | 1673.250000 | 1685.109985 | 1668.069946 | 1680.069946 | 5777500 |
| 2023-01-05 | 1663.859985 | 1676.819946 | 1659.900024 | 1674.810059 | 6321200 |
| 2023-01-06 | 1673.859985 | 1677.790039 | 1665.489990 | 1667.140015 | 4912600 |
| 2023-01-09 | 1691.119995 | 1693.420044 | 1684.900024 | 1685.300049 | 4677700 |
6.4.3 การปรับความถี่ข้อมูล (Macro Analysis)
ข้อมูลรายวันอาจมี Noise มากเกินไป นักเศรษฐศาสตร์มักใช้ข้อมูลรายสัปดาห์หรือรายเดือนเพื่อดูภาพรวมเชิงโครงสร้าง
Argument ที่สำคัญ: * interval: กำหนดความถี่ เช่น 1wk (รายสัปดาห์) หรือ 1mo (รายเดือน)
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลอัตราแลกเปลี่ยน USD/THB ย้อนหลัง 5 ปี แบบรายเดือน
usd_thb = yf.download(
tickers="USDTHB=X",
period="5y",
interval="1mo")
display(usd_thb.tail())| Price | Close | High | Low | Open | Volume |
|---|---|---|---|---|---|
| Ticker | USDTHB=X | USDTHB=X | USDTHB=X | USDTHB=X | USDTHB=X |
| Date | |||||
| 2025-12-01 | 31.450001 | 32.139999 | 30.990000 | 32.020000 | 0 |
| 2026-01-01 | 31.230000 | 31.600000 | 30.820000 | 31.500000 | 0 |
| 2026-02-01 | 31.080000 | 31.879999 | 30.920000 | 31.375000 | 0 |
| 2026-03-01 | 32.849998 | 33.056999 | 31.110001 | 31.135000 | 0 |
| 2026-04-01 | 32.730000 | 32.801998 | 31.724001 | 32.529999 | 0 |
6.4.4 การดึงข้อมูลราคาที่ปรับแล้ว (True Return Calculation)
สำหรับการคำนวณผลตอบแทนที่แท้จริง ต้องใช้ราคาที่ปรับปรุงผลจากการจ่ายปันผลและการแตกหุ้นแล้วเท่านั้น
Argument ที่สำคัญ:
auto_adjust=True: ระบบจะคำนวณราคาปิดที่ปรับแล้ว (Adjusted Close) ให้โดยอัตโนมัติ
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลหุ้นที่จ่ายปันผลสูง (เช่น ADVANC.BK) แบบปรับราคาอัตโนมัติ
advanc = yf.download(
tickers="ADVANC.BK",
period="5y",
auto_adjust=True)
# ราคาในคอลัมน์ Close จะเป็นราคาที่รวมผลตอบแทนจากปันผลแล้ว
display(advanc['Close'].tail())| Ticker | ADVANC.BK |
|---|---|
| Date | |
| 2026-04-23 | 345.0 |
| 2026-04-24 | 349.0 |
| 2026-04-27 | 348.0 |
| 2026-04-28 | 349.0 |
| 2026-04-29 | 348.0 |
6.4.5 การดึงข้อมูลพื้นฐานและเงินปันผล (Fundamental & Corporate Actions)
นอกเหนือจากราคา ข้อมูลการจ่ายปันผลเป็นดัชนีชี้วัดสุขภาพของบริษัทในมุมมองเศรษฐศาสตร์จุลภาค
วิธีการ: ใช้ yf.Ticker เพื่อเข้าถึง Metadata ของบริษัท
คลิกเพื่อดูโค้ดไพธอน
ticker_info = yf.Ticker("CPALL.BK")
# ดึงประวัติการจ่ายเงินปันผล (Dividends)
dividends = ticker_info.dividends
display(dividends.tail())Date
2021-05-05 10:00:00+07:00 0.90
2022-04-28 10:00:00+07:00 0.60
2023-05-02 10:00:00+07:00 0.75
2024-05-07 10:00:00+07:00 1.00
2025-05-06 10:00:00+07:00 1.35
Name: Dividends, dtype: float64
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลผู้ถือหุ้นรายใหญ่ (Major Holders)
holders = ticker_info.major_holders
display(holders)| Breakdown | Value |
|---|---|
| insidersPercentHeld | 0.43845 |
| institutionsPercentHeld | 0.12196 |
| institutionsFloatPercentHeld | 0.21718 |
| institutionsCount | 61.00000 |
6.5 การจัดการข้อมูลจาก yfinance (Data Wrangling)
ข้อมูลดิบที่ดึงมาจาก yfinance มักอยู่ในรูปของ “ระดับราคา” (Price Level) ซึ่งในทางเศรษฐมิติมักจะมีปัญหาความไม่นิ่ง (Non-stationary) เราจึงต้องเรียนรู้วิธีการแปลงข้อมูลให้อยู่ในรูปของผลต่างหรือผลตอบแทนก่อนนำไปวิเคราะห์
6.5.1 การคำนวณผลตอบแทนและผลต่าง (Returns & Differences)
ในงานวิจัยเรานิยมแปลงราคาให้เป็นค่าที่สามารถเปรียบเทียบกันได้ข้ามเวลา ดังนี้:
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลดัชนีหุ้นไทย และอัตราแลกเปลี่ยน
df = yf.download(["^SET.BK", "USDTHB=X"], period="1y")['Close']
# 1. การหาผลต่างธรรมดา (First Difference) - ใช้คำสั่ง .diff()
# เหมาะสำหรับตัวแปรอย่าง อัตราดอกเบี้ย หรือเพื่อกำจัดแนวโน้ม (Trend)
df_diff = df.diff()
# แสดงผลลัพธ์เบื้องต้น
display(df_diff.head())| Ticker | USDTHB=X | ^SET.BK |
|---|---|---|
| Date | ||
| 2025-04-29 | NaN | NaN |
| 2025-04-30 | 0.090000 | 26.140015 |
| 2025-05-01 | -0.010002 | NaN |
| 2025-05-02 | 0.090000 | NaN |
| 2025-05-05 | -0.419998 | NaN |
คลิกเพื่อดูโค้ดไพธอน
# 2. การคำนวณผลตอบแทนปกติ (Simple Return) - ใช้คำสั่ง .pct_change()
# คิดเป็นเปอร์เซ็นต์ส่วนเปลี่ยนแปลงเทียบกับวันก่อนหน้า
df_return = df.pct_change() * 100
# แสดงผลลัพธ์เบื้องต้น
display(df_return.tail())| Ticker | USDTHB=X | ^SET.BK |
|---|---|---|
| Date | ||
| 2026-04-23 | 0.217525 | -1.242787 |
| 2026-04-24 | 0.713177 | -0.359257 |
| 2026-04-27 | -0.184733 | 1.581624 |
| 2026-04-28 | -0.215915 | 0.072336 |
| 2026-04-29 | 1.174656 | 0.779627 |
คลิกเพื่อดูโค้ดไพธอน
import numpy as np
# 3. การคำนวณ Log Return (นิยมที่สุดในงานวิจัยเศรษฐศาสตร์)
# สูตร: ln(Pt) - ln(Pt-1) ช่วยให้ข้อมูลมีการกระจายตัวที่ดีขึ้น
df_log_return = np.log(df).diff()
# แสดงผลลัพธ์เบื้องต้น
display(df_log_return.tail())| Ticker | USDTHB=X | ^SET.BK |
|---|---|---|
| Date | ||
| 2026-04-23 | 0.002173 | -0.012506 |
| 2026-04-24 | 0.007106 | -0.003599 |
| 2026-04-27 | -0.001849 | 0.015692 |
| 2026-04-28 | -0.002161 | 0.000723 |
| 2026-04-29 | 0.011678 | 0.007766 |
6.5.2 การจัดการค่าว่าง (Handling Missing Values)
เนื่องจากตลาดหุ้นในแต่ละประเทศมีวันหยุดไม่ตรงกัน ข้อมูลที่ดึงมาพร้อมกันจึงมักเกิดค่าว่าง (NaN) เราสามารถจัดการได้ดังนี้:
คลิกเพื่อดูโค้ดไพธอน
# 1. การลบแถวที่มีค่าว่างทิ้ง (dropna)
# ใช้เมื่อข้อมูลมีจำนวนมากและต้องการความแม่นยำสูง
df_dropped = df_log_return.dropna()
# 2. การเติมค่าว่างด้วยวิธี Forward Fill (ffill)
# คือการใช้ราคาล่าสุดที่มีอยู่มาเติมในวันหยุด (วิธีมาตรฐานสำหรับ Time Series)
df_filled = df.ffill()
# 3. การแทนที่ค่าว่างด้วยค่าคงที่ (เช่น 0)
# มักใช้กับข้อมูลผลตอบแทน (Return) ในวันหยุดที่ถือว่าไม่มีการเปลี่ยนแปลง
df_zero = df_log_return.fillna(0)
display(df_filled.tail())| Ticker | USDTHB=X | ^SET.BK |
|---|---|---|
| Date | ||
| 2026-04-23 | 32.250000 | 1461.349976 |
| 2026-04-24 | 32.480000 | 1456.099976 |
| 2026-04-27 | 32.419998 | 1479.130005 |
| 2026-04-28 | 32.349998 | 1480.199951 |
| 2026-04-29 | 32.730000 | 1491.739990 |
6.6 การรวมข้อมูลจากต่างตลาดและต่างช่วงเวลา
ความท้าทายสำคัญของการวิเคราะห์เศรษฐกิจระหว่างประเทศ คือการจัดการข้อมูลที่มาจากตลาดคนละแห่งซึ่งมี “วันหยุดไม่ตรงกัน” เช่น ในวันที่ 13-15 เมษายน (วันสงกรานต์) ตลาดหลักทรัพย์ไทยปิดทำการ แต่ตลาดหลักทรัพย์นิวยอร์กยังคงเปิดซื้อขายปกติ ใน Python เราสามารถจัดการปัญหานี้ได้อย่างง่ายดายผ่านการใช้ Index (วันที่) เป็นตัวเชื่อม
6.6.1 การดึงข้อมูลหลายตลาดพร้อมกัน
เมื่อเราใช้ yf.download() ดึงข้อมูลหลาย Ticker พร้อมกัน ระบบจะสร้างตารางที่มี “วันที่” ครอบคลุมทุกวันที่อย่างน้อยหนึ่งตลาดมีการเคลื่อนไหว (Union Index)
คลิกเพื่อดูโค้ดไพธอน
# ดึงข้อมูลหุ้นไทย (PTT.BK) และหุ้นสหรัฐฯ (AAPL)
# ตลาดสองแห่งนี้มีวันหยุดและโซนเวลาที่แตกต่างกัน
assets = ["PTT.BK", "AAPL"]
df_merged = yf.download(assets, period="1mo")['Close']
# แสดงข้อมูล 10 แถวแรก เพื่อดูร่องรอยของค่าว่าง (NaN) ที่เกิดจากวันหยุดไม่ตรงกัน
display(df_merged.head(10))| Ticker | AAPL | PTT.BK |
|---|---|---|
| Date | ||
| 2026-03-30 | 246.630005 | 35.25 |
| 2026-03-31 | 253.789993 | 35.00 |
| 2026-04-01 | 255.630005 | 34.75 |
| 2026-04-02 | 255.919998 | 35.50 |
| 2026-04-03 | NaN | 34.25 |
| 2026-04-06 | 258.859985 | NaN |
| 2026-04-07 | 253.500000 | 34.75 |
| 2026-04-08 | 258.899994 | 35.00 |
| 2026-04-09 | 260.489990 | 35.50 |
| 2026-04-10 | 260.480011 | 34.75 |
6.6.2 กลยุทธ์การจัดการข้อมูลหลังการรวม (Merging Strategy)
หลังจากรวมข้อมูลแล้ว เราจะพบค่าว่าง (NaN) ในวันที่ตลาดแห่งหนึ่งปิดแต่เทรดอีกแห่งหนึ่งเปิด นักเศรษฐศาสตร์มี 2 วิธีหลักในการจัดการ:
วิธีที่ 1: การใช้ข้อมูลล่าสุดที่มี (Forward Fill) เป็นวิธีที่นิยมที่สุดในงานวิจัย เพราะถือว่าในวันที่ตลาดปิด ราคาสินทรัพย์นั้นยังคงมีมูลค่าเท่ากับราคาปิดล่าสุดที่ปรากฏ
คลิกเพื่อดูโค้ดไพธอน
# เติมค่าว่างด้วยค่าล่าสุดก่อนหน้า (Forward Fill)
df_ready = df_merged.ffill().dropna()
display(df_ready.head())| Ticker | AAPL | PTT.BK |
|---|---|---|
| Date | ||
| 2026-03-30 | 246.630005 | 35.25 |
| 2026-03-31 | 253.789993 | 35.00 |
| 2026-04-01 | 255.630005 | 34.75 |
| 2026-04-02 | 255.919998 | 35.50 |
| 2026-04-03 | 255.919998 | 34.25 |
วิธีที่ 2: การเลือกเฉพาะวันที่เปิดทำการร่วมกัน (Inner Join) ใช้เมื่อต้องการวิเคราะห์เฉพาะวันที่ทั้งสองตลาดมีการเคลื่อนไหวพร้อมกันเท่านั้น
คลิกเพื่อดูโค้ดไพธอน
# ลบแถวที่มีค่าว่างออกทั้งหมด
df_intersect = df_merged.dropna()
display(df_intersect.head())| Ticker | AAPL | PTT.BK |
|---|---|---|
| Date | ||
| 2026-03-30 | 246.630005 | 35.25 |
| 2026-03-31 | 253.789993 | 35.00 |
| 2026-04-01 | 255.630005 | 34.75 |
| 2026-04-02 | 255.919998 | 35.50 |
| 2026-04-07 | 253.500000 | 34.75 |
6.7 สรุปท้ายบท
บทนี้ได้นำเสนอการดึงข้อมูลเศรษฐกิจและการเงินแบบอัตโนมัติผ่านไลบรารี yfinance ซึ่งช่วยให้ผู้ใช้งานสามารถเข้าถึงข้อมูลจากแหล่งระดับโลกได้อย่างสะดวก รวดเร็ว และไม่มีค่าใช้จ่าย โดยข้อมูลที่ได้อยู่ในรูปแบบที่พร้อมนำไปวิเคราะห์ต่อด้วยเครื่องมือทางสถิติหรือสร้างแบบจำลองได้ทันที
เนื้อหาสำคัญของบทนี้ประกอบด้วยการทำความเข้าใจรหัสสินทรัพย์ (Ticker Symbols) สำหรับสินทรัพย์ประเภทต่าง ๆ เช่น หุ้น อัตราแลกเปลี่ยน สินค้าโภคภัณฑ์ และดัชนีตลาด รวมถึงการใช้งานฟังก์ชัน yf.download() เพื่อดึงข้อมูลย้อนหลังในช่วงเวลาที่ต้องการ
นอกจากนี้ ยังได้กล่าวถึงความท้าทายในการรวมข้อมูลจากหลายตลาดที่มีวันหยุดและเวลาทำการแตกต่างกัน ซึ่งอาจทำให้เกิดค่าว่าง (NaN) ในชุดข้อมูล และเสนอแนวทางการจัดการข้อมูลดังกล่าว เช่น การเติมค่าด้วยข้อมูลล่าสุด (Forward Fill) หรือการเลือกเฉพาะวันที่มีข้อมูลครบทุกตลาด (Inner Join)
โดยสรุป การใช้ yfinance ไม่เพียงช่วยลดภาระในการรวบรวมข้อมูล แต่ยังเป็นเครื่องมือสำคัญที่ช่วยให้นักเศรษฐศาสตร์สามารถทำงานกับข้อมูลจริงได้อย่างมีประสิทธิภาพ และพร้อมต่อยอดสู่การวิเคราะห์เชิงลึกในขั้นต่อไป