← 返回 Skills 市场
chen6896qqwee

双策略A股选股器

作者 chen6896qqwee · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
55
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install dual-strategy-selector
功能描述
基于仙人指路B和老鸭头B两策略,筛选符合多条件的A股股票,支持指定日期选股及信号检测。
使用说明 (SKILL.md)

-- coding: utf-8 --

""" 双策略选股器 - 通用版 策略1: 仙人指路B + 持股20天 策略2: 老鸭头B + 持股5天

使用方法: python dual_strategy_selector.py --data your_data.csv python dual_strategy_selector.py --data your_data.csv --date 2026-04-30 python dual_strategy_selector.py --data your_data.csv --watch

数据接口要求: CSV文件必须包含以下列:

  • symbol: 股票代码
  • name: 股票名称
  • date: 日期 (YYYY-MM-DD)
  • open: 开盘价
  • high: 最高价
  • low: 最低价
  • close: 收盘价
  • volume: 成交量
  • turnover: 换手率 (%)
  • ma5: 5日均线
  • ma10: 10日均线
  • ma20: 20日均线
  • ma60: 60日均线
  • volume_ratio: 量比
  • pct_change: 涨跌幅 (%)
  • is_up_limit: 是否涨停 (0/1) """

import pandas as pd import numpy as np from datetime import datetime import argparse import os

============================================================

策略配置

============================================================

