An interactive research dashboard for exploring Korean equity prices, technical indicators, headline sentiment and a leakage-safe next-session return forecasting experiment.
| Methodology | Design |
|---|---|
| Target | Next-session simple return |
| Split | Chronological 60% train / 20% validation / 20% test |
| Selection | Lowest validation return MAE |
| Final evaluation | Every frozen candidate scored on the held-out test period |
| Baselines | Zero return and latest observed one-session return |
This project is for educational and research purposes only. It does not provide investment advice, trade recommendations or guarantees of future performance.
The four-section Streamlit dashboard makes data provenance, descriptive technical conditions, held-out forecast evaluation, lexical headline context and limitations visible. It is deliberately a compact research project—not a trading terminal or a claim that prices are reliably predictable.
Both images are static previews generated from deterministic synthetic data. Their metrics are interface examples, not market-performance evidence.
- Validated OHLCV ingestion with pykrx preferred, yfinance fallback, and deterministic offline mode.
- Centralized MA20, MA60, RSI14, MACD, annualized 20-session volatility and drawdown calculations.
- Past-only feature engineering and train-only preprocessing.
- Honest comparison of zero-return, previous-return, Ridge and histogram-gradient-boosting candidates.
- Validation-only model selection followed by held-out metrics for every candidate.
- Transparent, dictionary-based headline sentiment that is never combined with technical indicators into a recommendation.
The target is defined exactly as close.pct_change().shift(-1). At session t, the previous-return baseline uses the latest observable return from t-1 to t. Features contain only information available at or before t: one-, two-, five- and twenty-session returns, rolling volatility, moving-average distances, RSI, MACD and relative volume. Rows remain chronological and are never shuffled.
Candidates are fitted on the first 60%. Validation MAE over the next 20% selects among the two baselines, a Ridge pipeline and HistGradientBoostingRegressor. Selection is frozen before every candidate is scored on the final 20%. Complexity receives no preference, so a baseline is selected whenever it has the lowest validation MAE.
After held-out evaluation is complete, a selected trainable model is freshly refit on all rows whose next-session target is known to produce the displayed latest forecast. This refit cannot change model selection or held-out metrics.
Validation and held-out test reporting includes return MAE, return RMSE, directional accuracy with sample count, mean actual and predicted returns, and implied one-session price MAE. Directional accuracy is descriptive and is not evidence of profitability. No strategy, Sharpe ratio, transaction costs or recursive multi-day forecast is presented.
- pykrx is the preferred provider library for Korean market histories; it is not described here as an official exchange API.
- yfinance provides a best-effort Yahoo Finance fallback using the
.KSsuffix. - Deterministic synthetic data supports offline demonstration and CI.
The dashboard identifies the provider actually used, request dates, first and last available observations, and row count. Latest observations are latest available provider data—not guaranteed real-time exchange quotes.
Google News RSS is queried best-effort in live mode. Missing news never prevents price analysis. A small documented vocabulary counts positive and negative matched terms; zero net score is neutral. HTML is removed and duplicate headlines are discarded while source and publication information are retained. This lexical heuristic can miss sarcasm, negation, language nuance and context; it neither establishes causality nor forecasts returns.
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
streamlit run app.pyNaver credentials are optional and currently unnecessary. .env.example contains placeholder names only.
STOCK_DASHBOARD_DEMO=1 streamlit run app.pyThis mode uses a fixed seed, requires no provider or API key, labels every output synthetic, and supports all four dashboard sections. Regenerate previews with:
STOCK_DASHBOARD_DEMO=1 python scripts/generate_demo_assets.pyapp.py # thin Streamlit presentation layer
equity_dashboard/ # data, indicators, forecasting, sentiment, charts
assets/ # clearly labelled synthetic SVG previews
scripts/generate_demo_assets.py
tests/ # focused offline suite
.github/workflows/ci.yml # Python 3.11 CI
python -m compileall app.py equity_dashboard scripts tests
STOCK_DASHBOARD_DEMO=1 python -m pytest -q
STOCK_DASHBOARD_DEMO=1 python scripts/generate_demo_assets.py --checkTests never contact market, news, credential or model-download services.
- Provider histories may be delayed, incomplete, adjusted differently, or revised; availability is not guaranteed.
- News coverage is partial, publication timestamps can be missing, and the lexical method is context-blind.
- Financial returns are noisy and non-stationary; validation success may not generalize.
- Associations between headlines, indicators and returns are non-causal.
- The experiment does not model execution, liquidity, slippage, tax or transaction costs and implements no trading strategy.
- Synthetic demo results are not real-market evidence.
This project is for educational and research purposes only. It does not provide investment advice, trade recommendations or guarantees of future performance.