import subprocess, os, sys
BASE = '{baseDir}'
os.makedirs(os.path.join(BASE, 'strategies'), exist_ok=True)
os.makedirs(os.path.join(BASE, 'output'), exist_ok=True)
try:
import httpx, loguru, matplotlib
print("DEPS_OK")
except ImportError:
print("INSTALLING_DEPS...")
subprocess.run([sys.executable, '-m', 'pip', 'install', '--break-system-packages',
'httpx', 'loguru', 'matplotlib'], capture_output=True)
print("DEPS_INSTALLED")
print(f"BASE={BASE}")
If deps install fails → tell user to install manually and STOP.
Detect the user's intent and execute the matching workflow straight through.
| User says (任意一个即触发) | Workflow | Your FIRST response |
|---|---|---|
| ----------- | ---------- | --------------------- |
| "推荐策略" "有什么策略" "推荐" "有现成的吗" "不会写策略" "不知道怎么写" "有没有好的策略" "recommend" "suggestions" "哪个策略好" "试试什么" | Recommend | 直接推荐正收益策略(见下方 §0) |
| "创建策略" "创建一个策略" "创建" "建策略" "新策略" "做一个策略" "写策略" "做策略" "生成策略" "设计策略" "帮我写一个" "create" "new strategy" "想做一个xx策略" "帮我做" "弄个策略" | Create | Extract params → generate Python script (§1),⛔ 禁止 Pine Script |
| "回测" "测一下" "测试" "跑一下" "试试" "看看效果" "backtest" "test" "历史验证" "验证一下" "跑个回测" "看看能不能赚钱" | Backtest | Execute backtest code (§2) |
| "优化" "调参" "优化参数" "优化策略" "优化下" "optimize" "tune" "调优" "提升" "改进参数" | Optimize | ⚠️ 见下方硬规则 |
| "监控" "部署" "上线" "跑起来" "定时执行" "定时跑" "跑策略" "执行策略" "自动执行" "自动跑" "挂着跑" "定时任务" "cron" "run" "deploy" "盯盘" "实盘" "开始跑" "启动" | Monitor | Execute monitor setup (§4) |
| Spans multiple (e.g. "建策略然后回测") | Chain | §1 → §2 sequentially |
当用户只回复一个数字(如 "1" "2" "3" "4" "5" "6")或数字+简短文字(如 "1 genetic" "选2"),必须结合上一轮对话上下文判断,不要当作新请求。
数字上下文映射表:
| 上一轮你问了什么 | 用户回复 | 你应该做什么 |
|---|---|---|
| ----------------- | --------- | ------------- |
| 优化算法选择 (1-6) | "1" / "genetic" / "遗传" | 执行 §3 用 genetic 算法优化 |
| 优化算法选择 (1-6) | "2" / "bayesian" / "贝叶斯" | 执行 §3 用 bayesian 算法优化 |
| 优化算法选择 (1-6) | "3" / "grid" / "穷举" | 执行 §3 用 grid 算法优化 |
| 优化算法选择 (1-6) | "4" / "random" / "随机" | 执行 §3 用 random 算法优化 |
| 优化算法选择 (1-6) | "5" / "annealing" / "退火" | 执行 §3 用 annealing 算法优化 |
| 优化算法选择 (1-6) | "6" / "pso" / "粒子" | 执行 §3 用 pso 算法优化 |
| 监控/部署请求 | 任何 | 执行 §4 选择模式(信号监控 or 监控+自动下单) |
| 私钥/密钥/钱包设置 | 任何 | 执行 §4 Step 2b 安全链接流程 |
| 回测报告下一步 (1-6) | "1" / "genetic" | 执行 §3 用 genetic 算法优化 |
| 回测报告下一步 | "回测" / "再测一次" | 执行 §2 重新回测 |
| 回测报告下一步 | "部署" / "监控" / "跑起来" | 执行 §4 监控 |
| 推荐策略下一步 (1-3) | "1" | 执行 §2 回测 sol_rsi_momentum.py |
| 推荐策略下一步 (1-3) | "2" | 执行 §2 回测 btc_rsi_momentum.py |
| 推荐策略下一步 (1-3) | "3" | 执行 §1 引导用户创建新策略 |
关键规则:
当用户触发 Recommend 工作流(含"推荐策略"/"有什么策略"/"推荐"/"有现成的吗"/"不会写"/"不知道怎么写"/"哪个好"/"recommend" 等),你的回复必须且只能是以下内容(逐字复制,不要改写、不要加分析、不要讲策略类型教程):
> 📊 这是我实测过有正收益的策略,直接用就行:
>
> 1️⃣ SOL RSI 动量策略 (sol_rsi_momentum.py)
> 🪙 SOLUSDT · 4h
> 📈 RSI>65 追涨 + RSI<35 追跌,EMA50 趋势过滤
> 💰 2025 回测: +2.27%
>
> 2️⃣ BTC RSI 动量策略 (btc_rsi_momentum.py)
> 🪙 BTCUSDT · 4h
> 📈 RSI>70 极端动量入场,EMA50 过滤,4x ATR trailing
> 💰 2025 回测: +1.40%(B 级评分)
>
> 选一个数字,我帮你回测看最新效果 👇
> 1 — 回测 SOL 策略
> 2 — 回测 BTC 策略
> 3 — 我想自己写一个新策略
然后等用户回复,不要做任何其他事情。
禁止行为(违反任何一条 = 没有遵守 skill):
❌ BAD — 以下是错误回复(绝对禁止):
> "最值得试的 4 类:1. 趋势跟随+回踩确认 2. EMA20/60+RSI+ATR 3. 突破策略 4. 波动率过滤趋势策略……"
> "我该先看 skill 里有没有推荐模板……我前面偏离了 skill 的执行纪律……"
✅ GOOD — 唯一正确的回复就是上方引用块里的模板,逐字复制,不多不少。
当用户触发 Optimize 工作流(含"优化"/"调参"/"调优"/"提升"/"改进参数"/"optimize"/"tune" 等),你的回复必须且只能是以下内容(逐字复制,不要改写、不要加分析、不要先给建议):
> 好的,我们用服务器算法自动搜索最优参数。请选择优化算法:
> 1️⃣ genetic(遗传算法)← 推荐
> 2️⃣ bayesian(贝叶斯优化)
> 3️⃣ grid(网格穷举)
> 4️⃣ random(随机搜索)
> 5️⃣ annealing(模拟退火)
> 6️⃣ pso(粒子群)
> 回复数字或名称即可开始。
然后等用户回复,不要做任何其他事情。
用户回复后 → 执行 §3 Step 0 + Step 1 代码 → 调用 run_optimization()。
禁止行为(违反任何一条 = 没有遵守 skill):
你没有权力判断策略值不值得优化。用户说优化,你就优化。
Automation posture: prefer direct execution. Run the code and show results rather than listing steps. Use sensible defaults unless user specifies otherwise.
Only stop to ask when:
Never stop for:
用户通过 Telegram 使用本 Skill。你执行代码后,必须把 stdout 输出作为 TG 消息发送给用户,而不是仅仅"展示执行结果"。
代码执行 → stdout 输出(print)→ AI 捕获 → 作为 TG 消息发送给用户
print() 输出的格式化内容原样作为 TG 消息发送,不要包裹在代码块里,不要加额外解释_equity_chart_path / _optimization_chart_path),用 Bash 执行 openclaw message send --path "<图片路径>" --caption "<_caption文本>" 发送图片print() 输出已经是格式化好的 tag 样式,直接发,不要用自己的话重写| 场景 | 发什么 | 怎么发 |
|---|---|---|
| ------ | -------- | -------- |
| 策略已生成 | 文本消息 | stdout 输出原样发送 |
| 回测完成 | 图片 + caption | 发图片附件,caption = _caption,不要额外发文字 |
| 优化完成 | 图片 + caption | 发图片附件,caption = _caption,不要额外发文字 |
| 监控启动/停止/列表/状态 | 文本消息 | stdout 输出原样发送 |
| 选择提示(算法/模式) | 文本消息 | 逐字发送模板内容 |
注意:回测和优化使用单代码块(run_server_backtest / run_optimization),执行过程中的 stdout(进度、提交确认等)不需要单独发送,最终只发图片+caption 即可。
User describes a trading idea → you generate a Python script → save to {baseDir}/strategies/.
From the user's description, extract:
SYMBOL: Which coin pair (default: BTCUSDT)
TIMEFRAME: K-line interval (default: 4h)
ENTRY: What triggers buy/long
EXIT: What triggers sell/close
RISK: Stop loss, take profit, position sizing
FILTERS: Volume, volatility, time-of-day
If entry/exit conditions are missing, STOP and ask. Everything else — use defaults silently.
Save to {baseDir}/strategies/{name}_strategy.py. The script is never executed locally — its source code is uploaded to the server as a string for backtesting.
import sys
sys.path.insert(0, '{baseDir}/scripts')
from data_client import DataClient
from indicators import Indicators as ind
import numpy as np
def generate_signals(mode='backtest', start_date=None, end_date=None):
dc = DataClient()
df = dc.get_perp_klines("BTCUSDT", "4h", start_date, end_date)
close = df["close"].values.astype(float)
high = df["high"].values.astype(float)
low = df["low"].values.astype(float)
volume = df["volume"].values.astype(float)
# --- Indicators ---
ema_fast = ind.ema(close, 20)
ema_slow = ind.ema(close, 60)
# --- Signals ---
signals = []
lookback = 61 # max indicator period + 1
for i in range(lookback, len(df)):
if np.isnan(ema_fast[i]) or np.isnan(ema_slow[i]):
continue
if ema_fast[i] > ema_slow[i] and ema_fast[i-1] <= ema_slow[i-1]:
signals.append({
"timestamp": str(df.iloc[i]["datetime"]),
"symbol": "BTCUSDT", "action": "buy", "direction": "long",
"confidence": 0.7, "reason": "EMA20 cross up EMA60",
"price_at_signal": float(df["close"].iloc[i]),
})
if ema_fast[i] < ema_slow[i] and ema_fast[i-1] >= ema_slow[i-1]:
signals.append({
"timestamp": str(df.iloc[i]["datetime"]),
"symbol": "BTCUSDT", "action": "sell", "direction": "long",
"confidence": 0.7, "reason": "EMA20 cross down EMA60",
"price_at_signal": float(df["close"].iloc[i]),
})
return {"strategy_name": "EMA Cross Strategy", "signals": signals}
策略文件保存后,发一条 TG 消息给用户(不是代码块,直接发文本消息):
> ✅ 策略已生成
> 📊 策略: {strategy_name}
> 🪙 交易对: {SYMBOL} · {TIMEFRAME}
> 📈 入场: {entry 一句话}
> 📉 出场: {exit 一句话}
> 📁 文件: {file_path}
> 要回测看看效果吗?
{baseDir}/strategies/)| Strategy file | Symbol | Style | 2025 回测 | Tested grade |
|---|---|---|---|---|
| -------------- | -------- | ------- | ----------- | -------------- |
sol_rsi_momentum.py | SOLUSDT | RSI>65 追涨 + RSI<35 追跌,EMA50 趋势过滤,trailing stop | +2.27% | C (7/14) |
btc_rsi_momentum.py | BTCUSDT | RSI>70 极端动量入场,EMA50 过滤,4x ATR trailing | +1.40% | B (10/14) |
sol_kdj_swing.py | SOLUSDT | KDJ 超卖反弹 + EMA50 趋势过滤,多空双向 | +2.09% | C (6/14) |
btc_trend_pullback.py | BTCUSDT | EMA50 趋势 + EMA20 回踩入场,ATR trailing | -1.21% | C (8/14) |
btc_macd_trend.py | BTCUSDT | MACD 金叉/死叉 + EMA100 方向过滤 | -1.84% | C (7/14) |
只推荐前 2 个正收益策略。 其余策略仅在用户主动问起时提及。
All strategies have PARAMS dict for optimization. Suggest: "可以用优化功能搜索最优参数"
| Allowed | Blocked |
|---|---|
| --------- | --------- |
sys, numpy, data_client, indicators | os, subprocess, socket, requests, httpx, pandas |
ind.ema(), ind.sma(), ind.rsi() | df.rolling(), df.shift(), df.apply() |
df["close"].values.astype(float) | df["close"].rolling(20).mean() |
float(df["close"].iloc[i]) | import pandas as pd |
str(df.iloc[i]["datetime"]) | df.index[i] or row index i as timestamp |
| Field | Required | Example |
|---|---|---|
| ------- | ---------- | --------- |
timestamp | Yes | str(df.iloc[i]["datetime"]) |
symbol | Yes | "BTCUSDT" |
action | Yes | buy / sell / close / hold |
direction | Yes | long / short |
confidence | Yes | 0.7 (0.0–1.0) |
reason | Yes | "EMA20 cross up EMA60" |
price_at_signal | Yes | float(df["close"].iloc[i]) |
suggested_stop_loss | No | stop loss price |
suggested_take_profit | No | take profit price |
How it works: Read strategy .py → pass source code as string → server fetches K-lines, executes script, simulates trades, returns metrics. You never run the strategy script locally.
LOCAL (单代码块) SERVER
┌──────────────────┐ script ┌─────────────────┐
│ run_server_ │ ───────▶ │ Fetch K-lines │
│ backtest() │ │ Execute script │
│ (内部自动轮询) │ ◀─────── │ Simulate trades │
│ print_metrics() │ metrics │ Return report │
└──────────────────┘ └─────────────────┘
⚠ 必须用 run_server_backtest()!它内置了自动轮询和进度打印,一个代码块搞定全流程。
⛔ 禁止拆分为两个代码块! 拆分后第二个代码块不会被执行,用户收不到结果。
import sys
sys.path.insert(0, '{baseDir}/scripts')
from api_client import QuantAPIClient
with open('{baseDir}/strategies/xxx_strategy.py', 'r') as f:
script_content = f.read()
client = QuantAPIClient(timeout=300.0)
bt = client.run_server_backtest(
script_content=script_content,
strategy_name="策略名",
symbol="BTCUSDT",
timeframe="4h",
start_date="2025-01-01",
end_date="2025-12-31",
leverage=3,
initial_capital=100000,
direction="long_short",
)
run_server_backtest() 内部会自动:
📋 回测已提交: {job_id} | 策略名 (BTCUSDT 4h)⏳ [Xs] stage (N%)print_metrics() 生成报告 + 权益曲线 PNG⚠ 代码执行完毕后你 MUST 用 Bash 发送图片:
openclaw message send --path "<bt._equity_chart_path的值>" --caption "<bt._caption的值 + 评分建议>"
⛔ 禁止只打印图片路径当文字发。必须用 openclaw message send --path 发送图片文件。
⛔ 禁止行为:
_caption 另起炉灶| Param | Default | Options |
|---|---|---|
| ------- | --------- | --------- |
symbol | BTCUSDT | Any Binance perpetual pair |
timeframe | 4h | 1m 5m 15m 1h 4h 1d |
start_date | 2025-01-01 | YYYY-MM-DD |
end_date | 2025-12-31 | YYYY-MM-DD |
leverage | 3 | 1–125 |
initial_capital | 100000 | USD |
direction | long_short | long_only short_only long_short |
| Error | Auto-action |
|---|---|
| ------- | ------------- |
脚本安全检查未通过 | Fix strategy (sandbox violation) — see §1 Sandbox rules |
status: failed | Retry once automatically, then report |
| 执行超时 | run_server_backtest 内部自动每 5 秒轮询,无需手动处理 |
| Network error / timeout | Retry once, then report |
print_trades(bt) prints full trade table — only needed if user asks for more details.
After completion, suggest next step based on grade (append to caption, keep concise):
#优秀 效果不错,可以直接部署监控#待优化 建议用参数优化提升,推荐 genetic#失败 建议重新设计策略逻辑#无信号 入场条件可能太严格Server returns a scorecard with 7 metrics, each scored 0-2 (max 14):
| Metric | 🟢 优 (2分) | 🟡 及格 (1分) | 🔴 差 (0分) |
|---|---|---|---|
| -------- | ------------ | -------------- | ------------ |
| 收益率 | >20% | >0% | ≤0% |
| Sharpe | >1.5 | >0.5 | ≤0.5 |
| 最大回撤 | <10% | <20% | ≥20% |
| 胜率 | >50% | >35% | ≤35% |
| 盈亏比 | >1.5 | >1.0 | ≤1.0 |
| 交易数 | ≥30 | ≥10 | <10 |
| 爆仓 | 0次 | — | >0次 |
| Grade | Score | Conclusion | Meaning |
|---|---|---|---|
| ------- | ------- | ------------ | --------- |
| A | 12-14 | approved | 优秀策略,可直接实盘 |
| B | 9-11 | approved | 良好策略,建议小仓实盘验证 |
| C | 6-8 | paper_trade_first | 及格策略,建议先模拟观察 |
| D | 3-5 | rejected | 较差策略,需要优化后再测 |
| F | 0-2 | rejected | 失败策略,建议重新设计 |
Reminder: 触发表里的"优化硬规则"已经规定了你的第一条回复内容。到这里时,用户已经选好了算法。直接执行下面的步骤。
The strategy must have a PARAMS dict at the top. If not, refactor it first:
Before (hardcoded — cannot optimize):
ema_fast = ind.ema(close, 20)
ema_slow = ind.ema(close, 60)
After (parameterized — ready to optimize):
PARAMS = {'fast_ema': 20, 'slow_ema': 60, 'rsi_th': 55, 'sl_atr': 1.5, 'tp_atr': 3.0}
def generate_signals(mode='backtest', start_date=None, end_date=None):
fast = PARAMS['fast_ema']
slow = PARAMS['slow_ema']
ema_fast = ind.ema(close, fast)
ema_slow = ind.ema(close, slow)
If the strategy needs refactoring, do it silently, save, then continue.
⚠ 必须用 run_optimization()!它内置了自动轮询和进度打印(25%/50%/90%里程碑),一个代码块搞定全流程。
⛔ 禁止拆分为两个代码块! 拆分后第二个代码块不会被执行,用户收不到结果。
import sys; sys.path.insert(0, '{baseDir}/scripts')
from api_client import QuantAPIClient
with open('{baseDir}/strategies/xxx_strategy.py', 'r') as f:
script_content = f.read()
client = QuantAPIClient(timeout=600.0)
result = client.run_optimization(
script_content=script_content,
params=[
{"name": "fast_ema", "type": "int", "low": 10, "high": 30, "step": 5},
{"name": "slow_ema", "type": "int", "low": 40, "high": 80, "step": 10},
{"name": "rsi_th", "type": "int", "low": 45, "high": 60, "step": 5},
{"name": "sl_atr", "type": "float", "low": 1.0, "high": 2.0, "step": 0.2},
{"name": "tp_atr", "type": "float", "low": 2.0, "high": 4.0, "step": 0.5},
],
strategy_name="策略优化",
symbol="BTCUSDT", timeframe="4h",
start_date="2025-01-01", end_date="2025-12-31",
fitness_metric="sharpe_ratio",
max_combinations=100,
method="genetic",
)
run_optimization() 内部会自动:
⏳ 优化任务已提交 (job_id: xxx),共 N 种参数组合print_optimization() 生成报告 + 优化图表 PNG⚠ 代码执行完毕后你 MUST 用 Bash 发送图片:
openclaw message send --path "<result._optimization_chart_path的值>" --caption "<result._caption的值>"
⛔ 禁止只打印图片路径当文字发。必须用 openclaw message send --path 发送图片文件。
⛔ 禁止行为:
_caption 另起炉灶| Method | Best for | When to pick |
|---|---|---|
| -------- | ---------- | -------------- |
genetic | Large param space | Default |
bayesian | Few evaluations | User says "快速" |
grid | ≤200 combos | User says "穷举" |
random | High-dimensional | Exploratory |
annealing | Escape local optima | Stuck in bad region |
pso | Continuous params | All-float params |
| Metric | Default |
|---|---|
| -------- | --------- |
sharpe_ratio | Yes — risk-adjusted return |
total_return | Raw total return |
max_drawdown | Minimize drawdown |
win_rate | Maximize win rate |
profit_factor | Gross profit / gross loss |
If the strategy hasn't been backtested, warn: "这个策略还没有回测过,建议先回测。" If user insists, proceed.
When user triggers Monitor workflow, you MUST present this message verbatim:
> 📡 策略监控部署 — 请选择模式:
>
> 1️⃣ 仅监控信号 — 服务器 7×24 运行,收到信号后你自己操作,不需要私钥
> 2️⃣ 监控 + 自动下单 — 服务器 7×24 运行,信号产生后自动下单到 Hyperliquid
>
> 两种模式都:免费 3 个策略、7×24、无需本地开机。
> 模式 2 需要通过安全链接配置钱包密钥(不在聊天里输入)。
> 回复 1 或 2 选择。
Wait for user to choose before proceeding.
import sys; sys.path.insert(0, '{baseDir}/scripts')
from api_client import QuantAPIClient
with open('{baseDir}/strategies/xxx_strategy.py', 'r') as f:
script_content = f.read()
client = QuantAPIClient(timeout=60.0)
result = client.start_monitor(
script_content=script_content,
strategy_name="策略名",
symbol="BTCUSDT",
timeframe="4h",
interval_seconds=14400,
)
print(f"✅ 监控已启动 | Job ID: {result['job_id']} | 配额 {result['quota_used']}/{result['quota_max']}")
先配置密钥(安全链接) → 再启动监控。信号产生后服务器自动下单。
import sys; sys.path.insert(0, '{baseDir}/scripts')
from api_client import QuantAPIClient
client = QuantAPIClient(timeout=60.0)
vault = client.vault_status()
if not vault.get("has_key"):
link = client.vault_setup_link()
print(f"\n🔐 请在浏览器中打开以下链接,安全提交你的钱包私钥:")
print(f"{link['url']}")
print(f"\n⏰ 链接 30 分钟内有效。提交完成后回来告诉我「OK」。")
When user confirms key is set:
import sys; sys.path.insert(0, '{baseDir}/scripts')
from api_client import QuantAPIClient
client = QuantAPIClient(timeout=60.0)
vault = client.vault_status()
if not vault.get("has_key"):
print("❌ 密钥还没有配置,请先打开链接提交私钥")
else:
with open('{baseDir}/strategies/xxx_strategy.py', 'r') as f:
script_content = f.read()
result = client.start_monitor(
script_content=script_content,
strategy_name="策略名",
symbol="BTCUSDT",
timeframe="4h",
interval_seconds=14400,
)
net = vault.get("network", "mainnet")
print(f"✅ 监控+自动下单已启动 | Job ID: {result['job_id']} | {net}")
print(f" 产生信号后将自动下单到 Hyperliquid {'测试网' if net == 'testnet' else '主网'}")
client.check_monitor(job_id)client.list_monitors()client.stop_monitor(job_id)client.vault_status()client.vault_delete()client.vault_setup_link()⛔ 绝对不要让用户在聊天中发送私钥!
如果用户主动发送了私钥,你必须立即回复:
> ⚠️ 安全警告
>
> 请不要在聊天中发送私钥!私钥会留在聊天记录中,非常不安全。
> 如果这个私钥控制了真实资金,建议立即转移资产并更换钱包。
>
> 正确做法:我帮你生成一个安全链接,你在浏览器里提交私钥,不经过聊天。
> 回复「设置密钥」,我来帮你操作。
| Rule | Default | Effect |
|---|---|---|
| ------ | --------- | -------- |
| 置信度 | ≥ 0.6 | 低于 0.6 的信号不执行 |
| 仓位限制 | 10% equity | 单笔不超过总权益的 10% |
| 并发限制 | 3 positions | 最多同时 3 个仓位 |
| 连续亏损 | 3 次暂停 | 连亏 3 笔自动暂停 (本地模式) |
| 冷却期 | 30 min | 两次交易间隔最短 (本地模式) |
Always include risk disclaimer: ⚠️ 实盘交易涉及真实资金风险,建议先用测试网 (HYPERLIQUID_TESTNET=1) 验证。
dc = DataClient()
df = dc.get_perp_klines("BTCUSDT", "4h", start_date, end_date) # perpetual futures
df = dc.get_spot_klines("BTCUSDT", "1h", start_date, end_date) # spot
# Returns DataFrame: datetime, open, high, low, close, volume
Only use get_perp_klines and get_spot_klines. Do not invent method names.
| Method | Signature |
|---|---|
| -------- | ----------- |
ema | ind.ema(series, period) |
sma | ind.sma(series, period) |
rsi | ind.rsi(series, period) |
macd | ind.macd(series, fast, slow, signal) |
bollinger_bands | ind.bollinger_bands(series, period, num_std) → (upper, middle, lower) |
atr | ind.atr(high, low, close, period) |
kdj | ind.kdj(high, low, close, k, d, j) |
crossover | ind.crossover(a, b) |
All return numpy arrays. Use arr[i], not .iloc[i].
| Method | Description |
|---|---|
| -------- | ------------- |
run_server_backtest(...) | ⭐ 回测必用 — 提交+轮询+报告一次完成 |
submit_backtest(...) | 仅提交任务(⛔ 不要单独使用,用 run_server_backtest 代替) |
check_backtest(job_id) | 仅查询状态(⛔ 不要单独使用,用 run_server_backtest 代替) |
wait_backtest(job_id) | 仅轮询等待(⛔ 不要单独使用,用 run_server_backtest 代替) |
run_optimization(...) | ⭐ 优化必用 — 提交+轮询+报告一次完成,内置进度打印 |
submit_optimization(...) | 仅提交任务(⛔ 不要单独使用,用 run_optimization 代替) |
check_optimization(job_id) | 仅查询进度(⛔ 不要单独使用,用 run_optimization 代替) |
print_metrics(result) | Display backtest report card |
print_optimization(result) | Display optimization report (auto-called) |
start_monitor(script, name, symbol, timeframe, interval) | 启动服务器监控(最多 3 个同时运行) |
check_monitor(job_id) | 查看监控状态 + 最近信号 |
list_monitors() | 列出我的所有监控任务 |
stop_monitor(job_id) | 停止监控任务 |
vault_setup_link() | 生成一次性安全链接,用户在浏览器中提交私钥 |
vault_status() | 查询密钥是否已配置 |
vault_delete() | 删除已存储的密钥 |
print_trades(result) | Display trade records (only when user asks) |
| Feature | Limit |
|---|---|
| --------- | ------- |
| Strategy generation | Unlimited, free |
| Backtest | Unlimited, free |
| Optimization | Unlimited, free |
| Live monitoring | 3 slots |
| Forbidden | Why | Correct |
|---|---|---|
| ----------- | ----- | --------- |
| Run strategy script locally for backtest | Server runs it | run_server_backtest(script_content=...) |
import os/subprocess/socket in strategy | Sandbox blocks them | Only sys, numpy, data_client, indicators |
df.rolling(), df.shift(), df.apply() | Server pandas restricted | Use ind.ema(), ind.sma() etc. |
| Install numpy/pandas for backtest | Server has them | Only httpx loguru matplotlib locally |
| Build local backtest engine | Server already has one | Use run_server_backtest() |
| 拆分为两个代码块 (submit→poll) | 第二个代码块不会被执行 | 用 run_server_backtest() / run_optimization() 单代码块 |
Call httpx.post() directly | Missing auth/polling | Use QuantAPIClient |
| 用户问"推荐策略"时讲策略类型教程(趋势跟随/均值回归/突破…) | 用户要能直接用的策略,不是上课 | 逐字发送推荐策略硬规则的固定模板,推荐 2 个正收益策略文件 |
| 只推荐本地运行、不提供服务器监控选项 | 用户可能更想 7×24 服务器监控 | 按 §4 Step 1 先让用户选择模式 |
| 在聊天中索要或接收用户的钱包私钥 | 私钥会留在聊天记录中,极不安全 | 用 vault_setup_link() 生成安全链接,用户在浏览器中提交 |
| Manually tweak params + re-backtest when user says "优化" | That's guessing, not optimizing | Use §3 run_optimization() |
| Add new indicators/filters when user says "优化" | That's redesign (§1), not optimize (§3) | 优化=调参数, 重新设计=改逻辑 |
| Send text and image as separate TG messages | 用户只看到最后一条 | 一条 TG 图片消息(caption 含指标摘要) |
Use  or 只打印路径 | TG 无法渲染本地路径 | openclaw message send --path |
| 把 stdout 放在代码块里展示 | 用户在 TG 看不到代码块结果 | 捕获 stdout → 作为 TG 文本消息发送 |
| 自己写分析替代 print 输出 | print 输出已格式化好 | 原样发送 stdout,不改写 |
| 生成 TradingView Pine Script (//@version=5) | 本 Skill 只支持 Python | 用 §1 的 Python 模板生成策略 |
sol_rsi_momentum.py 和 btc_rsi_momentum.py。run_server_backtest(),优化用 run_optimization(),一个代码块搞定全流程。禁止拆分为两个代码块。arr[i] not .iloc[i].str(df.iloc[i]["datetime"]) — never row index.lookback covers longest indicator. EMA(60) → at least 61 bars warmup.btc_ema_cross_strategy.py, not strategy1.py.httpx, loguru, matplotlib. Don't install numpy/pandas — server has them.共 1 个版本