Alpha Mine logo

Alpha Mine

Community
VernonOY
alpha-mine

Automated factor mining. Systematically generate, screen, and evaluate candidate factors. 自动因子挖掘。系统性生成、筛选和评估候选因子。 Triggers: "mine factors", "auto discover", "挖掘因子", "自动挖掘", "alpha-mine"

Overview

PublisherVernonOY
Repositoryalpha-skills
Skill namealpha-mine
Stars
122
Forks
23
Bundled files
Instructions only
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by VernonOY on GitHub. Read the source before you install it.

Installation

Install the Alpha Mine AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/VernonOY/alpha-skills/tree/main/skills/alpha-mine
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/VernonOY/alpha-skills.git /tmp/alpha-skills
mkdir -p .claude/skills
cp -r /tmp/alpha-skills/skills/alpha-mine .claude/skills/alpha-mine
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Alpha Mine in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Alpha Mine on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Alpha Mine is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

alpha-mine — Automated Factor Mining / 自动因子挖掘

You are an automated factor mining engine. Systematically search the factor expression space, generate candidates, screen them via IC, and present the best ones to the user.

你是一个自动因子挖掘引擎。系统性搜索因子表达式空间,生成候选因子,通过IC快筛,将最佳因子呈现给用户。

Bilingual Terms / 双语术语

English中文
Factor Mining因子挖掘
Expression Space表达式空间
Candidate候选因子
Operator算子
Operand操作数
Quick Screen快速筛选
IC (Information Coefficient)信息系数
ICIRIC信息比率
Genetic Programming遗传编程

Project Context / 项目定位

This skill generates factor expressions by combining operators (rolling mean, correlation, rank, etc.) with data fields (close, volume, high, low, etc.), evaluates them via IC, and presents winners.

本技能通过组合算子(滚动均值、相关性、排名等)和数据字段(收盘价、成交量、最高价、最低价等),生成因子表达式,通过IC评估,呈现优胜者。

Data Source / 数据来源: Same as alpha-evaluate — supports Tushare (A-share), YFinance (US/HK), or custom module.

Language Rule / 语言规则:

  • If the user speaks English, output in English
  • If the user speaks Chinese, output in Chinese

Input Recognition / 输入识别

User Says / 用户说Action / 行为
"mine factors" / "挖掘因子" / "自动挖掘"Full mining pipeline (generate → screen → evaluate top)
"mine momentum factors" / "挖掘动量类因子"Constrained mining (specific category)
"mine 50 candidates" / "挖掘50个候选"Control candidate count
"mine factors for US stocks" / "挖掘美股因子"Market-specific mining

Mining Pipeline / 挖掘管线

Step 1: Configure Mining Parameters / 配置挖掘参数

python
# Default parameters (user can override)
N_CANDIDATES = 50        # Number of candidates to generate
N_TOP = 10               # Number of top candidates to fully evaluate
HOLDING_PERIODS = [5, 10, 20]
IC_THRESHOLD = 0.02      # Minimum |IC| to pass quick screen
CATEGORY = "all"         # "all", "momentum", "mean_reversion", "volatility", "volume", "composite"

If the user specifies constraints (e.g., "only momentum factors"), adjust CATEGORY accordingly.

Step 2: Define the Expression Building Blocks / 定义表达式构建模块

Data Fields / 数据字段 (operands):

python
FIELDS = {
    "close": "close",           # 收盘价
    "open": "open_price",       # 开盘价 (if available)
    "high": "high",             # 最高价
    "low": "low",               # 最低价
    "volume": "volume",         # 成交量
    "returns": "close.pct_change(1)",  # 日收益率
}

Time-Series Operators / 时序算子:

python
TS_OPS = {
    "ts_mean":    lambda x, d: f"{x}.rolling({d}).mean()",
    "ts_std":     lambda x, d: f"{x}.rolling({d}).std()",
    "ts_max":     lambda x, d: f"{x}.rolling({d}).max()",
    "ts_min":     lambda x, d: f"{x}.rolling({d}).min()",
    "ts_rank":    lambda x, d: f"{x}.rolling({d}).apply(lambda s: s.rank(pct=True).iloc[-1])",
    "ts_delta":   lambda x, d: f"{x}.diff({d})",
    "ts_return":  lambda x, d: f"{x}.pct_change({d})",
    "ts_corr":    lambda x, y, d: f"{x}.rolling({d}).corr({y})",
    "ts_sum":     lambda x, d: f"{x}.rolling({d}).sum()",
    "ts_decay":   lambda x, d: f"({x} * pd.Series(range(1,{d}+1))).rolling({d}).sum() / pd.Series(range(1,{d}+1)).sum()",
}

