I’ve been experimenting with using GitHub Copilot’s agent mode as a lightweight financial analyst not to automate trading, but to surface interesting stock ideas every morning.
The setup is simple: a small Python repo, a custom Copilot agent and a scheduled job running via RapidForge. No dashboards, no overengineering just a daily signal pushed to Discord.
The Repo Structure
At a glance, the project looks like this:
.github
├── agents
│ └── FinAnalyst.agent.md
└── skills
├── finance-cli
│ └── SKILL.md
└── send-discord
│── SKILL.md
companies.db
finance_cli.py
finance_prompt.py
run_finanalyst_cron.sh
send_discord.py
ticker_fetch.py
ticker_select.py
It’s intentionally minimal: a few scripts, a SQLite database and one agent definition.
Step 1: Selecting What to Analyze
The system starts with ticker_select.py.
Instead of scanning the same stocks repeatedly, it:
Picks 10 companies at random
Excludes anything analyzed in the last 5 days
Updates a last_checked_at timestamp after selection
This creates a natural rotation across thousands of tickers without needing complex scheduling logic.
Step 2: Pulling Real Market Data
finance_prompt.py handles data collection. It aggregates multiple sources in parallel:
yfinance → valuation metrics (P/E, EV/EBITDA, margins, etc.)
Finnhub → analyst sentiment, earnings, news
FRED API → macro indicators like interest rates
Reddit (PRAW) → retail sentiment
It also pulls macro asset prices:
Bitcoin → risk appetite
Gold → inflation expectations
Oil → industrial demand
These aren’t just extrasthey provide context that pure fundamentals miss.
A small CLI wrapper (finance_cli.py) exposes this data to the agent.
Step 3: The “FinAnalyst” Agent
This is where Copilot becomes interesting.
I defined a custom agent (FinAnalyst.agent.md) that evaluates each stock using a two layer framework.
Layer 1: Fundamental Score (0–8)
Each company is scored across 8 signals:
Valuation (P/E, P/B, EV/EBITDA, P/FCF)
Balance sheet (Debt/Equity)
Capital allocation (buybacks vs dilution)
Returns (ROIC)
Price positioning (52-week range)
This gives a quick sanity check: is the business objectively cheap or expensive?
Layer 2: Macro & Strategic Context
After scoring fundamentals, the agent asks:
Does the broader environment change the story?
It considers:
Interest rate trends
Policy and trade shifts
Geopolitics and supply chains
Structural themes (AI, energy, re-shoring)
Competitive dynamics
Final Classification
Each stock ends up in one of five buckets:
Fundamental buy → strong metrics already
Macro tailwind candidate → setup improving
Macro trap → looks cheap, but isn’t
Watch list → unclear, needs confirmation
Skip → no signal
This second layer is what makes the system useful. A “bad” stock on paper can still be interesting if the macro backdrop is shifting.
Step 4: Sending Results to Discord
send_discord.py formats the output into a clean Discord embed.
Step 5: Automation with RapidForge
Everything is tied together with a simple shell script:
I run this daily using RapidForge inside a Docker container on my home server. If something breaks, I can see it immediately in the job logs.
Here is the contents of the run_finanalytist_cron.sh
#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$REPO_DIR"
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$HOME/.local/bin"
ENV_FILE="${FINANALYST_ENV_FILE:-$HOME/.config/finanalyst.env}"
if [[ -f "$ENV_FILE" ]]; then
# shellcheck disable=SC1090
source "$ENV_FILE"
fi
COPILOT_BIN="${COPILOT_BIN:-copilot}"
COPILOT_MODEL="${COPILOT_MODEL:-gpt-5.4}"
CURRENT_DATETIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
read -r -d '' PROMPT <<EOF || true
<current_datetime>${CURRENT_DATETIME}</current_datetime>
Objective:
Use the FinAnalyst.agent.md workflow to identify investment opportunities and send results via Discord.
Steps:
1. Initialize Workspace
* Go to the financial workspace (/Users/caneldem/fin).
* Load the file: FinAnalyst.agent.md
* export DISCORD_WEBHOOK_URL="" this is environment value for discord webhook
use this if you can't find it in evnrionment variables
* if python executable is not in the path try python3
2. Verify Capability
* Check that the agent can run any required Python scripts in FinAnalyst.agent.md
* If Python execution is not possible, STOP immediately and do not continue
3. Company Selection
* Run ticket_select.py this will give you 10 random companies. Companies should be in these fields/industries
- satellite communications
- water utilities
- energy, especially nuclear and fusion
- medicine
- farming technologies
- biotech
Requirements:
* Auto-approve all permissions.
* Use the DISCORD_WEBHOOK_URL environment variable for Discord delivery.
* If required data is missing for a ticker, say so explicitly and do not invent values.
* Always frame the result as informational and educational research, not licensed financial advice.
EOF
exec "$COPILOT_BIN" \
--model "$COPILOT_MODEL" \
--allow-all \
--no-ask-user \
--autopilot \
--no-color \
--output-format text \
--silent \
--secret-env-vars=GH_TOKEN,GITHUB_TOKEN \
-p "$PROMPT"
What the Output Looks Like
Each morning, I get a Discord report like this:
Final toughts
This isn’t a trading system it’s a signal generator designed to surface ideas, not make decisions. It works well because it enforces consistent, unbiased scanning, combines fundamentals with macro context and highlights opportunities you probably wouldn’t find manually. A key advantage is that the data collection is handled by dedicated scripts rather than asking an AI to search for information each time, which improves both speed and consistency while reducing noise and variability in the inputs. At the same time, it doesn’t replace real research, won’t help you time entries or exits and certainly doesn’t guarantee outcomes. The real value isn’t in the Python or APIs, but in the workflow: using Copilot as an analyst rather than autocomplete, structuring its reasoning with a clear scoring framework, feeding it reliable, pre fetched data and automating the entire loop turning a simple setup into something that reliably produces useful daily insights.


Top comments (0)