Initial commit: A-share stock analysis project with screening, backtesting, and multi-factor analysis tools
This commit is contained in:
@@ -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