Cross-Sectional Operators / 截面算子:

python
CS_OPS = {
    "cs_rank":    lambda x: f"{x}.rank(axis=1, pct=True)",
    "cs_zscore":  lambda x: f"({x}.sub({x}.mean(axis=1), axis=0)).div({x}.std(axis=1), axis=0)",
}

Arithmetic / 算术:

python
ARITH = {
    "neg":   lambda x: f"-({x})",
    "abs":   lambda x: f"({x}).abs()",
    "log":   lambda x: f"np.log(({x}).clip(lower=1e-10))",
    "square": lambda x: f"({x})**2",
    "sign":  lambda x: f"np.sign({x})",
}

Window Sizes / 窗口参数:

python
WINDOWS = [5, 10, 20, 40, 60]

Step 3: Generate Candidate Expressions / 生成候选表达式

Use a structured generation approach (NOT random — each expression has economic intuition):

使用结构化生成方式(非随机——每个表达式都有经济直觉):

Category Templates / 分类模板:

python
TEMPLATES = {
    "momentum": [
        # 不同周期的动量
        ("ts_return(close, {w})", "Momentum {w}d"),
        # 跳跃动量(避免短期反转噪音)
        ("ts_return(close.shift(5), {w})", "Skip-5 momentum {w}d"),
        # 相对强弱
        ("ts_return(close, {w1}) - ts_return(close, {w2})", "Relative momentum {w1}d vs {w2}d"),
        # 成交量加权动量
        ("(ts_return(close, {w}) * volume).rolling({w}).sum() / volume.rolling({w}).sum()", "Volume-weighted momentum {w}d"),
    ],
    "mean_reversion": [
        # 反转
        ("-ts_return(close, {w})", "Reversal {w}d"),
        # 距均线偏离
        ("-(close / close.rolling({w}).mean() - 1)", "Mean reversion to MA{w}"),
        # RSI变体
        ("-(close.diff().clip(lower=0).rolling({w}).mean() / (-close.diff().clip(upper=0)).rolling({w}).mean())", "RSI-like {w}d"),
        # 布林带位置
        ("-((close - close.rolling({w}).mean()) / close.rolling({w}).std())", "Bollinger z-score {w}d"),
    ],
    "volatility": [
        # 已实现波动率
        ("-(close.pct_change().rolling({w}).std() * np.sqrt(252))", "Low volatility {w}d"),
        # 高低价比率
        ("-((high / low - 1).rolling({w}).mean())", "Low HL ratio {w}d"),
        # 波动率变化
        ("-(close.pct_change().rolling({w1}).std() / close.pct_change().rolling({w2}).std())", "Vol change {w1}d/{w2}d"),
        # 下行波动率
        ("-(close.pct_change().clip(upper=0).rolling({w}).std())", "Low downside vol {w}d"),
    ],
    "volume": [
        # 量价背离
        ("-(close.pct_change().rolling({w}).corr(volume.pct_change()))", "PV divergence {w}d"),
        # 换手率
        ("-(volume.rolling({w}).mean())", "Low turnover {w}d (proxy)"),
        # 异常成交量
        ("-(volume.rolling({w1}).mean() / volume.rolling({w2}).mean() - 1)", "Abnormal volume {w1}d/{w2}d"),
        # 成交量趋势
        ("volume.rolling({w1}).mean() / volume.rolling({w2}).mean()", "Volume trend {w1}d/{w2}d"),
    ],
    "composite": [
        # 动量 + 低波动
        ("cs_rank(ts_return(close, {w})) + cs_rank(-(close.pct_change().rolling({w}).std()))", "Momentum+LowVol {w}d"),
        # 反转 + 量价背离
        ("cs_rank(-ts_return(close, {w1})) + cs_rank(-(close.pct_change().rolling({w2}).corr(volume.pct_change())))", "Reversal+PVDiv {w1}d/{w2}d"),
        # 多维动量
        ("cs_rank(ts_return(close, {w1})) * 0.5 + cs_rank(ts_return(close, {w2})) * 0.3 + cs_rank(-(close.pct_change().rolling(20).std())) * 0.2", "MultiMom {w1}d+{w2}d+LowVol"),
    ],
}

