Initial commit: A-share stock analysis project with screening, backtesting, and multi-factor analysis tools

This commit is contained in:
2026-07-01 06:39:40 +00:00
commit d80c208004
19 changed files with 1542 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
__pycache__/
*.py[cod]
*.egg-info/
dist/
.venv/
venv/
.env
.idea/
.vscode/
*.swp
*.swo
.DS_Store
+77
View File
@@ -0,0 +1,77 @@
---
name: market-overview
description: Assess current A-share market environment including index trends, market breadth, sector rotation, and position sizing recommendation
---
## What I Do
Evaluate the overall A-share market environment to determine:
1. Whether the market is favorable for medium-term trading
2. Suggested position sizing in RMB (capital-aware, for ~5万 account)
3. Current hot sectors and rotation patterns
4. Key risk factors
## Capital Context (CRITICAL)
**The user has ~5万 RMB capital.** Position sizing must be translated to concrete RMB amounts, not abstract percentages alone.
### Position Sizing for 5万 Account
| Signal | Total Position | Max Per Stock | Holding Count |
|--------|---------------|---------------|---------------|
| **Heavy (bullish)** | ¥35,00040,000 (7080%) | ¥10,00015,000 each | 34 positions |
| **Moderate (neutral)** | ¥15,00025,000 (3050%) | ¥5,00010,000 each | 23 positions |
| **Light (bearish)** | <¥15,000 (<30%) | <¥5,000 each | 12 positions |
Always present both: percentage of capital AND the corresponding RMB range.
## Assessment Dimensions
### Index Trend
- Shanghai Composite (000001), Shenzhen Component (399001), ChiNext (399006)
- Direction, strength, and stage of trend
- Key support/resistance levels
- 20/60-day MA relationship
### Market Breadth
- Advancing vs declining stocks ratio
- Volume trend (expanding / contracting)
- New highs vs new lows
- % of stocks above 20-day MA
### Sector Rotation
- Leading and lagging sectors
- Sector fund flow
- Continuity of sector trends (how many days in a row?)
## When to Use Me
Use when the user asks to:
- Check market conditions
- Decide position size
- Understand sector rotation
- Before running any stock screening
## Workflow
1. Fetch major index data via `stock-data index`
2. Fetch sector performance via `stock-data sector`
3. Analyze market breadth indicators
4. Identify sector hotspots and rotation signals
5. Output a structured market assessment:
### Output Format
1. **Market Signal**: Strong / Moderate / Weak — with justification
2. **Index Summary**: each index trend + key level
3. **Market Breadth**: breadth reading and what it means
4. **Hot Sectors**: top 35 sectors with momentum
5. **Position Recommendation**:
- Signal-based allocation in RMB and %
- Max per stock in RMB
- Suggested holding count
6. **Key Risks**: specific market risks to watch this week
## Risk Disclaimer
Always remind the user: results are for reference only. Market conditions can change rapidly. Position sizing is a suggestion, not financial advice.
+97
View File
@@ -0,0 +1,97 @@
---
name: stock-analyzer
description: Deep analysis of a single A-share stock covering technical, fundamental, capital flow, and sentiment dimensions
---
## What I Do
Generate a comprehensive analysis report for a single stock:
1. Fetch all relevant data for the stock
2. Analyze across four dimensions
3. Score each dimension (0-100)
4. Provide overall rating and actionable insights
## Capital Context (CRITICAL)
**The user has ~5万 RMB capital.** Every analysis must include:
- **Affordability check**: confirm the stock price × 100 shares is within reach
- **Position sizing advice**: based on market conditions and stock risk profile, suggest how many lots the user should buy
- **Risk in RMB**: always show stop-loss and take-profit levels in both percentage AND absolute RMB amount
- **Transaction cost**: calculate estimated round-trip cost for the suggested position
### Affordability Check
```
这股票一手要多少钱? 股价 × 100 = ____ 元
用户能买几手? 分配的仓位金额 ÷ (股价 × 100) = ____ 手
```
## Analysis Dimensions
### Technical Analysis
- Trend positioning: identify if stock is in uptrend/downtrend/sideways
- Moving average status: check MA alignment (5/10/20/60 day)
- Support/Resistance levels: identify key price levels
- Volume analysis: volume trend, volume-price divergence signals
- RSI/MACD: oscillator readings and signals
### Capital Flow Analysis
- Main fund flow: net inflow trend over 3/5/10 days
- Northbound capital: recent changes (if available)
- Large order ratio: institutional activity signals
### Fundamental Analysis
- Valuation: PE/PB historical percentile
- Profitability: ROE trend
- Growth: revenue and profit YoY growth
- Quick health check: debt ratio, cash flow
### Sentiment Analysis
- Recent news: key announcements in past 30 days
- Analyst ratings: direction of recent rating changes
## Scoring
Weighted composite score (0-100):
- Technical: 35%
- Capital Flow: 30%
- Fundamental: 25%
- Sentiment: 10%
## When to Use Me
Use when the user asks to:
- Analyze a specific stock by name or code
- Evaluate whether a stock is worth buying
- Get a detailed report on a stock
## Workflow
1. Get stock code (ask user if not provided)
2. Call `stock-data` tools to fetch all data
3. Analyze each dimension, calculate scores
4. Perform affordability check (price × 100 vs 5万 budget)
5. Present a structured report with:
### Report Sections
1. **Basic Info**: name, code, price, sector, market cap, 1手 cost
2. **Overall Score**: composite rating with grade (A/B/C/D)
3. **Dimension Breakdown**: each dimension's score with key observations
4. **Technical Check**: trend, support/resistance, volume signal
5. **Capital Flow Check**: recent money flow pattern and what it means
6. **Fundamental Check**: valuation context, growth trajectory
7. **News & Sentiment**: key events, sentiment direction
8. **Position Suggestion**:
- Suggested lot count (based on market signal + stock risk)
- Total cost in RMB
- Estimated round-trip transaction cost
9. **Risk Management**:
- Stop-loss level: price (¥) and loss amount (¥) with percentage
- Take-profit target: price (¥) and gain amount (¥) with percentage
10. **Verdict**: Watch / Consider / Caution / Avoid — with one-sentence reason
11. **Risk Disclaimer**: results for reference only
## Risk Disclaimer
Always remind the user: results are for reference only. Past performance does not guarantee future results. The user bears all trading risk.
+78
View File
@@ -0,0 +1,78 @@
---
name: stock-backtest
description: Design, run, and interpret strategy backtests for A-share stocks
---
## What I Do
Guide the agent through backtesting trading strategies:
1. Help design strategy rules from user descriptions
2. Run backtests on historical data
3. Interpret results and identify potential issues
4. Suggest improvements
## Capital Context (CRITICAL)
**The user has ~5万 RMB capital.** Backtest interpretation must be capital-aware:
- When presenting metrics, translate key numbers to the user's context:
- "Annualized return 15% = ¥7,500 on 5万"
- "Max drawdown 12% = ¥6,000 worst-case loss"
- "Average win ¥800, average loss ¥1,200 per trade"
- Assess whether a strategy is **practically usable** with 5万 considering position sizing constraints
- Flag if a strategy requires more positions than 5万 can support
## Key Backtest Metrics
- **Cumulative return**: total return over the period
- **Annualized return**: normalized yearly return (translate to ¥ on 5万)
- **Win rate**: percentage of profitable trades
- **Max drawdown**: worst peak-to-trough decline (translate to ¥)
- **Sharpe ratio**: risk-adjusted return
- **Benchmark comparison**: vs CSI 300 index
## Strategy Parameters
Common strategy elements to help users define:
- Entry conditions (e.g., MA crossover, breakout, pullback)
- Exit conditions (e.g., stop loss %, take profit %, trailing stop, time-based)
- Position sizing (e.g., fixed %, Kelly fraction)
- Test period and stock universe
## When to Use Me
Use when the user asks to:
- Backtest a trading strategy
- Verify a strategy's historical performance
- Compare multiple strategies
- Evaluate whether a strategy is worth using
## Workflow
1. Clarify strategy rules with user
2. Translate rules into testable parameters
3. Run backtest via `stock-backtest` tools
4. Present results with interpretation:
### Output Format
1. **Strategy Summary**: rules in plain language
2. **Performance Metrics**: all key metrics in table form
3. **Capital Context Translation**:
| Metric | Value | On 5万 Capital |
|--------|-------|----------------|
| Annualized Return | 18% | ¥9,000/year |
| Max Drawdown | 15% | ¥7,500 worst case |
| Avg Win per Trade | ¥450 | — |
| Avg Loss per Trade | ¥600 | — |
4. **Equity Curve Description**: shape, drawdown periods, recovery time
5. **Benchmark Comparison**: outperformance/underperformance vs CSI 300
6. **Practicality Assessment for 5万**:
- Can the user afford the position sizes?
- Does the strategy require too many concurrent positions?
- Is the max drawdown psychologically tolerable?
7. **Potential Concerns**: overfitting, look-ahead bias, survivorship bias, regime dependence
## Risk Disclaimer
Always remind: backtest results reflect historical data. Live performance will differ. Strategies can fail in new market regimes. The user bears all trading risk.
+79
View File
@@ -0,0 +1,79 @@
---
name: stock-screener
description: Multi-factor A-share stock screening workflow for medium-to-short-term selection
---
## What I Do
Guide the agent through a structured stock screening process:
1. Understand user preferences (industry, market cap, holding period)
2. Assess market environment via `market-overview` skill
3. Call screening tools to find candidates
4. Score and rank candidates by multi-factor model
5. Output **Top 3-5** picks with rationale, position sizing, and cost estimates
## Capital Context (CRITICAL)
**The user has ~5万 RMB capital.** Every recommendation must account for this:
- **Stock price filter**: each recommended stock must cost ¥10–¥50 per share so the user can afford at least 1手 (100 shares). Stocks >¥200 need explicit justification (concentrated bet). Stocks >¥500 are completely inaccessible — never recommend them.
- **Portfolio concentration**: default output is 35 stocks, not 10+. The user holds 24 stocks max.
- **Position sizing**: for each recommended stock, suggest a specific lot count and total cost in RMB.
- **Transaction cost**: for each recommended position, calculate estimated one-way cost (commission + stamp tax). Surface it alongside the position suggestion.
### Position Sizing Table (5万 context)
| Market Signal | Total Exposure | Max Per Stock | Holding Count |
|---------------|---------------|---------------|---------------|
| Strong uptrend | 35,00040,000 (7080%) | 10,00015,000 | 34 positions |
| Neutral/sideways | 15,00025,000 (3050%) | 5,00010,000 | 23 positions |
| Weak/downtrend | <15,000 (<30%) | <5,000 | 12 positions |
### Affordability Check
Before recommending any stock, verify:
```
股价 × 100 shares ≤ 计划分配给该股的仓位金额
```
Example: ¥38 stock × 100 = ¥3,800. With ¥10,000 allocation, the user can buy 2手 (200 shares, ¥7,600).
## Screening Dimensions
- **Technical (35%)**: Trend strength, moving average alignment, volume-price coordination, RSI position
- **Capital Flow (30%)**: Main fund net inflow trend, northbound capital, large order ratio
- **Fundamental (25%)**: PE percentile, ROE, profit growth, revenue growth
- **Sentiment (10%)**: News heat, analyst rating direction
## When to Use Me
Use when the user asks to:
- Find/screen stocks for investment
- Get stock recommendations
- Filter stocks by any criteria
## Workflow
1. Ask the user about preferences if not specified (sector, style, time horizon)
2. Load `market-overview` skill to check if market is favorable and get position sizing signal
3. Use `stock-screen` tools to filter candidates (default top_n=5)
4. For each top candidate, verify affordability:
- Check share price, calculate minimum buy cost (price × 100)
- Cross-check against the position sizing budget
- Filter out any stock the user cannot afford
5. For remaining candidates, run quick analysis with relevant tools
6. Present a ranked list with:
- Rank and composite score (0-100)
- Key strengths (why buy?) and risks (what can go wrong?)
- Suggested position: lot count × share price = total cost
- Estimated transaction cost for this position
- Stop-loss price in both ¥ and percentage
### Output Format Example
| Rank | Stock | Price | Score | Position | Cost | Stop-Loss | Rationale |
|------|-------|-------|-------|----------|------|-----------|-----------|
| 1 | 600XXX | ¥28.5 | 82 | 3手 (300股) = ¥8,550 | 交易费~¥14 | ¥25.7 (-10%, -¥855) | 放量突破+主力净流入 |
## Risk Disclaimer
Always remind: results are for reference only. Past performance does not guarantee future results. The user bears all trading risk.
+53
View File
@@ -0,0 +1,53 @@
import { tool } from "@opencode-ai/plugin";
import path from "path";
const SCRIPTS_DIR = (ctx: { worktree: string }) =>
path.join(ctx.worktree, "scripts");
async function runPython(
ctx: { worktree: string },
fn: string,
args: Record<string, unknown>,
): Promise<string> {
const scriptPath = path.join(SCRIPTS_DIR(ctx), "backtest_engine.py");
const argsJson = JSON.stringify(args);
const result = await Bun.$`python3 ${scriptPath} ${fn} ${argsJson}`.text();
return result.trim();
}
export const run = tool({
description: "Run a backtest for a trading strategy on specified stock universe and period",
args: {
strategy_name: tool.schema.string().optional().describe("Name of a predefined strategy, or omit to use custom rules"),
entry_rule: tool.schema.string().optional().describe("Custom entry condition (Python expression using df columns like close, ma20, ma60, volume, etc.)"),
exit_rule: tool.schema.string().optional().describe("Custom exit condition (Python expression) or 'stop_loss:0.05,take_profit:0.15,max_hold:20'"),
universe: tool.schema.enum(["hs300", "zz500", "all", "custom"]).default("hs300").describe("Stock universe to test on"),
symbols: tool.schema.string().optional().describe("Comma-separated stock codes for custom universe"),
start_date: tool.schema.string().default("20210101").describe("Start date YYYYMMDD"),
end_date: tool.schema.string().default("20251231").describe("End date YYYYMMDD"),
},
async execute(args, context) {
return runPython(context, "run", args);
},
});
export const predefined = tool({
description: "List all predefined backtest strategies with descriptions",
args: {},
async execute(args, context) {
return runPython(context, "predefined", args);
},
});
export const compare = tool({
description: "Compare multiple predefined strategies on the same universe and period",
args: {
strategies: tool.schema.string().describe("Comma-separated strategy names to compare"),
universe: tool.schema.enum(["hs300", "zz500", "all"]).default("hs300").describe("Stock universe"),
start_date: tool.schema.string().default("20210101").describe("Start date YYYYMMDD"),
end_date: tool.schema.string().default("20251231").describe("End date YYYYMMDD"),
},
async execute(args, context) {
return runPython(context, "compare", args);
},
});
+83
View File
@@ -0,0 +1,83 @@
import { tool } from "@opencode-ai/plugin";
import path from "path";
const SCRIPTS_DIR = (ctx: { worktree: string }) =>
path.join(ctx.worktree, "scripts");
async function runPython(
ctx: { worktree: string },
script: string,
fn: string,
args: Record<string, unknown>,
): Promise<string> {
const scriptPath = path.join(SCRIPTS_DIR(ctx), script);
const argsJson = JSON.stringify(args);
const result = await Bun.$`python3 ${scriptPath} ${fn} ${argsJson}`.text();
return result.trim();
}
export const quote = tool({
description: "Get daily/weekly K-line and real-time quotes for a stock",
args: {
symbol: tool.schema.string().describe("Stock code (e.g. 600519 for Kweichow Moutai)"),
period: tool.schema.enum(["daily", "weekly", "monthly"]).default("daily").describe("K-line period"),
start_date: tool.schema.string().optional().describe("Start date YYYYMMDD, defaults to 90 days ago"),
end_date: tool.schema.string().optional().describe("End date YYYYMMDD, defaults to today"),
},
async execute(args, context) {
return runPython(context, "market_data.py", "quote", args);
},
});
export const financial = tool({
description: "Get financial statement indicators for a stock",
args: {
symbol: tool.schema.string().describe("Stock code (e.g. 600519)"),
},
async execute(args, context) {
return runPython(context, "market_data.py", "financial", args);
},
});
export const moneyflow = tool({
description: "Get capital flow data (main fund, northbound) for a stock",
args: {
symbol: tool.schema.string().describe("Stock code (e.g. 600519)"),
days: tool.schema.number().default(10).describe("Number of recent days"),
},
async execute(args, context) {
return runPython(context, "market_data.py", "moneyflow", args);
},
});
export const news = tool({
description: "Get recent news and announcements for a stock",
args: {
symbol: tool.schema.string().describe("Stock code (e.g. 600519)"),
limit: tool.schema.number().default(20).describe("Max number of news items"),
},
async execute(args, context) {
return runPython(context, "sentiment.py", "news", args);
},
});
export const index = tool({
description: "Get major A-share index data (Shanghai Composite, Shenzhen Component, ChiNext)",
args: {
index_code: tool.schema.enum(["sh", "sz", "cyb", "all"]).default("all").describe("Index to fetch"),
days: tool.schema.number().default(30).describe("Number of recent trading days"),
},
async execute(args, context) {
return runPython(context, "market_data.py", "index", args);
},
});
export const sector = tool({
description: "Get sector/industry performance and ranking",
args: {
date: tool.schema.string().optional().describe("Date YYYYMMDD, defaults to latest"),
},
async execute(args, context) {
return runPython(context, "market_data.py", "sector", args);
},
});
+61
View File
@@ -0,0 +1,61 @@
import { tool } from "@opencode-ai/plugin";
import path from "path";
const SCRIPTS_DIR = (ctx: { worktree: string }) =>
path.join(ctx.worktree, "scripts");
async function runPython(
ctx: { worktree: string },
fn: string,
args: Record<string, unknown>,
): Promise<string> {
const scriptPath = path.join(SCRIPTS_DIR(ctx), "stock_screener.py");
const argsJson = JSON.stringify(args);
const result = await Bun.$`python3 ${scriptPath} ${fn} ${argsJson}`.text();
return result.trim();
}
export const multi_factor = tool({
description: "Screen stocks using multi-factor scoring model (technical + capital flow + fundamental + sentiment)",
args: {
strategy: tool.schema.enum(["comprehensive", "momentum", "value", "breakout"]).default("comprehensive").describe("Screening strategy"),
sector: tool.schema.string().optional().describe("Filter by sector/industry name"),
market_cap: tool.schema.enum(["large", "medium", "small", "all"]).default("all").describe("Market cap filter"),
top_n: tool.schema.number().default(5).describe("Number of top stocks to return (user has 5万 capital, keep it tight)"),
},
async execute(args, context) {
return runPython(context, "multi_factor", args);
},
});
export const strong = tool({
description: "Screen for strong-trend stocks (MA bull alignment + relative strength)",
args: {
sector: tool.schema.string().optional().describe("Filter by sector/industry name"),
top_n: tool.schema.number().default(5).describe("Number of top stocks to return (user has 5万 capital, keep it tight)"),
},
async execute(args, context) {
return runPython(context, "strong", args);
},
});
export const breakout = tool({
description: "Screen for volume breakout stocks (price breaking resistance with expanding volume)",
args: {
lookback_days: tool.schema.number().default(60).describe("Lookback period for resistance identification"),
top_n: tool.schema.number().default(5).describe("Number of top stocks to return (user has 5万 capital, keep it tight)"),
},
async execute(args, context) {
return runPython(context, "breakout", args);
},
});
export const oversold = tool({
description: "Screen for oversold stocks with potential rebound signals",
args: {
top_n: tool.schema.number().default(5).describe("Number of top stocks to return (user has 5万 capital, keep it tight)"),
},
async execute(args, context) {
return runPython(context, "oversold", args);
},
});
+149
View File
@@ -0,0 +1,149 @@
# Stock Analysis Project - Agent Instructions
This project is an A-share (Chinese stock market) stock selection assistant built on opencode with Skills and Custom Tools.
## Project Purpose
Help users make informed medium-to-short-term stock selection decisions through multi-factor quantitative analysis.
All analysis is data-driven using the AKShare Python library. No automated trading - users make their own execution decisions.
## Architecture
- **Python scripts** in `scripts/` — core data fetching, screening, backtesting logic (using AKShare)
- **Custom Tools** in `.opencode/tools/` — TypeScript wrappers that expose Python scripts as LLM-callable tools
- **Skills** in `.opencode/skills/` — structured workflows guiding the agent through analysis steps
## Guiding Philosophy (READ FIRST)
This project is a **laboratory for learning, not a money printer.** Its core value is accelerating the user's learning loop: question → hypothesis → backtest → revise → repeat. All agent behavior, tool output, and skill workflows must align with the principles in:
- `docs/FOUNDATIONS.md` — universal cognitive framework (how to think, reason, and act effectively)
- `docs/PRINCIPLES.md` — FOUNDATIONS.md applied to stock investment (10 domain-specific principles)
## Agent Thinking Framework
When analyzing any problem or proposing any solution, structure your thinking using the framework from `docs/FOUNDATIONS.md`:
### 1. Direction First
Before jumping to solutions, ask: **what is the right thing to pursue?** What > How. Selection > Effort. The direction decision determines everything that follows.
### 2. Think Before Acting
Apply the thinking tools from FOUNDATIONS.md before proposing any plan:
- **Completeness**: are we missing any people, variables, or relationships? An incomplete analysis is wrong no matter how refined.
- **Time scale**: over what period is this judgment valid? Short-term beneficial may be long-term harmful.
- **Asymmetric check**: if A implies B, does B imply A? If not, why? We naturally overlook asymmetry.
- **People & interests**: who are the stakeholders? What are their relationships and incentives? Surface = data. Underlying = people and interests.
- **First principles**: reduce to the most basic, indisputable facts. Rebuild reasoning from there.
- **Simplicity**: is there a simpler explanation or approach? Complexity must be forced by data, not pursued for its own sake.
### 3. Action with Feedback
- **Start with Why**: before executing, clarify the purpose. Action without clear motivation drifts.
- **Define measurable outcomes**: what does success look like?
- **After action**: compare results to expectations. Use the gap to revise direction. No feedback loop = no learning.
### 4. Output Structure
When presenting a proposal or analysis, organize it as:
1. **Direction & Goal** — what are we trying to achieve, and why?
2. **Method** — how will we achieve it?
3. **Action** — what are the specific, executable steps?
4. **Feedback** — how will we measure success and correct course?
## Agent Behavioral Constraints (MANDATORY)
Every analysis, recommendation, and backtest output MUST comply with these rules:
1. **Fact vs. Inference**: clearly separate data (fact) from scoring/interpretation (inference). Never present an opinion as a fact.
2. **Out-of-sample labeling**: every backtest result must explicitly label which period was in-sample (training) and which was out-of-sample (testing). If no split was used, state: "Warning: no out-of-sample validation — results may be overfit."
3. **Trade count**: every backtest result must report the number of actual trades. If trade count < 30, append: "Warning: sample size too small for statistical significance."
4. **Parameter count warning**: state the number of tunable parameters in any strategy. If parameter count ≥ 5, append: "High overfitting risk — requires strict out-of-sample validation."
5. **RMB translation**: all risk metrics (drawdown, stop-loss, position size) must be displayed in both percentage AND absolute RMB terms based on 5万 capital.
6. **Position sizing first**: before any stock selection output, state the recommended position size. Position sizing beats stock selection.
7. **User fitness**: for each strategy recommendation, include a brief "Fitness for You" section covering: (a) max single-trade loss in RMB, (b) psychological difficulty rating (easy/medium/hard), (c) required monitoring frequency.
8. **Uncertainty**: when data is insufficient to conclude, say "data insufficient" rather than fabricating an answer. Uncertainty is honest; false confidence is harmful.
9. **Learning stage awareness**: the user is a beginner. Prefer simple strategies (1-3 parameters) over complex ones. Explain concepts before using jargon. The user's learning is more important than any single trade recommendation.
10. **Reminder cadence**: at least every 5 interactions, remind the user: "You make the final decision. No analysis can guarantee profits. This project is for learning support, not investment advice."
## Key Principles
1. **Verify before trusting** — every strategy must be backtested before recommendation
2. **Data-driven** — all conclusions must reference quantifiable metrics, not subjective judgment
3. **Auxiliary decision-making** — output analysis reports, not trading orders
4. **Risk disclaimer** — always remind the user that results are for reference only
## User Context
**Target user has ~5万 RMB capital, trading A-shares with manual execution.**
Capital constraints affect every recommendation:
- **Stock accessibility**: the user must afford at least 1手 (100 shares). A stock priced at ¥500+ is completely out of reach. Prefer stocks in ¥10–¥50 range.
- **Concentrated portfolio**: with 5万, hold 24 stocks max (not dozens). Screening output should default to Top 35, not Top 1020.
- **Cost awareness**: one round-trip (buy + sell) costs roughly ¥60 (commission ¥5+¥5 + stamp tax ~¥50 at ¥5万 volume). This is 0.12% of capital, manageable if turnover is low. However, splitting into tiny positions amplifies cost. Always calculate and surface the estimated transaction cost for each proposed trade.
- **Psychological reality**: a 5% loss = ¥2500, which feels significant. Risk metrics (stop-loss levels, max drawdown) must be presented in both percentage AND absolute RMB terms.
- **Return expectations**: annualized 20% = ¥10,000. This is a meaningful learning goal, not a wealth-building strategy. Set expectations accordingly.
## Available Skills
- `stock-screener` — multi-factor stock screening workflow (outputs Top 3-5, with position sizing)
- `stock-analyzer` — single stock deep analysis (includes affordability check)
- `market-overview` — market environment assessment (capital-aware position sizing)
- `stock-backtest` — strategy backtesting guidance
## Data Sources
All market data comes from AKShare (Python library). Script location: `scripts/market_data.py`
If data fetching fails, suggest the user to run `pip install akshare --upgrade`.
## Tool Usage Pattern
Custom tools execute Python scripts via `Bun.$`. When a tool fails, check:
1. Python environment is active
2. AKShare is installed and up to date
3. Network is accessible
## Coding Guidelines
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks (typo fixes, one-liners), use judgment.
### 1. Think Before Coding
Before implementing:
- State assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
### 2. Simplicity First
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If 200 lines could be 50, rewrite it.
### 3. Surgical Changes
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it — don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
### 4. Goal-Driven Execution
Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"
For multi-step tasks, state a brief plan with verification steps.
**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
---
*Guidelines adapted from [andrej-karpathy-skills](https://github.com/multica-ai/andrej-karpathy-skills) (MIT)*
+38
View File
@@ -0,0 +1,38 @@
# A股中短期选股辅助系统
基于 opencode + Skill/Custom Tool 的 A股多因子选股分析工具。
## 文档体系
```
docs/FOUNDATIONS.md 通用认知框架(跨领域方法论 — 如何正确思考与行动)
↓ 领域应用
docs/PRINCIPLES.md 股票投资原则(10条领域专属原则)
↓ 翻译为可执行规则
AGENTS.md Agent行为约束 + 思维框架(Agent强制执行规则)
↓ 指导
.opencode/skills/ 工作流技能(选股/分析/回测/大盘)
↓ 调用
.opencode/tools/ + scripts/ 工具与数据层
```
## 快速开始
```bash
# 安装 Python 依赖
pip install -r requirements.txt
# 启动 opencode
opencode
```
## 使用方式
在 opencode 中直接对话:
- "帮我筛选本周有潜力的中短期股票"
- "分析一下贵州茅台 600519"
- "当前大盘环境怎么样,适合操作吗?"
- "回测一下 20日均线上穿60日均线 这个策略过去3年的表现"
详细计划见 [docs/PLAN.md](docs/PLAN.md)
+128
View File
@@ -0,0 +1,128 @@
# 认知操作系统 — 通用思想与方法论
> 本文档位于文档体系(见 `README.md`)的**顶层**
> 是纯粹的元认知框架,不针对任何特定领域。
> 它回答一个根本问题:**我们如何正确地认识世界、思考问题和有效行动?**
>
> 领域应用:`docs/PRINCIPLES.md`
> 执行约束:`AGENTS.md`
> 完整文档层次:`README.md`
---
## 元层:知识组织法则
所有知识分为三层,但不是单向堆叠,而是循环关系:
```
价值观(应该追求什么)
↑↓ 决定并接受修正
方法论(如何追求)
↑↓ 指导并接受修正
实践经验(做了什么、学到了什么)
```
三层不断循环。实践修正方法论,方法论重塑价值观。**没有反馈循环的知识体系是死的。**
---
## 第一脉:战略链 — 方向 > 目标 > 行动 > 反馈
### 方向:选择大于努力
想做什么比能做什么更重要。一个冲突出现时,选择"小事化了"还是"升级事态"——这个方向选择决定了后续一切目标、行动和最终结果。
方向正确,慢也是快。方向错误,快也是倒退。
### 目标:Why 与 What 的顺序
- **研究事物从 What 开始**:先搞清楚"这是什么",再追问"为什么"。先描述,后解释。
- **做事情从 Why 开始**:先想清楚"为什么要做",再决定"做什么"和"怎么做"。
### 行动:可执行的步骤
方向和目标不落地到每天的具体动作,就是幻觉。每个目标必须有一个对应的、明天就可以做的事。
### 反馈:闭环才是学习
观察行动的后果 → 判断目标是否达成 → 判断方向是否正确 → 修正。没有反馈循环,任何方法论都是纸上谈兵。
---
## 第二脉:思维工具 — 理解世界的武器
### 1. 完备性(思考前的第一道检查)
在分析任何问题之前,先问:我考虑到的因素是不是全的?有没有遗漏的人、关系、变量?
不完备的分析再精致也是错的。最难的往往就是做到完备。
### 2. 时间尺度(每个判断的隐含前提)
任何判断都有一个隐含的有效时间范围。短期有利的可能长期有害,长期有效的可能短期难受。没有标注时间尺度的判断是不完整的。
每当你下一个结论,必须追问:这个结论在什么时间范围内成立?
### 3. 非对称检查(正向成立 ≠ 反向成立)
A 在 B 条件下成立,不意味着 B 在 A 条件下成立。我们天然容易忽略这种不对称性。
每次得出一个结论,反问:反过来成立吗?如果不成立,原因是什么?
### 4. 人是最重要的
梳理任何一件事,把参与人一个不漏地列出来。搞清楚人物之间的关系,每个人的利益诉求。做到这一步,事情的来龙去脉自然清晰,走向也能预测。
表面是数字和逻辑,底层是人和利益。
### 5. 性质-关系法(关系 > 性质)
事物的性质是孤立的标签,关系揭示结构。不要只问"它是什么属性",更要问"它和其他事物是什么关系"。
### 6. 第一性原理
不依靠类比和他人结论。把问题拆到最基本的不可再拆的事实,从那里重新推理。不是不能借鉴前人经验,而是不能不经验证地接受。
### 7. 简洁原则(单一原则 + 奥卡姆剃刀)
每个体系里存在一个主导性的组织原则。找到它,其余都是推导。不必要的复杂度不应引入——复杂应该被数据逼出来,不是主动追求的。
---
## 第三脉:行动法则 — 如何有效做事
### 1. 复习比学习更重要
学新东西的快感容易上瘾。但真正改变行为的不是"第一次知道",而是"反复消化"。读完一篇好文章,花三倍时间反复思考它,比再读三篇新文章更有价值。
### 2. 知行合一
知道而做不到,等于不知道。真正的"知道"是你的行为已经发生了改变。如果知道一个道理后你的行为没有任何变化,那不是知识,是信息。
### 3. 刻意练习
不是重复做已经会的,而是:聚焦弱点 → 接受反馈 → 不断增加难度。每一次练习之后必须回答:我练习了什么?哪里不够好?下次怎么做?
### 4. 逆向求解
与其问"如何成功",先问"保证失败的做法是什么",然后反着做。逆向思维揭示正面思考永远发现不了的路径。
---
## 桥接层:不确定性下的理性
### 1. 可证伪性
一个说法如果无论如何都不能被证明是错的,那它不是知识,是信仰。科学知识的特点是:它告诉你在什么条件下它就不成立了。
### 2. 概率思维
世界是不确定的。用概率而非确定性思考。新证据到来时,更新你的信念,而不是固守旧观念。一次结果说明不了问题,大量重复试验的统计分布才是真相。
### 3. 复利思维
微小的持续改进在时间作用下产生指数级效果。每天进步 1%,一年 37 倍。不需要某一天突然变强。需要的是每天都不倒退。
---
*最后更新:2026-07-01*
+207
View File
@@ -0,0 +1,207 @@
# 中短期A股选股辅助系统 — 项目计划
## 一、项目定位
基于 opencode + Skill/Custom Tool 机制构建的 **A股选股分析辅助工具**。利用 AI 辅助多维度分析,
帮助用户做出更有信息量的选股决策。**不涉及自动交易,仅做分析推荐,人工下单。**
## 二、核心原则
1. **验证优先** — 任何策略上线前必须经过历史回测,不依赖未经数据验证的经验法则
2. **辅助决策,而非替代决策** — 输出结构化分析报告,给出评分和依据,最终决策权归用户
3. **数据驱动** — 所有分析基于可量化的数据指标,避免主观模糊的语言
4. **增量迭代** — 先建回测引擎,再建选股工具,最后补舆情分析
## 三、技术架构
```
┌──────────────────────────────────────────────┐
│ opencode TUI │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ Skills │ │ Skills │ │ Skills │ │
│ │ Screener │ │ Analyzer │ │ Overview/ │ │
│ │ │ │ │ │ Backtest │ │
│ └────┬─────┘ └────┬─────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌────▼──────────────▼───────────────▼──────┐ │
│ │ Custom Tools (TypeScript) │ │
│ │ stock-data / stock-screen / backtest │ │
│ └──────────────────┬───────────────────────┘ │
└─────────────────────┼─────────────────────────┘
│ Bun.$ `python3 ...`
┌─────────────────────▼─────────────────────────┐
│ Python Scripts │
│ ┌───────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ AKShare │ │ Screener │ │ Backtest │ │
│ │ Data │ │ Engine │ │ Engine │ │
│ └───────────┘ └──────────┘ └──────────────┘ │
└───────────────────────────────────────────────┘
```
### 数据源
| 数据类别 | 来源 | 说明 |
|----------|------|------|
| 日K/周K行情 | AKShare | `stock_zh_a_hist` |
| 实时行情 | AKShare | `stock_zh_a_spot_em` |
| 财务报表 | AKShare | `stock_financial_analysis_indicator` |
| 资金流向 | AKShare | `stock_individual_fund_flow` |
| 龙虎榜 | AKShare | `stock_sina_lhb_detail_daily` |
| 新闻舆情 | AKShare + 自建爬虫 | `stock_news_em` |
| 板块数据 | AKShare | `stock_board_industry_*` |
## 四、分阶段实施计划
### 阶段 0:环境与框架搭建 ✅
- [x] 初始化项目目录结构
- [ ] 安装 Python 环境与依赖
- [x] 编写 AGENTS.md 供 opencode 理解项目
- [x] 搭建 Custom Tool 骨架(TypeScript → Python 桥接)
- [x] 搭建 Skill 文件骨架
- [x] 适配小资金(5万)场景约束
### 阶段 1:回测引擎(高优先级)
**目标:** 任何策略可以输入规则 + 参数,输出回测报告。
- [ ] 实现回测引擎核心 `backtest_engine.py`
- 模拟交易(按收盘价成交)
- 计算收益曲线、胜率、最大回撤、夏普比率
- 支持多策略对比
- [ ] 实现 `stock-backtest` 工具(TypeScript 包装)
- [ ] 实现回测 Skill(指导 LLM 如何设计、运行、解读回测)
- [ ] 用历史数据跑几个经典策略验证引擎正确性
**验证标准:** 能跑出 60日均线上穿120日均线 这个经典策略在沪深300上的回测结果。
### 阶段 2:选股引擎
**目标:** 多因子打分,输出 Top N 推荐列表。
- [ ] 实现选股筛选器 `stock_screener.py`
- 技术因子:趋势强度、均线排列、量价配合、RSI、MACD
- 资金因子:主力净流入(3/5/10日)、北向资金变化
- 基本面因子:PE 分位、ROE、营收/利润增速
- 消息因子:近期新闻数量、机构评级变化(后续补充)
- 加权打分公式
- [ ] 实现 `stock-screen` 工具
- [ ] 实现选股 Skill(工作流:大盘评估 → 多因子筛选 → 排序输出)
### 阶段 3:单股深度分析
**目标:** 对任意股票生成结构化分析报告。
- [ ] 实现个股分析器 `stock_analyzer.py`
- 技术面:趋势定位、均线状态、支撑/阻力位、技术形态识别
- 资金面:近期主力资金行为模式
- 基本面:PE/PB 历史分位、杜邦分析摘要
- 消息面:近30天关键公告、新闻情绪评分
- [ ] 实现 `stock-analyzer` Skill
### 阶段 4:大盘环境评估
**目标:** 每次选股前判断当前是否适合操作。
- [ ] 实现大盘分析 `market_overview.py`
- 主要指数趋势判断
- 市场宽度(上涨/下跌家数比)
- 成交量趋势
- 板块轮动热力图
- 仓位建议(轻仓/中等/重仓)
- [ ] 实现 `market-overview` Skill
### 阶段 5:舆情分析增强
- [ ] 新闻爬取与解析
- [ ] 关键词/情绪评分
- [ ] 机构研报监控
## 五、因子体系设计(初版)
### 多因子打分权重
| 维度 | 权重 | 子因子 |
|------|------|--------|
| 技术面 | 35% | 趋势强度、均线排列、量价配合、RSI位置 |
| 资金面 | 30% | 主力净流入趋势、北向资金、大单占比 |
| 基本面 | 25% | PE分位、ROE、利润增速、营收增速 |
| 消息面 | 10% | 新闻热度、机构评级方向 |
### 每个因子标准化为 0-100 分,加权求和得综合分。
## 六、风险与应对
| 风险 | 应对方案 |
|------|----------|
| AKShare 接口变动 | 封装统一数据层,多数据源 fallback |
| LLM 分析幻觉 | 所有数据由 Python 脚本计算,LLM 仅做解读和呈现 |
| 策略过拟合 | 回测引擎支持样本外检验(滚动窗口) |
| 市场风格切换 | 多因子框架允许动态调整权重 |
## 七、目录结构
```
stock/
├── .opencode/
│ ├── tools/ # Custom Tools (LLM 可调用的函数)
│ │ ├── stock-data.ts # 数据获取工具组
│ │ ├── stock-screen.ts # 选股筛选工具组
│ │ └── stock-backtest.ts # 回测工具组
│ └── skills/ # Agent Skills (工作流指令)
│ ├── stock-screener/ # 选股工作流
│ ├── stock-analyzer/ # 单股分析工作流
│ ├── market-overview/ # 大盘评估工作流
│ └── stock-backtest/ # 回测工作流
├── scripts/ # Python 实现
│ ├── market_data.py # 数据获取 (AKShare)
│ ├── stock_screener.py # 多因子选股引擎
│ ├── stock_analyzer.py # 个股深度分析
│ ├── backtest_engine.py # 回测引擎
│ └── sentiment.py # 舆情分析
├── docs/
│ └── PLAN.md # 本文件
├── requirements.txt
├── AGENTS.md # opencode 项目理解
└── README.md
```
## 八、小资金(5万)场景适配
### 约束条件
| 约束 | 影响 | 设计调整 |
|------|------|----------|
| 每股单价限制 | 股价 >500 元直接买不起1手 | 选股池自动过滤高价股,优先 10-50 元区间 |
| 集中持仓 | 5万只能分散到 2-4 只 | 选股输出 Top 3-5,附带仓位分配建议 |
| 手续费敏感 | 单次交易 ~60 元(0.12%) | 每次推荐附带交易成本估算,避免过度拆分 |
| 心理因素 | 5% = 2500 元,感受强烈 | 所有风控指标同时用百分比和绝对金额展示 |
| 收益预期 | 年化 20% = 10000 元 | 目标定位为学习验证,非财富增长 |
### 仓位分配参考
| 大盘环境 | 总仓位 | 单只最大 | 持有数量 |
|----------|--------|----------|----------|
| 强势(重仓) | 3.5-4万(70-80% | 1-1.5万/只 | 3-4只 |
| 中性(中等) | 1.5-2.5万(30-50% | 0.5-1万/只 | 2-3只 |
| 弱势(轻仓) | <1.5万(<30% | <0.5万/只 | 1-2只 |
### 价格可买性校验
每只推荐股票前校验:`股价 × 100 ≤ 计划仓位`
## 九、里程碑时间线
| 阶段 | 预计可交付 | 里程碑 |
|------|-----------|--------|
| 阶段 0 | ✅ 框架搭建 | 项目骨架可运行,上下文齐全 |
| 阶段 1 | 回测引擎 | 可验证任意策略历史表现 |
| 阶段 2 | 选股引擎 | 每天可生成 Top N 推荐 |
| 阶段 3 | 单股分析 | 可对任意股票出详细分析报告 |
| 阶段 4 | 大盘评估 | 判断市场可操作性 |
| 阶段 5 | 舆情分析 | 消息面因子补充 |
---
*最后更新:2026-07-01*
+138
View File
@@ -0,0 +1,138 @@
# 股票投资原则 — 引导项目走向正确方向的元原则
> 本文档是项目的"宪法"。所有设计决策、策略开发和 Agent 行为都必须对齐这些原则。
> 当直觉与原则冲突时,服从原则。
>
> 本文档是通用认知框架(`docs/FOUNDATIONS.md`)在股票投资领域的具体应用。
> 阅读本文之前,建议先理解 FOUNDATIONS.md 中的元层思维。
---
## 一、关于市场本身的认知
### 原则 1:市场是复杂适应系统,不是物理定律
股票价格由无数参与者的买卖行为决定,参与者在学习、适应、进化。这意味着:
- **任何策略的有效性都是暂时的。** 今天赚钱的策略明天可能失效,不是因为策略错了,而是因为太多人发现了它。
- 我们的目标不是"找到一个永远有效的策略",而是"建立一套能持续发现临时有效策略的方法论"。
- 策略失效时,不抱怨市场,而是回到方法论检查哪里出了问题。
### 原则 2:我们赚的每一分钱都来自别人的错误
超额收益 = 你的判断正确 × 市场定价错误。在 4000+ 只 A 股中,每天有百万级的活跃交易者在买卖。
- 如果你不能清晰说出"为什么市场错了而我对了",就不要交易。
- 推论:买股票前,必须有一句话解释你的信息优势或视角差异。说不出 = 不是机会 = 不买。
---
## 二、关于回测的科学伦理
### 原则 3:回测的黄金法则 — 样本外验证
单次回测 = 讲故事,不是科学。正确的做法是**时间序列交叉验证**:
> 用历史数据的前段(如 2019-2022)优化策略参数,用后段(如 2023-2025)检验。优化和验证永远不能看同一批数据。
- Agent 每次输出回测结果时,必须明确标注哪些时间段是样本内(训练),哪些是样本外(检验)。
- 如果有人(包括你自己)给你看一个回测曲线但没有区分样本内/样本外,那个曲线是垃圾。
### 原则 4:过拟合是最大的敌人
给你 1200 个交易日的历史数据,你可以拟合出任何一条你想要的曲线。
- 参数越多,过拟合风险指数级上升:
- 1 个参数(如单均线) → 几乎不过拟合
- 2-3 个参数(如均线交叉 + 成交量过滤) → 可控
- 5+ 个参数(多因子加权) → 99%在过拟合,必须严格样本外验证
- 推论:永远从最简策略开始。最简版本通过了,才考虑加复杂度。
### 原则 5:你其实没有那么多数据
5 年日线 ≈ 1200 个交易日。但如果一个策略只触发了 15 次交易,你的实际样本量是 15,不是 1200。
- 用 15 个样本得出"胜率 60%"——统计学上毫无意义。
- Agent 输出回测结果时,必须报告**实际交易次数**,交易次数 < 30 的结果标注"样本不足,结论仅供参考"。
---
## 三、关于策略设计
### 原则 6:简单优于复杂(奥卡姆剃刀)
均线金叉策略(1 个规则)和深度学习模型(1000 万参数)相比,前者在实盘中更不容易翻车。
| 策略复杂度 | 过拟合风险 | 实盘翻车概率 | 适合阶段 |
|-----------|-----------|-------------|----------|
| 单规则(均线、突破) | 极低 | 低 | 入门 |
| 2-3 因子组合 | 低 | 中低 | 进阶 |
| 5+ 因子打分 | 高 | 高 | 需严格样本外验证 |
| 机器学习 | 极高 | 极高 | 不适合个人投资者 |
### 原则 7:仓位管理 > 选股 > 择时
学术研究表明,资产配置(投多少钱)解释了约 90% 的收益方差。但散户 90% 的精力花在"明天买哪只"上。
- 5 万本金时,满仓一只还是分三只,这个决策的影响远大于选的是茅台还是五粮液。
- Agent 每次推荐策略或选股时,必须在选股结论之前先给出仓位建议。
- 选股评分不能替代仓位决策。
---
## 四、关于心理与行为
### 原则 8:策略必须适合你自己,而不是理论上最优
5 万本金时:
- 策略要求持有 10 只股票 → 你做不到 → 别选这个策略
- 策略最大回撤 30%(¥15,000)→ 你心理承受上限 10%(¥5,000)→ 你会提前止损,破坏策略
- Agent 展示每个策略时,必须附加一个"用户适配度"维度的评估。
- 每个策略的评估必须包含:单笔最大亏损(RMB)和心理冲击等级。
### 原则 9:区分"运气"和"能力"
| 场景 | 是运气还是能力? |
|------|-----------------|
| 第一次交易赚了 10% | 大概率运气 |
| 前 3 个月都在盈利 | 大概率运气 + 牛市 |
| 持续 2 年跑赢指数 | 可能有能力 |
| 单次交易亏了 20% | 正常,不是能力差 |
| 连续 10 次交易亏损后不失控 | 这才是真正的能力 |
- 不要用前 3 个月的结果评价自己或任何策略。
- 给自己至少 1 年学习期。前 6 个月的目标不是赚钱,是学会不犯致命错误。
---
## 五、关于这个项目的定位
### 原则 10:项目是实验室,不是印钞机
这个系统的核心价值是**加速你的学习循环**:提问 → 假设 → 回测 → 修正 → 再提问。
它不应该成为"每天打开看推荐然后买入"的工具——那会让你跳过思考,变成被动使用者。
- 每当你准备基于项目的输出做一笔交易,你必须能口头解释:
1. 为什么这笔交易会赚钱?
2. 我用什么数据验证过这个判断?
3. 如果亏了,止损在哪?
- 三个答案任何一个说不出来,不交易。
---
## 附录 AAgent 行为约束
以下需要更新到 AGENTS.md 作为 Agent 的强制行为标准(见 AGENTS.md 的 Agent Behavioral Constraints 章节)。
## 附录 B:用户自查清单
每次看项目输出时,问自己三个问题:
1. 我看懂这个推荐背后的逻辑了吗?——看不懂,暂停,不买。
2. 我愿意持有这个判断到止损触发吗?——不愿意,不买。
3. 这笔交易如果全亏了,对我的生活有影响吗?——有影响,不买。
---
*最后更新:2026-07-01*
+3
View File
@@ -0,0 +1,3 @@
akshare>=1.14.0
pandas>=2.0.0
numpy>=1.24.0
+89
View File
@@ -0,0 +1,89 @@
"""
Strategy backtesting engine for A-share stocks.
Supports:
- Predefined strategies (MA crossover, momentum, mean reversion, etc.)
- Custom entry/exit rules
- Multi-strategy comparison
- Performance metrics (returns, drawdown, Sharpe, win rate)
Usage: python3 backtest_engine.py <function> <json_args>
"""
import sys
import json
def run(strategy_name=None, entry_rule=None, exit_rule=None,
universe="hs300", symbols=None, start_date="20210101", end_date="20251231"):
"""Run a single backtest. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Backtest (strategy={strategy_name or 'custom'}, universe={universe}) — not yet implemented",
"metrics": {
"cumulative_return": None,
"annualized_return": None,
"win_rate": None,
"max_drawdown": None,
"sharpe_ratio": None,
"benchmark_return": None,
},
}, ensure_ascii=False)
def predefined():
"""List available predefined strategies."""
strategies = [
{
"name": "ma_cross",
"description": "MA Golden Cross: buy when 20-day MA crosses above 60-day MA",
"params": {"fast": 20, "slow": 60},
},
{
"name": "momentum_breakout",
"description": "Momentum Breakout: buy when price breaks 20-day high with volume > 1.5x avg",
"params": {"lookback": 20, "volume_multiplier": 1.5},
},
{
"name": "mean_reversion",
"description": "Mean Reversion: buy when price deviates >2 std below 20-day MA, sell at MA",
"params": {"ma_period": 20, "std_dev": 2},
},
{
"name": "turtle",
"description": "Turtle Trading: breakout of 20-day high, exit at 10-day low",
"params": {"entry_period": 20, "exit_period": 10},
},
]
return json.dumps({"strategies": strategies}, ensure_ascii=False)
def compare(strategies, universe="hs300", start_date="20210101", end_date="20251231"):
"""Compare multiple strategies. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Strategy comparison ({strategies}) — not yet implemented",
"comparison": [],
}, ensure_ascii=False)
FUNCTIONS = {
"run": run,
"predefined": predefined,
"compare": compare,
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: backtest_engine.py <function> [json_args]")
sys.exit(1)
func_name = sys.argv[1]
args = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
if func_name not in FUNCTIONS:
print(f"Unknown function: {func_name}")
sys.exit(1)
result = FUNCTIONS[func_name](**args)
print(result)
+81
View File
@@ -0,0 +1,81 @@
"""
A-share market data fetching module.
Uses AKShare as the primary data source.
Usage: python3 market_data.py <function> <json_args>
"""
import sys
import json
from datetime import datetime, timedelta
def get_quote(symbol, period="daily", start_date=None, end_date=None):
"""Get K-line data for a stock. Stub - to be implemented with AKShare."""
# TODO: Implement with akshare.stock_zh_a_hist()
return json.dumps({
"status": "stub",
"message": f"Quote for {symbol} ({period}) — not yet implemented",
"symbol": symbol,
"period": period,
}, ensure_ascii=False)
def get_financial(symbol):
"""Get financial indicators. Stub - to be implemented with AKShare."""
# TODO: Implement with akshare.stock_financial_analysis_indicator()
return json.dumps({
"status": "stub",
"message": f"Financial data for {symbol} — not yet implemented",
}, ensure_ascii=False)
def get_moneyflow(symbol, days=10):
"""Get capital flow data. Stub - to be implemented with AKShare."""
# TODO: Implement with akshare.stock_individual_fund_flow()
return json.dumps({
"status": "stub",
"message": f"Money flow for {symbol} ({days}d) — not yet implemented",
}, ensure_ascii=False)
def get_index(index_code="all", days=30):
"""Get index data. Stub - to be implemented with AKShare."""
# TODO: Implement with akshare.stock_zh_index_daily()
return json.dumps({
"status": "stub",
"message": f"Index data ({index_code}, {days}d) — not yet implemented",
}, ensure_ascii=False)
def get_sector(date=None):
"""Get sector performance. Stub - to be implemented with AKShare."""
# TODO: Implement with akshare.stock_board_industry_name_em()
return json.dumps({
"status": "stub",
"message": "Sector data — not yet implemented",
}, ensure_ascii=False)
FUNCTIONS = {
"quote": get_quote,
"financial": get_financial,
"moneyflow": get_moneyflow,
"index": get_index,
"sector": get_sector,
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: market_data.py <function> [json_args]")
sys.exit(1)
func_name = sys.argv[1]
args = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
if func_name not in FUNCTIONS:
print(f"Unknown function: {func_name}")
sys.exit(1)
result = FUNCTIONS[func_name](**args)
print(result)
+47
View File
@@ -0,0 +1,47 @@
"""
News and sentiment analysis for A-share stocks.
Usage: python3 sentiment.py <function> <json_args>
"""
import sys
import json
def news(symbol, limit=20):
"""Get recent news for a stock. Stub - to be implemented with AKShare."""
return json.dumps({
"status": "stub",
"message": f"News for {symbol} — not yet implemented",
"items": [],
}, ensure_ascii=False)
def market_sentiment():
"""Get overall market sentiment score. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": "Market sentiment — not yet implemented",
"score": None,
}, ensure_ascii=False)
FUNCTIONS = {
"news": news,
"market_sentiment": market_sentiment,
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: sentiment.py <function> [json_args]")
sys.exit(1)
func_name = sys.argv[1]
args = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
if func_name not in FUNCTIONS:
print(f"Unknown function: {func_name}")
sys.exit(1)
result = FUNCTIONS[func_name](**args)
print(result)
+54
View File
@@ -0,0 +1,54 @@
"""
Single stock deep analysis module.
Analyzes a stock across technical, fundamental, capital flow, and sentiment dimensions.
Usage: python3 stock_analyzer.py <function> <json_args>
"""
import sys
import json
def analyze(symbol):
"""Full analysis report. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Analysis for {symbol} — not yet implemented",
"symbol": symbol,
"overall_score": None,
"dimensions": {
"technical": {"score": None, "details": None},
"capital_flow": {"score": None, "details": None},
"fundamental": {"score": None, "details": None},
"sentiment": {"score": None, "details": None},
},
}, ensure_ascii=False)
def technical(symbol):
"""Technical analysis only. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Technical analysis for {symbol} — not yet implemented",
}, ensure_ascii=False)
FUNCTIONS = {
"analyze": analyze,
"technical": technical,
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: stock_analyzer.py <function> [json_args]")
sys.exit(1)
func_name = sys.argv[1]
args = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
if func_name not in FUNCTIONS:
print(f"Unknown function: {func_name}")
sys.exit(1)
result = FUNCTIONS[func_name](**args)
print(result)
+68
View File
@@ -0,0 +1,68 @@
"""
Multi-factor A-share stock screening engine.
Usage: python3 stock_screener.py <function> <json_args>
"""
import sys
import json
def multi_factor(strategy="comprehensive", sector=None, market_cap="all", top_n=10):
"""Multi-factor scoring screen. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Multi-factor screen (strategy={strategy}, sector={sector}) — not yet implemented",
"strategy": strategy,
"results": [],
}, ensure_ascii=False)
def strong(sector=None, top_n=20):
"""Strong trend screen. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": "Strong trend screen — not yet implemented",
"results": [],
}, ensure_ascii=False)
def breakout(lookback_days=60, top_n=20):
"""Volume breakout screen. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": f"Breakout screen ({lookback_days}d) — not yet implemented",
"results": [],
}, ensure_ascii=False)
def oversold(top_n=20):
"""Oversold rebound screen. Stub - to be implemented."""
return json.dumps({
"status": "stub",
"message": "Oversold screen — not yet implemented",
"results": [],
}, ensure_ascii=False)
FUNCTIONS = {
"multi_factor": multi_factor,
"strong": strong,
"breakout": breakout,
"oversold": oversold,
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: stock_screener.py <function> [json_args]")
sys.exit(1)
func_name = sys.argv[1]
args = json.loads(sys.argv[2]) if len(sys.argv) > 2 else {}
if func_name not in FUNCTIONS:
print(f"Unknown function: {func_name}")
sys.exit(1)
result = FUNCTIONS[func_name](**args)
print(result)