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:
Achmad
2026-05-17 07:31:51 +00:00
parent 568be26adc
commit c31096fe4b
5 changed files with 361 additions and 2 deletions
+102 -2
View File
@@ -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