Generation Logic / 生成逻辑:

python
import itertools
import random

def generate_candidates(category="all", n_candidates=50):
    """Generate candidate factor expressions"""
    candidates = []
    
    cats = TEMPLATES.keys() if category == "all" else [category]
    
    for cat in cats:
        for template_expr, template_name in TEMPLATES[cat]:
            # Instantiate with different window combinations
            if "{w1}" in template_expr and "{w2}" in template_expr:
                for w1, w2 in itertools.combinations(WINDOWS, 2):
                    expr = template_expr.format(w1=w1, w2=w2)
                    name = template_name.format(w1=w1, w2=w2)
                    candidates.append({"expr": expr, "name": name, "category": cat})
            elif "{w}" in template_expr:
                for w in WINDOWS:
                    expr = template_expr.format(w=w)
                    name = template_name.format(w=w)
                    candidates.append({"expr": expr, "name": name, "category": cat})
    
    # Shuffle and limit
    random.shuffle(candidates)
    return candidates[:n_candidates]

Step 4: Quick Screen (IC Filter) / 快速筛选(IC过滤)

For each candidate:

  1. Compute factor values using the expression
  2. Calculate IC against forward returns
  3. Keep only candidates with |IC mean| > threshold

对每个候选因子:

  1. 用表达式计算因子值
  2. 计算IC
  3. 只保留 |IC均值| > 阈值的候选
python
from scipy import stats

def quick_screen(expr, close, volume, high, low, forward_returns, ic_threshold=0.02):
    """
    Quick IC screen for a candidate expression.
    Returns (ic_mean, ic_std, passed) or None if computation fails.
    """
    try:
        # Evaluate the expression
        factor_values = eval(expr)
        
        # Cross-sectional standardize
        factor_values = (factor_values.sub(factor_values.mean(axis=1), axis=0)
                        .div(factor_values.std(axis=1), axis=0))
        
        # Calculate IC on sampled dates (every 5th date for speed)
        common_dates = factor_values.index.intersection(forward_returns.index)[::5]
        common_stocks = factor_values.columns.intersection(forward_returns.columns)
        
        ic_values = []
        for date in common_dates:
            f = factor_values.loc[date, common_stocks].dropna()
            r = forward_returns.loc[date, common_stocks].dropna()
            common = f.index.intersection(r.index)
            if len(common) < 30:
                continue
            fv, rv = f[common].values, r[common].values
            valid = np.isfinite(fv) & np.isfinite(rv)
            if valid.sum() < 30:
                continue
            corr, _ = stats.spearmanr(fv[valid], rv[valid])
            if np.isfinite(corr):
                ic_values.append(corr)
        
        if len(ic_values) < 10:
            return None
        
        ic_mean = np.mean(ic_values)
        ic_std = np.std(ic_values)
        icir = ic_mean / ic_std if ic_std > 0 else 0
        passed = abs(ic_mean) > ic_threshold
        
        return {"ic_mean": ic_mean, "ic_std": ic_std, "icir": icir, "passed": passed}
    except Exception:
        return None

Step 5: Full Evaluation of Top Candidates / 对Top候选完整评估

For candidates that pass quick screen, run full evaluation (same as alpha-evaluate):

  • Full IC series (all dates, not sampled)
  • Quintile stratification
  • Long-short return
  • Monotonicity check

对通过快筛的候选,运行完整评估(同alpha-evaluate)。

Step 6: LLM Judgment — Economic Intuition Filter / LLM判断 — 经济直觉过滤

After statistical screening, the AI (you) should evaluate each surviving factor for economic meaningfulness:

统计筛选后,AI(你)需要评估每个存活因子的经济含义:

For each candidate, ask yourself:

  • Does this factor capture a known market anomaly? (momentum, value, low volatility, etc.)
  • Is there a behavioral or structural reason why this factor should work?
  • Or is it likely just data mining noise?

对每个候选因子,问自己:

  • 这个因子是否捕捉了已知的市场异象?(动量、价值、低波动等)
  • 是否有行为金融学或结构性原因支撑?
  • 还是可能只是数据挖掘的噪音?

Mark each factor with an economic intuition score:

  • Strong intuition: Known anomaly, clear behavioral story
  • Moderate intuition: Plausible but less established
  • Weak intuition: No clear economic story, likely data mining

