Add SQLite-cached check_holidays MCP tool with pre-analysis checklist
- Add check_holidays MCP tool in server.py with SQLite caching (cache-first, API-fallback) - Add Section 6 Pre-Analysis Checklist (market status, holidays, news, analysis type) to SKILL.md - Add holidays-data named volume to docker-compose.yml for DB persistence - Add API_CO_ID_KEY and HOLIDAYS_DB_PATH env vars to Dockerfile and .env.example - Remove scripts/ directory (replaced by MCP tool), slim down Dockerfile
This commit is contained in:
@@ -19,6 +19,9 @@ Indonesian stocks are accessed via `market_type="stocks"` and `market_country="i
|
||||
| `find_most_active(market_country="indonesia")` | Most active by volume |
|
||||
| `technical_scan(market_country="indonesia", ...)` | Screen using technical conditions |
|
||||
| `fundamental_scan(market_country="indonesia", ...)` | Screen using fundamental metrics |
|
||||
| `check_holidays(mode="upcoming", limit=10)` | Check IDX holidays (SQLite-cached, `refresh=True` to re-fetch) |
|
||||
| `check_holidays(mode="check", date="2026-05-14")` | Check if a specific date is a holiday |
|
||||
| `check_holidays(mode="range", start_date="...", end_date="...")` | List holidays in a date range |
|
||||
|
||||
---
|
||||
|
||||
@@ -459,7 +462,104 @@ fundamental_scan({
|
||||
|
||||
---
|
||||
|
||||
## 6. Workflow: How to Run Full Analysis
|
||||
## 6. Pre-Analysis Checklist
|
||||
|
||||
Before running any analysis, always perform these 3 preliminary checks:
|
||||
|
||||
### 6.1 Check Today's Date & Market Status
|
||||
|
||||
IDX (Bursa Efek Indonesia) trading schedule:
|
||||
- **Session 1:** 09:00 – 12:00 WIB
|
||||
- **Session 2:** 13:30 – 15:50 WIB (pre-closing: 15:50-16:00)
|
||||
- **Trading days:** Monday – Friday
|
||||
- **Weekend:** Closed Saturday & Sunday
|
||||
|
||||
Use `bash` with `date` to check today's date and day-of-week. Determine if market is open/closed.
|
||||
|
||||
### 6.2 Check Indonesian Holidays (MCP Tool — SQLite Cached)
|
||||
|
||||
IDX is also closed on national holidays. Holidays can cause multi-day breaks (e.g., 4 days off for long weekends), which significantly impacts BSJP and short-term strategies.
|
||||
|
||||
**Use the `check_holidays` MCP tool instead of the shell script** — the data is stored in `holidays.db` (SQLite) so subsequent calls are instant:
|
||||
|
||||
```
|
||||
# Upcoming holidays (default, next 10):
|
||||
check_holidays(mode="upcoming", limit=10)
|
||||
|
||||
# All holidays for a given year:
|
||||
check_holidays(mode="year", year=2026)
|
||||
|
||||
# Check if a specific date is a holiday:
|
||||
check_holidays(mode="check", date="2026-05-14")
|
||||
|
||||
# List holidays in a date range:
|
||||
check_holidays(mode="range", start_date="2026-05-01", end_date="2026-05-31")
|
||||
|
||||
# Force re-fetch from API (bypass cache):
|
||||
check_holidays(mode="upcoming", refresh=True)
|
||||
```
|
||||
|
||||
The first call fetches from the API and caches. Subsequent calls read directly from SQLite. Pass `refresh=True` to force a fresh fetch.
|
||||
|
||||
Requires `API_CO_ID_KEY` in `.env`.
|
||||
|
||||
**Holiday impact on analysis:**
|
||||
- If today is the last trading day before a multi-day holiday, BSJP entries become **extended holds** (2-4 days instead of overnight). The gap at reopening can be larger.
|
||||
- Historical candle data showing "flat" prices across dates may actually mean the market was closed — that the stock didn't move.
|
||||
- Always cross-reference dates against the holiday calendar before drawing conclusions about price action.
|
||||
|
||||
### 6.3 Include Market Calendar in Every Report
|
||||
|
||||
```
|
||||
Analysis Date: {YYYY-MM-DD HH:MM WIB}
|
||||
Day: {Monday/Tuesday/...}
|
||||
Market Status: [OPEN / CLOSED]
|
||||
Last Trading Day: {YYYY-MM-DD}
|
||||
Next Trading Day: {YYYY-MM-DD}
|
||||
Upcoming Holidays: {list any within next 14 days}
|
||||
Holiday Note: {if next trading day is after a break, flag this}
|
||||
```
|
||||
|
||||
### 6.4 News Search for Target Stocks
|
||||
|
||||
Before analyzing any stock, search for recent news that may affect price:
|
||||
|
||||
```
|
||||
websearch(query="{Stock Name} {Ticker} berita saham terbaru {YYYY}")
|
||||
```
|
||||
|
||||
Key things to look for:
|
||||
- Earnings releases / financial reports
|
||||
- Insider buying/selling
|
||||
- Sector-wide news (commodity prices, regulation changes)
|
||||
- Corporate actions (stock split, rights issue, buyback)
|
||||
- Analyst ratings changes
|
||||
|
||||
Include relevant news in the report under a "Recent News & Catalysts" section.
|
||||
|
||||
### 6.5 Determine Analysis Type
|
||||
|
||||
Depending on what the user asks, pick one of these paths:
|
||||
|
||||
| Analysis Type | Data Needed |
|
||||
|--------------|-------------|
|
||||
| **Full fundamental + technical** | All columns (Section 4 template) |
|
||||
| **BSJP (Beli Sore Jual Pagi)** | Top losers today, RSI, volume, BB.lower, market cap |
|
||||
| **Breakout scan** | RSI 50-70, SMA50/200, ADX >25, rel volume >1.5 |
|
||||
| **Oversold bounce** | RSI <30, near SMA200/SMA50, volume confirmation |
|
||||
| **Dividend hunting** | Dividend yield, payout ratio, P/E, market cap |
|
||||
|
||||
---
|
||||
|
||||
## 7. Workflow: How to Run Full Analysis
|
||||
|
||||
**Step 0** — Run Pre-Analysis Checklist (Section 6):
|
||||
```
|
||||
date → check today's date & day
|
||||
check_holidays(mode="upcoming") → check upcoming IDX holidays (SQLite-cached)
|
||||
check_holidays(mode="check", date="YYYY-MM-DD") → verify if key dates are holidays
|
||||
websearch → check news for target ticker
|
||||
```
|
||||
|
||||
**Step 1** — Get company overview & fundamentals:
|
||||
```
|
||||
@@ -485,7 +585,7 @@ screen_market({
|
||||
|
||||
---
|
||||
|
||||
## 7. Field Reference (for constructing queries)
|
||||
## 8. Field Reference (for constructing queries)
|
||||
|
||||
### Indonesian Stock Ticker Format
|
||||
- `IDX:BBRI` — Bank Rakyat Indonesia
|
||||
|
||||
Reference in New Issue
Block a user