Python 365 ngày

Lấy Dữ Liệu Chứng Khoán Miễn Phí Bằng yfinance | Yahoo Finance (Python 365 Ngày 54)

21/08/2026 Đặng Trí Thanh 207 lượt xem ~17 phút đọc
Mục lục bài viết
    Lấy Dữ Liệu Chứng Khoán Miễn Phí Bằng yfinance | Yahoo Finance (Python 365 Ngày 54)
    Xem video Python 365 Ngày 54 trên YouTube

    🎬 Xem video trên YouTube

    Lấy dữ liệu chứng khoán miễn phí bằng yfinance là gì? Ngày 53 bạn học cách scrape giá coin không cần API. Hôm nay, Ngày 54 của chuỗi Python 365 ngày, chúng ta chuyển sang thị trường chứng khoán — và câu chuyện dễ thở hơn nhiều: chỉ cần 1 dòng Python là có dữ liệu giá cổ phiếu từ Yahoo Finance.

    Thư viện yfinance (Yahoo Finance) là công cụ phổ biến nhất để lấy dữ liệu chứng khoán miễn phí bằng Python: giá, khối lượng, thông tin công ty, cổ tức, chia tách… Tất cả trả về dưới dạng DataFrame của pandas — sẵn sàng phân tích ngay. Trong bài này, bạn sẽ học: cài đặt, tải lịch sử giá, đọc hiểu bảng dữ liệu OHLCV, lấy thông tin công ty, tính toán lợi nhuận/MA20/biến động, so sánh nhiều mã cùng lúc — và một nguồn dự phòng Stooq khi chưa cài được yfinance.

    Với nhà đầu tư Việt Nam, bài này càng có ý nghĩa: thị trường chứng khoán trong nước (HOSE/HNX) vẫn chưa có nhiều nguồn dữ liệu lịch sử mở, còn các nền tảng chuyên nghiệp thì đắt đỏ. yfinance cho phép bạn lấy giá cổ phiếu Việt Nam (dạng mã VNM.VN, FPT.VN) miễn phí — đủ để học phân tích, thử chiến lược, xây dashboard cá nhân mà không tốn một đồng nào. Đây chính là “đòn bẩy” giúp bạn đi từ người xem bảng giá đến người phân tích dữ liệu thị trường bằng Python.

    1. Vì sao dữ liệu chứng khoán “khó xin” hơn crypto?

    Ở Ngày 53, bạn thấy coin có CoinGecko công khai. Còn chứng khoán thì sao?

    Nguồn API Chi phí Độ khó
    Yahoo Finance Không có API chính thức (đã đóng 2017) — Phải scrape hoặc dùng yfinance
    Bloomberg / Refinitiv Có Rất đắt (hàng chục triệu đồng/năm) Cao
    Alpha Vantage Có Miễn phí giới hạn ~5 req/phút Trung bình
    Stooq CSV tải trực tiếp Miễn phí Thấp
    yfinance Gói lại từ Yahoo Miễn phí Rất thấp

    Điểm mấu chốt: Yahoo Finance không có API chính thức, nhưng cộng đồng đã “gói” endpoint dữ liệu của Yahoo thành thư viện yfinance — miễn phí, không cần key, cú pháp cực đơn giản. Đây là lý do hầu hết người học phân tích chứng khoán bằng Python đều bắt đầu từ yfinance.

    2. Cài đặt yfinance — 1 lệnh là xong

    pip install yfinance

    yfinance tự kéo theo pandas và requests nên bạn không cần cài riêng. Kiểm tra nhanh:

    import yfinance as yf
    print(yf.__version__)

    Nếu máy bạn dùng nhiều dự án Python, nên tạo môi trường ảo (virtual environment) để tránh xung đột thư viện:

    python -m venv venv
    venvScriptsactivate        # Windows
    source venv/bin/activate     # macOS / Linux
    pip install yfinance

    Thói quen dùng venv sẽ cứu bạn rất nhiều lần khi dự án lớn dần — mỗi dự án có bộ thư viện riêng, không đè lên nhau.

    3. Tải lịch sử giá — 1 dòng Python

    Cách nhanh nhất để lấy giá cổ phiếu: yf.download().

    import yfinance as yf
    
    df = yf.download("AAPL", period="6mo")
    print(df.tail())

    Kết quả là một DataFrame với các cột quen thuộc:

    Open High Low Close Volume
    … … … … … …
    2026-08-18 226.50 229.30 225.80 228.70 48210300
    2026-08-19 229.10 231.20 227.90 230.50 50123400

    Mỗi dòng là một phiên giao dịch (ngày), chỉ mục là ngày (DatetimeIndex). Năm cột chuẩn của dữ liệu giá: Open (giá mở), High (cao nhất), Low (thấp nhất), Close (giá đóng), Volume (khối lượng).

    Còn nếu muốn dữ liệu chi tiết hơn cho từng mã, dùng Ticker:

    ticker = yf.Ticker("AAPL")
    hist = ticker.history(period="6mo")
    print(hist.tail(3))

    Ticker.history() trả về thêm cột Dividends và Stock Splits — hữu ích khi nghiên cứu cổ tức và chia tách cổ phiếu.

    Tham số hay dùng của yf.download()

    Tham số Ý nghĩa Ví dụ
    period Kỳ dữ liệu gần đây "6mo", "1y", "5y", "max"
    start / end Khoảng ngày cụ thể start="2025-01-01", end="2026-01-01"
    interval Tần suất dữ liệu "1d" (ngày), "1h", "15m", "1wk"
    group_by Nhóm theo mã khi tải nhiều ticker "ticker"
    auto_adjust Giá đã điều chỉnh cổ tức/chia tách mặc định True
    threads Tải song song False khi gặp lỗi mạng

    Chọn đúng tham số giúp bạn tải đúng loại dữ liệu, đúng khoảng thời gian — nền tảng cho mọi phân tích phía sau.

    4. Đọc hiểu DataFrame giá (OHLCV)

    DataFrame là “bảng tính” của pandas — nếu bạn đã học pandas ở các ngày trước thì phần này rất quen. Các thao tác quan trọng:

    print(df.tail(5))
    
    print(df.describe())
    
    print(df["Close"].iloc[-1])
    
    print(df["Volume"].sum())
    
    print(df["High"].max())

    Mẹo: df["Close"] là một Series — bạn có thể cộng trừ, vẽ biểu đồ, hoặc đưa thẳng vào các chỉ báo kỹ thuật như MA, RSI (kết hợp Ngày 57).

    Mỗi cột trong OHLCV kể một câu chuyện riêng: Open phản ánh tâm lý đầu phiên, Close là “chân lý” cuối ngày được dùng trong hầu hết chỉ báo, High/Low cho biết biên độ dao động, còn Volume là “hơi thở” của thị trường — giá tăng kèm khối lượng lớn thường đáng tin hơn giá tăng với khối lượng nhỏ. Khi mới học, hãy làm quen với việc nhìn cả năm cột, đừng chỉ chăm chăm vào Close.

    Lấy dữ liệu theo khoảng ngày cụ thể

    Không phải lúc nào bạn cũng cần “6 tháng gần nhất” — đôi khi cần đúng một khoảng thời gian lịch sử (ví dụ cả năm 2025 để backtest):

    import yfinance as yf
    
    df = yf.download("AAPL", start="2025-01-01", end="2026-01-01", interval="1d")
    print(f"Số phiên: {len(df)}")
    print(df.head(3))

    start/end chấp nhận chuỗi ngày "YYYY-MM-DD" hoặc đối tượng datetime. Kết hợp interval="1h" hoặc "15m" bạn có thể lấy dữ liệu trong ngày (intraday) — hữu ích cho phân tích kỹ thuật ngắn hạn.

    5. Thông tin công ty — Ticker.info

    Ngoài giá, yfinance còn lấy được thông tin công ty qua Ticker.info — một dictionary khổng lồ:

    import yfinance as yf
    
    info = yf.Ticker("AAPL").info
    for key in ["longName", "sector", "marketCap", "trailingPE", "dividendYield",
                "fiftyTwoWeekHigh", "fiftyTwoWeekLow", "website"]:
        print(f"{key}: {info.get(key)}")

    Kết quả ví dụ:

    longName: Apple Inc.
    sector: Technology
    marketCap: 3500000000000
    trailingPE: 33.4
    dividendYield: 0.0045
    fiftyTwoWeekHigh: 237.0
    fiftyTwoWeekLow: 164.0
    website: https://www.apple.com

    Với dữ liệu này, bạn có thể lọc cổ phiếu theo ngành, theo P/E, theo cổ tức — xây dựng bộ lọc cổ phiếu của riêng mình.

    So sánh định giá giữa các công ty

    Ticker.info còn giúp bạn so sánh định giá — ví dụ P/E (giá trên lợi nhuận) của các ông lớn công nghệ:

    import yfinance as yf
    
    for symbol in ["AAPL", "MSFT", "TSLA"]:
        info = yf.Ticker(symbol).info
        pe = info.get("trailingPE")
        name = info.get("shortName", symbol)
        print(f"{symbol:5} {name:22} P/E: {pe if pe is not None else 'N/A'}")

    P/E thấp thường có vẻ “rẻ” hơn, nhưng phải xét trong bối cảnh ngành và tốc độ tăng trưởng — một công ty tăng trưởng nhanh có thể xứng đáng P/E cao. Đừng bao giờ quyết định chỉ bằng một con số.

    Cổ tức và chia tách cổ phiếu

    Nhà đầu tư dài hạn không thể bỏ qua cổ tức. yfinance cho bạn lịch sử cổ tức và chia tách một cách trực tiếp:

    import yfinance as yf
    
    t = yf.Ticker("AAPL")
    print("Cổ tức 2 năm gần nhất (USD/cổ phiếu):")
    print(t.dividends.tail(8))
    print("nLịch sử chia tách:")
    print(t.splits.tail(5))

    Khi tính tổng lợi nhuận (total return) của một cổ phiếu, bạn cần cộng cả cổ tức nhận được — đừng chỉ nhìn vào chênh lệch giá. Cột Dividends trong history() chính là dữ liệu để làm việc đó.

    6. Tính toán nhanh: lợi nhuận, MA20, biến động

    Dữ liệu giá mà không phân tích thì phí. Ba phép tính cơ bản nhất:

    import yfinance as yf
    
    df = yf.download("AAPL", period="6mo")["Close"]
    
    ret = df.iloc[-1] / df.iloc[0] - 1
    print(f"Lợi nhuận 6 tháng: {ret*100:+.2f}%")
    
    ma20 = df.rolling(20).mean().iloc[-1]
    print(f"MA20 hiện tại: {ma20:,.2f}")
    
    daily_ret = df.pct_change().dropna()
    vol = daily_ret.std() * (252 ** 0.5)  # annualized
    print(f"Biến động năm hóa: {vol*100:.2f}%")

    Giải thích:

    • pct_change() — lợi nhuận từng ngày.
    • std() * sqrt(252) — nhân với căn bậc hai của số phiên giao dịch một năm (~252) để năm hóa biến động — con số này chính là “vol” bạn thấy trên báo cáo tài chính.

    Ba con số này — lợi nhuận, MA20, biến động — chính là “bộ ba sức khỏe” của một cổ phiếu: lợi nhuận cho biết nó đi được bao xa, MA20 cho biết xu hướng hiện tại, biến động cho biết mức độ rủi ro. Khi so sánh nhiều cổ phiếu, hãy luôn nhìn cả ba — một cổ phiếu lợi nhuận cao nhưng biến động gấp đôi thị trường có thể không đáng giá rủi ro.

    Nếu muốn đi xa hơn, bạn có thể tính thêm hệ số tương quan giữa hai cổ phiếu — con số từ -1 đến +1 cho biết chúng di chuyển cùng chiều hay ngược chiều:

    import yfinance as yf
    
    df = yf.download(["AAPL", "MSFT"], period="1y")["Close"]
    corr = df["AAPL"].pct_change().corr(df["MSFT"].pct_change())
    print(f"Tương quan AAPL - MSFT (1 năm): {corr:.2f}")

    Hệ số tương quan là nền tảng của đa dạng hóa danh mục: kết hợp những cổ phiếu tương quan thấp giúp giảm rủi ro tổng thể.

    7. Nhiều mã cùng lúc — so sánh AAPL / MSFT / TSLA

    Sức mạnh thực sự của yfinance là tải nhiều mã trong một lệnh:

    import yfinance as yf
    
    tickers = ["AAPL", "MSFT", "TSLA"]
    df = yf.download(tickers, period="6mo", group_by="ticker")
    
    for t in tickers:
        sub = df[t].dropna()
        ret = sub["Close"].iloc[-1] / sub["Close"].iloc[0] - 1
        ma20 = sub["Close"].rolling(20).mean().iloc[-1]
        print(f"{t}: giá {sub['Close'].iloc[-1]:>8,.2f} | lợi nhuận kỳ {ret*100:>+7.2f}% | MA20 {ma20:>8,.2f}")

    Với group_by="ticker", DataFrame có cấp bậc hai: df["AAPL"], df["MSFT"], df["TSLA"] — mỗi mã một bảng OHLCV riêng. Đây là nền tảng để xây dựng bảng so sánh cổ phiếu hay danh mục đầu tư.

    Lưu dữ liệu ra CSV để dùng tiếp

    Dữ liệu tải về hôm nay có thể không còn tải lại được nguyên trạng vào ngày mai (giá luôn đổi). Hãy lưu ngay xuống CSV khi tải:

    import yfinance as yf
    
    df = yf.download(["AAPL", "MSFT", "TSLA"], period="6mo", group_by="ticker")
    df.to_csv("gia_co_phieu.csv")
    print("Đã lưu gia_co_phieu.csv")

    Lần sau muốn phân tích lại, chỉ cần pd.read_csv("gia_co_phieu.csv", index_col=0, header=[0,1]) — không cần gọi mạng lần nữa. Thói quen “tải rồi lưu” giúp bạn backtest nhất quán: kết quả cũ không bị thay đổi vì dữ liệu mới.

    8. Code hoàn chỉnh Ngày 54

    Đây là toàn bộ script Day 54_yfinance du lieu chung khoan.py:

    """
    Day 54 - Lấy dữ liệu chứng khoán miễn phí bằng yfinance
    ========================================================
    yfinance: dữ liệu từ Yahoo Finance. Nếu chưa cài -> tự in hướng dẫn
    và dùng nguồn dự phòng Stooq (kiểu Ngày 49) để vẫn xem được dữ liệu.
    
    Cài:  pip install yfinance
    Chạy: python "Day 54_yfinance du lieu chung khoan.py"
    """
    import sys
    
    TICKERS = ["AAPL", "MSFT", "TSLA"]
    PERIOD = "6mo"
    
    def demo_stooq(symbol: str = "aapl.us"):
        import csv
        import io
        import urllib.request
    
        url = f"https://stooq.pl/q/d/l/?s={symbol}&i=d"
        req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 PythonDay54"})
        with urllib.request.urlopen(req, timeout=15) as resp:
            text = resp.read().decode("utf-8")
        rows = list(csv.DictReader(io.StringIO(text)))
        closes = [float(r["Close"]) for r in rows if r["Close"]]
        print(f"   (Nguồn dự phòng Stooq) {symbol}: {len(closes)} phiên")
        print(f"   Giá mới nhất: {closes[-1]:,.2f} | thấp nhất: {min(closes):,.2f} | "
              f"cao nhất: {max(closes):,.2f}")
        ret = closes[-1] / closes[0] - 1
        print(f"   Lợi nhuận cả kỳ: {ret*100:+.2f}%")
    
    
    def demo_yfinance():
        import pandas as pd
    
        print(f"📈 Tải dữ liệu {len(TICKERS)} mã, kỳ {PERIOD}...")
        df = __import__("yfinance").download(TICKERS, period=PERIOD, group_by="ticker")
    
        for t in TICKERS:
            sub = df[t].dropna()
            print(f"n▶ {t}")
            print("   Bảng dữ liệu (5 dòng cuối):")
            print(sub.tail(5).round(2).to_string())
            ret = sub["Close"].iloc[-1] / sub["Close"].iloc[0] - 1
            ma20 = sub["Close"].rolling(20).mean().iloc[-1]
            print(f"   Giá hiện tại: {sub['Close'].iloc[-1]:,.2f} | "
                  f"Lợi nhuận kỳ: {ret*100:+.2f}% | MA20: {ma20:,.2f}")
    
    
    def main():
        try:
            import yfinance  # noqa: F401
        except ImportError:
            print("❌ Chưa cài yfinance.")
            print("   Cài bằng:  pip install yfinance")
            print("   (Dùng nguồn dự phòng Stooq để xem dữ liệu ngay)n")
            demo_stooq()
            return
    
        demo_yfinance()
    
    
    if __name__ == "__main__":
        main()

    Kết quả khi chạy (ví dụ):

    📈 Tải dữ liệu 3 mã, kỳ 6mo...
    
    ▶ AAPL
       Giá hiện tại: 230.50 | Lợi nhuận kỳ: +12.34% | MA20: 226.10
    ▶ MSFT
       Giá hiện tại: 415.20 | Lợi nhuận kỳ: +8.90% | MA20: 409.70
    ▶ TSLA
       Giá hiện tại: 248.30 | Lợi nhuận kỳ: -5.20% | MA20: 252.80

    9. Hiểu code từng phần

    • TICKERS = ["AAPL", "MSFT", "TSLA"] — danh sách mã chứng khoán cần tải; bạn có thể đổi thành bất kỳ mã nào (VNM, FPT, BID trên HOSE cũng hỗ trợ dạng .VN — ví dụ "VNM.VN").
    • PERIOD = "6mo" — kỳ dữ liệu: 1mo, 3mo, 6mo, 1y, 2y, 5y, max…
    • __import__("yfinance") — cách gọi thư viện động; thực chất tương đương import yfinance.
    • sub = df[t].dropna() — lấy bảng của từng mã và bỏ dòng rỗng (mã nào niêm yết muộn sẽ có NaN ở đầu).
    • rolling(20).mean() — đường trung bình 20 phiên — chỉ báo xu hướng quen thuộc từ Ngày 56.

    Điểm đáng chú ý của script: nó được thiết kế để không bao giờ chết giữa chừng. Nếu chưa cài yfinance, thay vì báo lỗi rồi thoát, nó in hướng dẫn cài đặt và tự chuyển sang Stooq — bạn vẫn nhìn thấy dữ liệu, vẫn học được bài học. Đây là tư duy “fail gracefully” mà mọi script thực tế đều nên có: trong sản xuất, một script chết vì thiếu thư viện là một đêm mất dữ liệu; một script biết tự chuyển nguồn là một đêm yên tâm.

    10. Fallback Stooq — khi chưa cài được yfinance

    Nếu import yfinance thất bại, script tự chuyển sang Stooq — trang web cho phép tải CSV giá trực tiếp, chỉ dùng thư viện chuẩn (csv, urllib), giống kỹ thuật bạn đã học ở Ngày 53:

    def demo_stooq(symbol: str = "aapl.us"):
        import csv
        import io
        import urllib.request
    
        url = f"https://stooq.pl/q/d/l/?s={symbol}&i=d"
        req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 PythonDay54"})
        with urllib.request.urlopen(req, timeout=15) as resp:
            text = resp.read().decode("utf-8")
        rows = list(csv.DictReader(io.StringIO(text)))
        closes = [float(r["Close"]) for r in rows if r["Close"]]
        print(f"   (Nguồn dự phòng Stooq) {symbol}: {len(closes)} phiên")
        print(f"   Giá mới nhất: {closes[-1]:,.2f} | thấp nhất: {min(closes):,.2f} | "
              f"cao nhất: {max(closes):,.2f}")
        ret = closes[-1] / closes[0] - 1
        print(f"   Lợi nhuận cả kỳ: {ret*100:+.2f}%")

    Lưu ý mã trên Stooq có dạng aapl.us, msft.us (viết thường + đuôi sàn .us). Đây chính là bài học xuyên suốt chuỗi: luôn có phương án B — khi công cụ chính không dùng được, vẫn phải ra được kết quả.

    Stooq cũng hỗ trợ thị trường Việt Nam với mã dạng vnm.vn, fpt.vn — nên dù bạn ở môi trường nào, chỉ cần có Python thuần là vẫn đọc được giá cổ phiếu. Hãy thử chạy demo_stooq("vnm.vn") để xem dữ liệu VNM (Vinamilk) — bài tập nhỏ nhưng giúp bạn tự tin rằng không có nguồn dữ liệu nào là “bắt buộc phải có”.

    11. Xử lý lỗi thường gặp

    Lỗi Nguyên nhân Cách xử lý
    No data found Mã sai hoặc kỳ không có dữ liệu Kiểm tra lại mã (vd VNM.VN cho HOSE); thử period="1mo"
    Rate limit / timeout Yahoo chặn tạm thời Đợi vài phút; giảm số mã tải cùng lúc; thêm threads=False
    KeyError: 'AAPL' Mã không có dữ liệu trong kỳ Kiểm tra df.columns; dùng dropna()
    SSL / connection Mạng chặn Thử pip install --upgrade yfinance; dùng nguồn Stooq

    Quy tắc vàng: khi nghi ngờ, in ra df.tail() để nhìn dữ liệu thật — đừng đoán mò.

    Quy trình debug chuẩn khi dữ liệu “lạ”: (1) in df.tail() và df.columns xem cấu trúc; (2) kiểm tra số dòng len(df) — quá ít nghĩa là kỳ/quá short hoặc mã sai; (3) thử với một mã chắc chắn đúng như AAPL để cô lập lỗi; (4) nếu mạng lỗi, lưu dữ liệu cũ trong CSV và chạy tiếp với dữ liệu đó. Đừng sửa code mù quáng — hãy nhìn dữ liệu trước, sửa code sau.

    12. yfinance vs các nguồn khác — chọn gì?

    Tiêu chí yfinance Stooq CSV Alpha Vantage
    Cài đặt pip install yfinance Không cần pip install alpha_vantage
    API key Không cần Không cần Cần (miễn phí giới hạn)
    Phạm vi Toàn cầu (US, VN…) Toàn cầu Toàn cầu
    Dữ liệu công ty ✅ Ticker.info ❌ ✅
    Độ ổn định Khá (không chính thức) Cao Cao
    Tốc độ Nhanh Chậm hơn Giới hạn 5 req/phút

    Kết luận: yfinance cho phân tích cá nhân và học tập; Stooq làm phương án dự phòng; API trả phí khi xây sản phẩm thương mại.

    Một lời khuyên thực dụng: đừng mất thời gian so sánh quá kỹ từng nguồn — hãy bắt đầu với yfinance vì nó nhanh nhất để có dữ liệu trong tay, rồi khi dự án lớn dần và đòi hỏi độ tin cậy cao hơn, mới cân nhắc nâng cấp nguồn dữ liệu. Dữ liệu 90% đúng + bắt đầu ngay hôm nay luôn tốt hơn dữ liệu 100% đúng + bắt đầu tuần sau.

    13. Ứng dụng thực tế — từ giá cổ phiếu đến hệ thống phân tích

    Với dữ liệu từ yfinance, bạn có thể xây dựng:

    • Bộ lọc cổ phiếu (stock screener) — quét hàng trăm mã, lọc theo P/E, cổ tức, biến động (dùng Ticker.info).
    • Chiến lược MA crossover — mua khi giá cắt lên MA20, bán khi cắt xuống (kết hợp Ngày 56).
    • Tính RSI/backtest — dữ liệu lịch sử sạch là đầu vào cho mọi chỉ báo (Ngày 57, 60).
    • Dashboard giá — vẽ biểu đồ nến bằng matplotlib/plotly (Ngày 65), lưu CSV hàng ngày.
    • Cảnh báo Telegram — khi cổ phiếu chạm ngưỡng, gửi tin nhắn (Ngày 51).

    Ví dụ cụ thể: bạn muốn nhận cảnh báo khi VNM chạm mức hỗ trợ. Chỉ cần một script chạy mỗi sáng: tải VNM.VN bằng yfinance → kiểm tra giá đóng cửa hôm qua so với ngưỡng bạn đặt → nếu chạm thì gửi tin Telegram. Toàn bộ logic khoảng 30 dòng Python, dữ liệu miễn phí, chạy trên máy nhà hoặc VPS giá rẻ. Đây chính là kiểu dự án nhỏ biến kiến thức thành công cụ hàng ngày.

    Mảnh ghép Python 365 của bạn đang lớn dần: scrape (53) → chứng khoán (54) → bot Binance (55) → MA (56) → RSI (57)… — đủ bộ công cụ để xây dựng một hệ thống phân tích thị trường hoàn chỉnh.

    Vẽ biểu đồ giá cổ phiếu

    Nhìn con số không bằng nhìn biểu đồ. Với dữ liệu yfinance + matplotlib, bạn có biểu đồ giá + MA20 chỉ trong vài dòng (chi tiết hơn ở Ngày 65):

    import yfinance as yf
    import matplotlib.pyplot as plt
    
    df = yf.download("AAPL", period="6mo")
    df["MA20"] = df["Close"].rolling(20).mean()
    
    plt.figure(figsize=(12, 6))
    plt.plot(df.index, df["Close"], label="AAPL", linewidth=1.5)
    plt.plot(df.index, df["MA20"], label="MA20", linewidth=1, linestyle="--")
    plt.title("AAPL — Giá đóng cửa & MA20 (6 tháng)")
    plt.xlabel("Ngày"); plt.ylabel("USD")
    plt.legend(); plt.grid(alpha=0.3)
    plt.tight_layout(); plt.show()

    Biểu đồ này chính là khởi đầu của một dashboard theo dõi cổ phiếu — bạn có thể thêm RSI (Ngày 57), khối lượng, hoặc nhiều mã cùng lúc.

    14. Bài tập thực hành hôm nay

    1. Cơ bản: Chạy script Ngày 54 nguyên bản với 3 mã AAPL/MSFT/TSLA, ghi lại lợi nhuận từng mã.
    2. Trung bình: Đổi sang cổ phiếu Việt Nam — thử VNM.VN, FPT.VN, BID.VN (kỳ 1y) và so sánh lợi nhuận + MA20 của 3 mã.
    3. Nâng cao: Viết hàm screen(tickers) lấy Ticker.info của 10 mã bất kỳ, in bảng: tên công ty, ngành, P/E, cổ tức — rồi sắp xếp theo cổ tức giảm dần.
    4. Thử thách: Tải dữ liệu 2 cổ phiếu bất kỳ trong 1 năm, tính hệ số tương quan lợi nhuận ngày — rồi trả lời: chúng di chuyển cùng chiều hay ngược chiều? Giải thích vì sao.

    15. FAQ

    Hỏi: yfinance có hợp pháp không? yfinance là thư viện mã nguồn mở phổ biến, dùng dữ liệu công khai của Yahoo Finance — phù hợp cho học tập và phân tích cá nhân. Với sản phẩm thương mại quy mô lớn, hãy cân nhắc nguồn dữ liệu có giấy phép.

    Hỏi: Có lấy được cổ phiếu Việt Nam không? Có — dùng mã dạng VNM.VN, FPT.VN, BID.VN… Yahoo hỗ trợ HOSE/HNX. Dữ liệu lịch sử có thể không đầy đủ bằng US nhưng đủ để học.

    Hỏi: Vì sao dữ liệu của tôi khác app chứng khoán? Vì giá đóng cửa có thể được điều chỉnh (adjusted) theo cổ tức/chia tách. Mặc định history(auto_adjust=True) trả giá đã điều chỉnh — gần với “lợi nhuận thật của nhà đầu tư” hơn.

    Hỏi: Cần pandas không? Có — yfinance trả về DataFrame nên bạn nên có pandas (pip install pandas), thường được cài kèm tự động.

    Hỏi: Dữ liệu yfinance có đáng tin cho backtest không? Đủ tốt cho học tập và kiểm chứng chiến lược ở mức cá nhân. Lưu ý: giá đã điều chỉnh (adjusted) có thể khác giá “thô” bạn thấy trên app — hãy hiểu rõ bạn đang dùng loại nào. Với sản phẩm thương mại, hãy dùng nguồn dữ liệu chính thức.

    Hỏi: yfinance có bị chặn không? Yahoo đôi khi giới hạn request (rate limit) khi gọi quá nhiều. Cách tránh: tải dữ liệu một lần rồi lưu CSV, không gọi lại liên tục; tăng period thay vì tải nhiều lần; nếu gặp lỗi, chờ vài phút rồi thử lại.

    16. Kết luận

    Ngày 54 đã trang bị cho bạn công cụ lấy dữ liệu chứng khoán miễn phí bằng yfinance — chỉ 1 dòng Python là có giá cổ phiếu từ Yahoo Finance. Bạn đã học:

    • ✅ Cài đặt yfinance và tải lịch sử giá bằng yf.download() / Ticker.history().
    • ✅ Đọc hiểu DataFrame OHLCV (Open/High/Low/Close/Volume).
    • ✅ Lấy thông tin công ty qua Ticker.info.
    • ✅ Tính lợi nhuận, MA20, biến động năm hóa.
    • ✅ Tải nhiều mã cùng lúc và so sánh AAPL/MSFT/TSLA.
    • ✅ Nguồn dự phòng Stooq khi không cài được thư viện.

    Từ hôm nay, bạn không còn phải “xin” dữ liệu thị trường từ ai — cả chứng khoán lẫn crypto đều nằm trong tầm tay một script Python. Bước tiếp theo trong hành trình: Ngày 55 — Bot Binance tự động mua/bán và xa hơn là Ngày 57 — RSI, nơi bạn sẽ dùng chính bộ dữ liệu này để tính chỉ báo.

    Hãy nhớ điều quan trọng nhất của bài hôm nay: dữ liệu miễn phí, công cụ miễn phí, nhưng kỹ năng phân tích thì vô giá. yfinance chỉ là “vòi nước” — thứ tạo ra giá trị là bạn biết lấy gì, tính gì, và quyết định gì từ con số. Chạy script, thử đổi sang cổ phiếu Việt Nam, vẽ biểu đồ đầu tiên của bạn — và chuẩn bị cho Ngày 55, nơi chúng ta bắt đầu tự động hóa giao dịch. 📈

    ▶ Playlist Python 365 · 🌐 Website Hướng Nghiệp Dữ Liệu · 📌 Lập trình Python nâng cao — Tự động hóa

    Đặng Trí Thanh

    Đặng Trí Thanh

    Giám đốc Công nghệ · DNT Digital · Giảng viên HNDL Hướng Nghiệp Dữ Liệu
    831 Bài viết
    15.4k Người theo dõi
    120k+ Lượt đọc

    Đặng Trí Thanh — Founder & CTO · Hướng Nghiệp Dữ Liệu - DNT Digital. Chuyên đào tạo và triển khai thực chiến Python, MT5 và hệ thống bot auto trading / IB cho học viên và doanh nghiệp.

    Bài viết liên quan

    DNT DIGITAL

    🤖 AI CODE: Vibe Code NEEDED! 🚀 🏦 SSI • DNSE • MT5 • Bitget ⚡

    Zalo 0934145100
    Khóa đào tạo
    Hỗ trợ

    Được học lại miễn phí · Hỗ trợ trọn đời · Cập nhật miễn phí

    Đội ngũ hỗ trợ

    Đặng Trí Thanh
    Đặng Trí Thanh
    Giám đốc Công nghệ DNT Digital
    Zalo 0934145100
    Mộng Cầm
    Mộng Cầm
    Hỗ trợ khách hàng · Huấn luyện viên
    Zalo 0927909257
    Khánh Linh
    Khánh Linh
    Hỗ trợ khách hàng · Huấn luyện viên
    Zalo 0927909582