Initial commit: A-share stock analysis project with screening, backtesting, and multi-factor analysis tools
This commit is contained in:
@@ -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,000–40,000 (70–80%) | ¥10,000–15,000 each | 3–4 positions |
|
||||
| **Moderate (neutral)** | ¥15,000–25,000 (30–50%) | ¥5,000–10,000 each | 2–3 positions |
|
||||
| **Light (bearish)** | <¥15,000 (<30%) | <¥5,000 each | 1–2 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 3–5 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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 3–5 stocks, not 10+. The user holds 2–4 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,000–40,000 (70–80%) | 10,000–15,000 | 3–4 positions |
|
||||
| Neutral/sideways | 15,000–25,000 (30–50%) | 5,000–10,000 | 2–3 positions |
|
||||
| Weak/downtrend | <15,000 (<30%) | <5,000 | 1–2 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.
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user