0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Colab × Streamlit × yfinanceで「株価チャート+ニュース」Webアプリを爆速構築!

Posted at

1. はじめに

「個人で株価を分析するちょっとしたWebアプリを作りたい!」
そう思って、React + FastAPI + Dockerで構築しようとしたら、yfinanceがすぐにアクセス過多のエラーが発生しました。
(時間空けながらアクセスはしても発生)

ただGoogle Colabで実施したら、時間空けながらyfinanceで実施しても、問題なく取得できました。

原因を調査すると、以下のようなことが考えられそうでした。

そこで私は、Google Colab × Streamlit の組み合わせでWebアプリケーションが出来ないかを検討したところngrokを利用することで、Webアプリケーションが構築できるということを見つけて、実際に確認してみました。

2. アーキテクチャと構成

構成図は以下の通りです。

[ Google Colab ] → Streamlit (port 8501) → ngrok tunnel → [ User browser ]
                              ↑
                      yfinance(米/日株)

使用技術

技術 用途
Streamlit Web UIの描画
yfinance 株価データ & ニュースの取得
mplfinance ローソク足チャートの描画
pyngrok Colab環境を外部公開

ngrokとは?

Colabで立てたStreamlitサーバーは外部からアクセスできません
ngrokを使うと、ローカルポートをパブリックURLとして中継できるようになります。

3. ソース解説

データ取得層

def fetch_price(ticker: str):
    df = yf.download(ticker, period="1mo", interval="1d", group_by="ticker")
    df = flatten_columns(df, ticker)
    df = ensure_datetime_index(df)
    if {"Open", "High", "Low", "Close", "Volume"}.issubset(df.columns):
        return df.dropna()
    return None

def fetch_company_name(ticker: str):
    info = yf.Ticker(ticker).info
    return info.get("shortName") or info.get("longName") or ticker

データ整形層

def flatten_columns(df, ticker):
    if isinstance(df.columns, pd.MultiIndex):
        lvl0 = df.columns.get_level_values(0)
        if "Price" in lvl0:
            return df.droplevel(0, axis=1)
        elif ticker in lvl0:
            return df.xs(ticker, axis=1, level=0)
    return df

def ensure_datetime_index(df):
    if not isinstance(df.index, pd.DatetimeIndex):
        df.index = pd.to_datetime(df.index, errors="coerce")
    return df

ニュース解析層

def parse_news(raw):
    parsed = []
    for n in raw:
        title = n.get("title") or n.get("headline") or n.get("content", {}).get("title")
        link  = n.get("link") or n.get("url") or n.get("canonicalUrl", {}).get("url") or n.get("content", {}).get("clickThroughUrl", {}).get("url")
        ts    = n.get("providerPublishTime") or n.get("pubDate")
        time_str = datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%d %H:%M") if isinstance(ts, (int, float)) else ""
        if title:
            parsed.append({"title": title, "link": link or "", "time": time_str})
    return parsed

UI描画層

def render_chart(df, title):
    fig, _ = mpf.plot(df, type="candle", volume=True, style="yahoo", returnfig=True)
    st.subheader(title)
    st.pyplot(fig)

def render_news_section(ticker, company):
    if st.button(f"{company} のニュースを表示 / 隠す"):
        st.session_state.show_news = not st.session_state.show_news
    if st.session_state.show_news:
        news = parse_news(getattr(yf.Ticker(ticker), "news", [])[:5])
        st.subheader(f"{company} 最新ニュース")
        for n in news:
            st.markdown(f"- {n['time']} | [{n['title']}]({n['link']})" if n["link"] else f"- {n['time']} | {n['title']}")

実際の画面のイメージはこちらです。

初期画面

image.png

検索ボタンクリック時

image.png

ニュース表示ボタンクリック時

image.png

上記のようにGoogle Colabを利用して動的なアプリケーションを構築できました。

また、ngrokのtunnelを構築するのは以下のようなソースで問題ありません。

from pyngrok import ngrok
import threading, os, time

# 認証トークンを最初に設定(1回だけでOK)
ngrok.set_auth_token(AUTH-TOKEN)

# Streamlit実行
def run():
    os.system("streamlit run app.py")
threading.Thread(target=run).start()

# 起動まで少し待機してから公開
time.sleep(5)
public_url = ngrok.connect(addr="8501", proto="http")
print(f"公開URL: {public_url}")

また、既存トンネルがあると競合してしまい、エラーが発生するので、明示的に削除する必要があります。

ngrok.kill()

4. メリットとデメリット

✅ メリット ⚠️ デメリット
Colabだけで完結し、環境構築が不要 セッション切れでアプリがリセットされる
yfinanceが安定して使える ngrok トンネルURLが毎回変わる
SSLや証明書エラーに悩まされない 本格運用には向かない(あくまで試作・個人用)
Streamlitで高速プロトタイピング可能 Web UIはStreamlitの制約内に限られる

5. おわりに

Colabとngrokを組み合わせれば、Python一つで株価情報とニュースを確認できるWebアプリを簡単に作れます。
Colabベースのこの構成は最小構成で最大の成果を得る手段になります。
正直個人的にはフロントエンドとバックエンドを分離できないため、とても開発しにくいと思っていますがw、 簡単に動的画面で分析したい場合はとても良いと思いました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?