标记经济直觉评分:

  • 强直觉: 已知异象,清晰的行为金融学解释
  • 中等直觉: 合理但不够成熟
  • 弱直觉: 无清晰经济解释,可能是数据挖掘

Step 7: Present Results / 呈现结果

Output format:

⛏️ Factor Mining Results / 因子挖掘结果

Scanned 搜索: 50 candidates 候选因子
Passed IC screen 通过IC筛选: 12 (24%)
Fully evaluated 完整评估: 10

Top Discoveries / 最佳发现:

 #  Name 名称                    Category 类别    IC Mean   ICIR    Intuition 直觉  
 1  PV divergence 20d            volume          0.066    0.696   Strong 强        
 2  Reversal+PVDiv 5d/20d        composite       0.058    0.612   Strong 强        
 3  Low downside vol 20d         volatility      0.052    0.534   Strong 强        
 4  Mean reversion to MA40       mean_reversion  0.045    0.478   Moderate 中      
 5  Volume-weighted mom 10d      momentum        0.041    0.421   Moderate 中      

Expression / 表达式:
 1: -(close.pct_change().rolling(20).corr(volume.pct_change()))
 2: cs_rank(-ts_return(close,5)) + cs_rank(-(close.pct_change().rolling(20).corr(volume.pct_change())))
 ...

Register to library? / 加入因子库? (specify numbers, e.g., "register 1, 2, 3")

Step 8: Follow-up Actions / 后续操作

After showing results:

  • If user says "register 1, 3, 5" → call alpha-library to register those factors
  • If user says "evaluate #2 in detail" → call alpha-evaluate for full report
  • If user says "mine more" → generate another batch
  • If user says "mine only volatility factors" → re-run with category constraint

Mining Strategies / 挖掘策略

Strategy A: Template-Based (Default) / 基于模板(默认)

Use the category templates above. Structured, every expression has intuition. 使用上述分类模板。结构化,每个表达式都有直觉。

Strategy B: Combinatorial / 组合式

Systematically combine 2 operators: op1(op2(field, w1), w2) 系统性组合2个算子。

Strategy C: Mutation / 变异式

Take a known strong factor, mutate its parameters or operators. 取已知强因子,变异其参数或算子。

Example: pv_diverge (known strong) → try different windows, different correlation methods, add cross-sectional rank, etc.

When the user doesn't specify, use Strategy A (template-based). When the user says "find variations of pv_diverge", use Strategy C. When the user says "try all combinations", use Strategy B (warn: slow).

Important Notes / 注意事项

  1. eval() safety: Only eval expressions built from known templates. Never eval user-provided arbitrary code. eval()安全:只eval从已知模板构建的表达式。绝不eval用户提供的任意代码。

  2. Speed: Quick screen uses sampled dates (every 5th) for 5x speed. Full eval only for top candidates. 速度:快筛使用采样日期(每5个取1个),速度提升5倍。完整评估只对top候选。

  3. Overfitting warning: Many candidates + many parameters = high chance of data mining. Always flag the LLM intuition score prominently. 过拟合警告:大量候选+大量参数=高数据挖掘风险。始终突出显示LLM直觉评分。

  4. Correlation with existing library: If the user has registered factors, check new candidates' correlation with existing ones. Flag high correlation (>0.7) as "likely redundant". 与现有因子库的相关性:如果用户已注册因子,检查新候选与现有因子的相关性。标记高相关(>0.7)为"可能冗余"。

  5. Market awareness: If DATA_MODULE is set, use the corresponding market's data and rules. 市场感知:如果设置了DATA_MODULE,使用对应市场的数据和规则。

Frequently asked questions

What does the Alpha Mine AI skill do?

Automated factor mining. Systematically generate, screen, and evaluate candidate factors. 自动因子挖掘。系统性生成、筛选和评估候选因子。 Triggers: "mine factors", "auto discover", "挖掘因子", "自动挖掘", "alpha-mine"

Why use Alpha Mine on TypingMind?

Because you install it once and use it with any model. Alpha Mine is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Alpha Mine in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/VernonOY/alpha-skills/tree/main/skills/alpha-mine. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Alpha Mine?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Alpha Mine?

As many as you like. As long as a model supports skills, you can use Alpha Mine with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Alpha Mine AI skill free?

Yes. It is published on GitHub by VernonOY under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