STRATEGY_CONFIG = { '仙人指路B': { 'name': '仙人指路B', 'version': '1.0', 'hold_days': 20, 'expected_win_rate': 54.2, 'expected_avg_profit': 3.53, 'params': { 'upper_shadow_pct': 2.0, # 上影线>2% 'body_pct_max': 2.0, # 实体\x3C2% 'turnover_min': 3.0, # 换手>3% 'turnover_max': 7.0, # 换手\x3C7% 'volume_ratio_min': 1.0, # 量比>1 } }, '老鸭头B': { 'name': '老鸭头B', 'version': '1.0', 'hold_days': 5, 'expected_win_rate': 72.0, 'expected_avg_profit': 0.77, 'params': { 'near_pct': 0.02, # 回调至20日线±2% 'require_10x60': True, # 10日上穿60日 'require_ma10_up': True, # MA10向上 'require_price_above_20': False, } } }

============================================================

数据加载函数

============================================================

def load_data(data_path, target_date=None): """ 加载用户数据

参数:
    data_path: CSV文件路径
    target_date: 目标日期 (可选)

返回:
    DataFrame
"""
print(f"[OK] 加载数据: {data_path}")

if not os.path.exists(data_path):
    print(f"[ERROR] 文件不存在: {data_path}")
    return None

df = pd.read_csv(data_path)

# 检查必要列
required_cols = ['symbol', 'name', 'date', 'open', 'high', 'low', 'close', 
                 'volume', 'turnover', 'ma5', 'ma10', 'ma20', 'ma60', 
                 'volume_ratio', 'pct_change', 'is_up_limit']

missing_cols = [col for col in required_cols if col not in df.columns]
if missing_cols:
    print(f"[ERROR] 缺少必要列: {missing_cols}")
    print("[INFO] 请确保CSV包含以下列:")
    for col in required_cols:
        print(f"  - {col}")
    return None

# 转换日期
df['date'] = pd.to_datetime(df['date'])

print(f"[OK] 数据: {len(df)}行, {df['symbol'].nunique()}只股票")
print(f"[OK] 日期范围: {df['date'].min()} ~ {df['date'].max()}")

return df

============================================================

信号检测函数

============================================================

def detect_signals(df): """检测双策略信号""" df = df.sort_values(['symbol', 'date'])

# 预计算shift
df['ma5_prev'] = df.groupby('symbol')['ma5'].shift(1)
df['ma10_prev'] = df.groupby('symbol')['ma10'].shift(1)
df['ma20_prev'] = df.groupby('symbol')['ma20'].shift(1)
df['ma60_prev'] = df.groupby('symbol')['ma60'].shift(1)
df['close_prev'] = df.groupby('symbol')['close'].shift(1)

# === 仙人指路B ===
df['body'] = abs(df['close'] - df['open'])
df['body_pct'] = df['body'] / df['close_prev'] * 100
df['upper_shadow'] = df['high'] - df[['open', 'close']].max(axis=1)
df['upper_shadow_pct'] = df['upper_shadow'] / df['close_prev'] * 100

params_xr = STRATEGY_CONFIG['仙人指路B']['params']
df['signal_xrB'] = (
    (df['upper_shadow_pct'] > params_xr['upper_shadow_pct']) &
    (df['body_pct'] \x3C params_xr['body_pct_max']) &
    (df['turnover'] >= params_xr['turnover_min']) &
    (df['turnover'] \x3C= params_xr['turnover_max']) &
    (df['volume_ratio'] > params_xr['volume_ratio_min'])
).astype(int)

# === 老鸭头B ===
df['s_5x10'] = ((df['ma5_prev'] \x3C df['ma10_prev']) & (df['ma5'] >= df['ma10'])).astype(int)
df['ma20_slope'] = df.groupby('symbol')['ma20'].transform(lambda x: x.diff().rolling(5).mean())
df['s_20_up'] = (df['ma20_slope'] > 0).astype(int)
df['price_near_20'] = (abs(df['close'] - df['ma20']) / df['ma20'] \x3C STRATEGY_CONFIG['老鸭头B']['params']['near_pct']).astype(int)
df['signal_lyB_base'] = (df['s_5x10'] & df['s_20_up'] & df['price_near_20']).astype(int)

# 加成条件
df['s_10x60'] = ((df['ma10_prev'] \x3C df['ma60_prev']) & (df['ma10'] >= df['ma60'])).astype(int)
df['s_ma10_up'] = (df['ma10'] > df['ma10_prev']).astype(int)
df['s_price_above_20'] = (df['close'] > df['ma20']).astype(int)

# 老鸭头B完整信号
ly_params = STRATEGY_CONFIG['老鸭头B']['params']
conditions = [df['signal_lyB_base'] == 1]
if ly_params['require_10x60']:
    conditions.append(df['s_10x60'] == 1)
if ly_params['require_ma10_up']:
    conditions.append(df['s_ma10_up'] == 1)
if ly_params['require_price_above_20']:
    conditions.append(df['s_price_above_20'] == 1)

df['signal_lyB'] = np.where(pd.concat(conditions, axis=1).all(axis=1), 1, 0)

# 清理临时列
drop_cols = ['ma5_prev', 'ma10_prev', 'ma20_prev', 'ma60_prev', 'close_prev',
             'body', 'body_pct', 'upper_shadow', 'upper_shadow_pct',
             's_5x10', 'ma20_slope', 's_20_up', 'price_near_20']
df = df.drop(columns=drop_cols)

return df

============================================================

选股函数

============================================================

def select_stocks(df, target_date=None, top_n=20): """选股主函数"""

if target_date:
    target_dt = pd.to_datetime(target_date)
else:
    target_dt = df['date'].max()

print(f"[OK] 目标日期: {target_dt.strftime('%Y-%m-%d')}")

# 检测信号
df = detect_signals(df)

# 只取目标日期
today_df = df[df['date'] == target_dt].copy()

if len(today_df) == 0:
    print(f"[WARN] 目标日期无数据")
    return None

# === 策略1: 仙人指路B ===
xr_signals = today_df[today_df['signal_xrB'] == 1].copy()

# === 策略2: 老鸭头B ===
ly_signals = today_df[today_df['signal_lyB'] == 1].copy()

# 输出结果
print("\

" + "="*80) print(f"双策略选股结果 - {target_dt.strftime('%Y-%m-%d')}") print("="*80)

# 策略1输出
print(f"\

【策略1: 仙人指路B】") print(f"预期胜率: {STRATEGY_CONFIG['仙人指路B']['expected_win_rate']}%") print(f"预期均益: +{STRATEGY_CONFIG['仙人指路B']['expected_avg_profit']}%") print(f"持股周期: {STRATEGY_CONFIG['仙人指路B']['hold_days']}天") print(f"信号股票: {len(xr_signals)}只")

if len(xr_signals) > 0:
    xr_signals = xr_signals.sort_values('volume_ratio', ascending=False)
    top_xr = xr_signals.head(top_n)
    
    print(f"\

--- TOP {len(top_xr)} ---") for i, (_, row) in enumerate(top_xr.iterrows(), 1): print(f"
{i:2d}. {row['symbol']} {row['name']}") print(f" 价格: {row['close']:.2f} | 涨幅: {row['pct_change']:+.2f}%") print(f" 换手: {row['turnover']:.2f}% | 量比: {row['volume_ratio']:.2f}") print(f" 上影线: {(row['high'] - max(row['open'], row['close'])) / row['close'] * 100:.2f}%") print(f" 实体: {abs(row['close'] - row['open']) / row['open'] * 100:.2f}%")

# 策略2输出
print(f"\

【策略2: 老鸭头B】") print(f"预期胜率: {STRATEGY_CONFIG['老鸭头B']['expected_win_rate']}%") print(f"预期均益: +{STRATEGY_CONFIG['老鸭头B']['expected_avg_profit']}%") print(f"持股周期: {STRATEGY_CONFIG['老鸭头B']['hold_days']}天") print(f"信号股票: {len(ly_signals)}只")

if len(ly_signals) > 0:
    ly_signals['score'] = (
        ly_signals['s_10x60'] * 30 +
        ly_signals['s_ma10_up'] * 20 +
        ly_signals['turnover'] * 5
    )
    ly_signals = ly_signals.sort_values('score', ascending=False)
    top_ly = ly_signals.head(top_n)
    
    print(f"\

--- TOP {len(top_ly)} ---") for i, (_, row) in enumerate(top_ly.iterrows(), 1): print(f"
{i:2d}. {row['symbol']} {row['name']}") print(f" 价格: {row['close']:.2f} | 涨幅: {row['pct_change']:+.2f}%") print(f" 换手: {row['turnover']:.2f}% | 量比: {row['volume_ratio']:.2f}") print(f" MA5: {row['ma5']:.2f} | MA10: {row['ma10']:.2f} | MA20: {row['ma20']:.2f} | MA60: {row['ma60']:.2f}") print(f" 信号: 10日上穿60日{'Y' if row['s_10x60'] else 'N'} | MA10向上{'Y' if row['s_ma10_up'] else 'N'}") print(f" 评分: {row['score']:.0f}")

# 保存结果
if len(xr_signals) > 0 or len(ly_signals) > 0:
    output_file = f"selection_{target_dt.strftime('%Y%m%d')}.csv"
    
    # 合并保存
    xr_save = xr_signals[['symbol', 'name', 'date', 'close', 'pct_change', 'turnover', 'volume_ratio']].copy()
    xr_save['strategy'] = '仙人指路B'
    
    ly_save = ly_signals[['symbol', 'name', 'date', 'close', 'pct_change', 'turnover', 'volume_ratio']].copy()
    ly_save['strategy'] = '老鸭头B'
    
    combined = pd.concat([xr_save, ly_save], ignore_index=True)
    combined.to_csv(output_file, index=False)
    print(f"\

[OK] 结果保存: {output_file}")

return xr_signals, ly_signals

============================================================

主函数

============================================================

def main(): parser = argparse.ArgumentParser(description='双策略选股器 - 通用版') parser.add_argument('--data', type=str, required=True, help='数据文件路径 (CSV)') parser.add_argument('--date', type=str, help='指定日期 (YYYY-MM-DD)') parser.add_argument('--top', type=int, default=20, help='显示前N只 (默认20)')

args = parser.parse_args()

# 加载数据
df = load_data(args.data, args.date)
if df is None:
    return

# 选股
select_stocks(df, args.date, args.top)

if name == 'main': main()

安全使用建议
Before installing, use a trusted Python environment, install pandas/numpy carefully, and run the script only on CSV files you choose. Treat the stock-screening output and backtest claims as informational, not guaranteed investment advice.
功能分析
Type: OpenClaw Skill Name: dual-strategy-selector Version: 1.0.0 The skill bundle is a technical analysis tool for stock selection based on two specific trading strategies. The Python code in dual_strategy_selector.py and SKILL.md uses standard data processing libraries (pandas, numpy) to filter local CSV data and save results to a new file; it contains no network requests, obfuscation, or attempts to access sensitive system information.
能力评估
Purpose & Capability
The README, package metadata, and visible code consistently describe an A-share stock selector based on two technical-analysis strategies; no trading, account mutation, or unrelated capability is evident.
Instruction Scope
Usage is user-directed through local commands such as running the Python script with a CSV file and optional date; no prompt override, forced autonomous execution, or hidden instruction behavior is evident.
Install Mechanism
There is no install spec, while the code imports pandas and numpy and package.json declares broad dependency ranges, so users should install dependencies from trusted Python package sources.
Credentials
The script reads a user-selected local CSV and writes a dated selection CSV in the working directory; this is proportionate to the purpose but can create or overwrite local output files.
Persistence & Privilege
No credentials, elevated privileges, background service, persistent memory, or continuing autonomous behavior is evident in the provided artifacts; persistence is limited to the generated results file.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install dual-strategy-selector
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /dual-strategy-selector 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
仙人指路+老鸭头形态选股策略
元数据
Slug dual-strategy-selector
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

双策略A股选股器 是什么?

基于仙人指路B和老鸭头B两策略,筛选符合多条件的A股股票,支持指定日期选股及信号检测。 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 55 次。

如何安装 双策略A股选股器?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install dual-strategy-selector」即可一键安装,无需额外配置。

双策略A股选股器 是免费的吗?

是的,双策略A股选股器 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

双策略A股选股器 支持哪些平台?

双策略A股选股器 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 双策略A股选股器?

由 chen6896qqwee(@chen6896qqwee)开发并维护,当前版本 v1.0.0。

💬 留言讨论