Install
openclaw skills install ai-stock-watchdogDaily monitoring for Indian equity holdings (NSE/BSE) using a documented severity rubric. Silent by default — only surfaces Sev-1 events (governance, cash flow, promoter/pledge, surveillance, earnings, flows). Includes quarterly checks, segment view for conglomerates, and guidance tracking.
openclaw skills install ai-stock-watchdogDaily monitoring for NSE/BSE holdings against
severity-rubric.md. Silence by default — notify only when a Sev-1 rule fires or the portfolio-health rules say so. Results depend on available sources and search quality; verify material facts yourself.
All data files live in the same directory as this SKILL.md file, referred to as {SKILL_DIR}. Resolve it to the actual absolute path at runtime.
Files:
{SKILL_DIR}/portfolio.json — holdings, watchlist, preferences, holding periods{SKILL_DIR}/competitors.json — sector peers + conglomerate segment mapping{SKILL_DIR}/severity-rubric.md — Sev-1/2/3 classification rules{SKILL_DIR}/sources.md — data sources with search query templates{SKILL_DIR}/state/last-run.json — alerts sent, results calendar, management guidance tracker, suppression log{SKILL_DIR}/alerts/{YYYY-MM-DD}-*.md — archived alerts{SKILL_DIR}/state/portfolio-backup-{TS}.json — auto-backups| User message contains... | Run |
|---|---|
portfolio.json _first_run: true, OR "set up stock monitor" / "start monitoring" | Onboarding Workflow |
| "I bought", "I sold", "add to portfolio", "trim", "exit", "update my portfolio", broker screenshot | Portfolio Update Workflow |
| "check my stocks", "morning brief", "scan", "anything I should know", scheduled run | Daily Monitoring Workflow |
| "portfolio health check", "how's my portfolio", "concentration risk" | Portfolio Health Check (then optionally Daily Monitoring) |
| Ambiguous | Ask the user which they want |
portfolio.json starts with _first_run: true and empty holdings. Detect on first invocation. NEVER skip — always offer setup.
Greet warmly. Explain in plain language:
Use AskUserQuestion (if available) OR ask in chat:
"How would you like to share your portfolio?"
- Drop a screenshot of my broker app (Zerodha, Groww, Upstox, Angel One, etc.)
- Describe in text (e.g., "50 shares of XYZ at avg 1500, 10 shares of ABC at 2900")
- Skip for now
Follow Update Workflow (Update-2+) for processing.
Ask:
Save into portfolio.json → preferences.
Offer daily schedule for the Daily Monitoring Workflow every weekday at 8:30 AM IST.
mcp__scheduled-tasks__create_scheduled_task is available: use it with cron 30 8 * * 1-5. This tool only creates a time-based cron trigger — no shell access.Offer: "Want me to do a first-look scan now? I'll check the last 7 days of news, filings, promoter activity, and surveillance status for your holdings."
If yes, run Daily Monitoring Workflow once. If no, confirm setup done.
Set _first_run: false in portfolio.json. Save.
The user never edits portfolio.json. They describe changes or drop screenshots.
Read image using vision. Extract: ticker/company name, quantity, average buy price, broker.
Common layouts:
CRUCIAL: Before computing diff, ASK: "Is this your complete portfolio, or just additions/changes?" Default: layer onto existing. Never silently remove based on absence.
If truncated (scroll indicator, "+N more"), ask to scroll and re-upload.
Parse natural language:
competitors.json → ticker_to_sector. If found, use it.sector_peers.conglomerate_segments key in competitors.json), also note the segment mapping for the ticker if it exists.competitors.json. Never leave sector blank.When adding a new stock, record buy_date: "{YYYY-MM-DD}" in portfolio.json. This is used for:
Read {SKILL_DIR}/portfolio.json. Compute proposed new state.
NEVER write without explicit confirmation:
Proposed portfolio update:
✱ ADD {TICKER_A} qty: 10 avg: ₹2,900 sector: {sector}
✏ UPDATE {TICKER_B} qty: 50→75 avg: ₹1,620→₹1,607 (weighted)
✗ REMOVE {TICKER_C} (full exit)
Concentration check: {TICKER_A} would be 28% of portfolio — within limits.
Summary: +1 new, 1 increased, 1 exit. Net 2 holdings.
Apply? (yes / no / edit)
Wait for explicit confirmation.
{SKILL_DIR}/state/portfolio-backup-{YYYY-MM-DD-HHMMSS}.jsoncompetitors.json → ticker_to_sector for new tickersnew_avg = ((old_qty × old_avg) + (new_qty × new_price)) / (old_qty + new_qty)
Show the calculation. If user states explicit avg, use theirs.
Run this before daily monitoring OR when user asks "how's my portfolio" / "portfolio health check". This catches structural risks the daily scan doesn't.
buy_date.If current price data is available from scan:
You apply this skill's rubric to Indian equities. Job: silence by default. Only surface when a Sev-1 trigger matches severity-rubric.md (plus the notify rules below). False positives erode trust faster than missed noise.
{SKILL_DIR}/portfolio.json. If _first_run: true OR holdings empty → route to Onboarding.holdings.competitors.json. Build peer set.{SKILL_DIR}/state/last-run.json for alert history and management guidance tracker.Before stock-level scanning, check:
If NSE is closed today (Republic Day, Holi, Diwali, etc.), skip the scan. Update state with "market_holiday" and exit.
Quick search for:
Search: US close (Dow/Nasdaq/S&P), GIFT Nifty, Brent crude, USD/INR, US 10Y yield, India VIX.
Only flag if global shock directly maps to a holding:
For each held ticker, run in parallel:
Search: site:nseindia.com "{COMPANY_NAME}" announcement, site:bseindia.com "{COMPANY_NAME}".
Look for: results dates, board meetings, auditor changes, KMP exits, credit rating actions, pledge disclosures, SAST/PIT filings, corporate governance reports, scheme of arrangement.
"{COMPANY_NAME}" news last 1 day — prefer Moneycontrol / ET / Reuters / Mint / Business Standard"{COMPANY_NAME}" SEBI last 7 days"{COMPANY_NAME}" ED CBI "income tax" raid last 30 days (only if NEW)"{COMPANY_NAME}" downgrade last 7 days"{COMPANY_NAME}" fraud whistleblower "forensic audit" last 90 days (only if NEW)Promoter holding & pledge (check against latest quarterly shareholding pattern):
"{COMPANY_NAME}" promoter holding or "{TICKER}" shareholding patternInsider trading disclosures (last 7 days):
"{TICKER}" insider trading SAST PIT disclosure site:nseindia.comBlock/bulk deals (last 24h):
"{TICKER}" block deal bulk dealFII/MF holding changes (when quarterly data available):
"{TICKER}" GSM ASM surveillance. Cache 7 days.For each sector:
state/last-run.json → results_calendar.If the ticker is flagged as a conglomerate in competitors.json → conglomerate_segments:
key_metrics for each segment in the data file.Classify each signal against severity-rubric.md. Apply context modifiers:
Suppression rule: If already alerted on same signal_id in last 14 days, suppress.
Quarterly deep-dive should cover cash flow quality and segment trends, not only headline PAT and EPS vs consensus.
Pull from BSE/NSE filing, Screener, or Trendlyne:
Pull cash flow statement (Screener cash flow tab or filing):
For companies with multiple reported segments (refer to conglomerate_segments in competitors.json for segment definitions):
key_metrics from the conglomerate_segments data to know which numbers to pull for each segment.Pull consensus from Trendlyne or Moneycontrol:
Locate transcript (Screener Documents tab or company IR):
state/last-run.json → guidance_tracker.Same as Step 5 but summarized: one paragraph per peer (QoQ delta + concall tone). Sector-level read: "Industry trend: {strong / mixed / weak / deteriorating}."
Surface ONLY if it changes the read on a held stock.
Notify only if:
Otherwise — update state and exit silently.
EXCEPTION: if delivery = daily_brief, always post a one-liner: "All clear — no Sev-1 across {N} holdings as of {time}."
Save to {SKILL_DIR}/alerts/{YYYY-MM-DD}-alert.md AND surface in chat:
🔴 STOCK ALERT — {date}
{TICKER} — {one-line headline}
Severity: Sev-1 | Category: {rubric section} | Sector: {sector}
What happened:
{2-3 lines, factual, with specific numbers}
Why it matters for YOU ({horizon} holder, avg ₹{avg_price}, {N} shares):
- {bullet 1 — direct portfolio impact}
- {bullet 2 — what this historically leads to}
Suggested action: {Hold / Watch closely / Trim / Exit bias}
Confidence: {High / Medium / Low}
Management credibility: {High / Medium / Low} (based on {N} quarters tracked)
Sources:
- [Title](URL)
- [Title](URL)
Counter-view: {one line — what could make this NOT critical}
Portfolio impact: This holding is {X}% of your portfolio. {If concentrated: "Given your concentrated position, consider this signal with extra weight."}
If multiple stocks triggered, repeat per ticker. Group by severity.
Update {SKILL_DIR}/state/last-run.json:
last_run_date: today's datealerts_sent: append any new alerts with signal_id and timestampresults_calendar: update upcoming/past results datesguidance_tracker: store management guidance numbers for forward comparisonpromoter_holding_history: store latest promoter holding % and pledge % per tickerinstitutional_holding_history: FII %, DII %, MF holding % per tickermanagement_credibility: running score per company based on guidance vs actualsurveillance_check: last checked date, any active GSM/ASM entries_first_run: true or holdings empty → route to Onboarding.User can trigger ad-hoc:
In ad-hoc mode, run same workflow but if nothing critical, give a one-liner: "All clear — no Sev-1 triggers across {N} holdings as of {time}." rather than total silence.