moss-trade-bot-skills — one sentence in, a 36-field trading strategy out

Give Moss a one-sentence mission and it fills all 36 parameters and grades them with its own backtest. Those 36 fields were carried into a weltiq paper slot to

Part 15. moss-trade-bot-skills — the factory that fills 36 strategy fields from one sentence

Done when: you have pulled a 36-field strategy configuration out of a one-sentence mission, moved it into a different engine that charges fees, and re-measured the same 30 days there.

What it does Takes one plain-language sentence, fills in all 36 parameters, and grades that configuration with its own backtest
Who it fits Anyone who has a strategy idea and finds turning it into numbers daunting — and who intends to measure that draft once more somewhere that has costs
Who it doesn't fit Anyone who would trust the score as-is and commit capital (the self-grading has no fees) · anyone expecting it to pick instruments · anyone who wants a dashboard
What you end up with 36 fields from one sentence, that configuration's self-graded score, and the same 30 days re-measured on an engine that charges fees
What you need · cost Code free (MIT-0) · Model your agent's LLM calls (this article: $0.005365) · Market data free · weltiq only if you follow section 5
Time · difficulty 36 fields in a single exchange. Difficulty low-medium — you drop one folder where your agent can see it
Relationship to weltiq It only decides, and leaves the execution seat empty. weltiq went into that empty seat and I counted how many of the 36 fields cross over (section 5). The resident feedback loop, though, did not close
Test environment · date macOS 26.6.2 · arm64 · Python 3.14 · skill moss-trade-bot-factory-en-1.0.3 · 2026-09-21 20:50–21:20 KST (commands and numbers) / 2026-09-22 (screens)
Disclosure weltiq pays me to write this series. Everything said about the tool comes from runs I did myself

The human sentences are the commands I actually typed, rewritten as conversation. The output is measured and the numbers are untouched. Where I cut something for length, I say so. Every order is simulated and there was not one live-account order. None of this is a trading opinion. The raw logs are in the verification record.


1. What this is

moss-site/moss-trade-bot-skills is a bundle of agent skills. It is not a Python library and not an MCP server — it is one SKILL.md plus bundled scripts. Tell an agent like Claude Code or Codex to "install this skill" and the agent reads it and follows it; the instructions are the body of the thing.

Which means what sits in the deciding seat is not this repository's code but the LLM that read this repository's instructions. The code is on the calculator side, taking the numbers that LLM filled in and running a backtest. That distinction matters throughout this article.

There are three steps. (1) The user describes a trading style in one sentence. (2) The LLM fills in all 36 parameters — it does not ask field by field; inference rules like "for trend following, both directions at 0.5" and "if aggressive, 15 to 25 times" are baked into the instructions. (3) It runs its own backtest with those parameters and grades itself.

Item Value How it was checked
URL github.com/moss-site/moss-trade-bot-skills
License MIT-0 (No Attribution — you do not even have to credit the author) GitHub API
Stars ★385 · 34 forks (observed 2026-09-21) GitHub API
Last push 2026-09-09 GitHub API
Created 2026-04-15 · 2 open issues · not archived GitHub API
Distribution shape 12 skill version folders inside the repository (1.0.21 ~ 1.0.27, en-1.0.3) ls
Parameters 36 (scripts/params_schema.json) counted below

The repository description says "bit-exact between backtest and live execution". Whether that claim is true is not covered here — I did not attach to Moss's live platform (ai.moss.site). What I measured is "what happens when you move that configuration to a different execution engine."


2. Installing

There are only two prerequisites — Python 3.14 (the skill digs a .venv inside its own folder) and no money at all. The official route is to have your agent do it.

What you say

Install this skill: https://github.com/moss-site/moss-trade-bot-skills/tree/v1.0.28/moss-trade-bot-factory

If you want to type it yourself
git clone --depth 1 https://github.com/moss-site/moss-trade-bot-skills
cd moss-trade-bot-skills/moss-trade-bot-factory-en-1.0.3
python3 scripts/setup_env.py

The screen after installation finishes

The screen after installation finishes. Three places to look — the 12 at the top means there are twelve folders in the repository that carry a SKILL.md (which one to install is settled just below), the Local virtualenv ready: and Only packages from scripts/requirements.txt were installed. in the middle are the evidence that this tool touched nothing outside its own folder, and the last four lines are where an agent recognises this folder as a skill — name: and user-invocable: true.

The declared dependencies are four lines (pandas, numpy, ccxt, scipy) and 27 packages including what they pull in. I did not time the installation — that is unverified. It does not modify the system Python, it installs nothing beyond the bundled requirements.txt, and it reads no environment variables.

Where it gets stuck

Symptom Cause Fix
I don't know which folder to install 12 version folders, and the folder names and the skill name: do not line up, so three pairs share a name Keep exactly one edition at a time. For English, moss-trade-bot-factory-en-1.0.3
The agent never picks up the skill Folder location Drop the whole folder under ~/.claude/skills/. If you created that directory after the session started, restart the agent
I can't tell whether it fired If it does not fire, the agent just answers plausibly out of its own knowledge Three tells — it asks whether to install the .venv · it asks "shall I turn on weekly evolution?" · all 36 fields come back at once with no field-by-field questions
data_cache/ is empty It is fetched on first run That is normal
The backtest won't run You used the system Python {skill folder}/.venv/bin/python

3. The first result

There is no dashboard. No web UI, no TUI — the conversation output and the terminal output are all of it, with no command to start, no address and no login. (The maker's hosting platform ai.moss.site does have a dashboard, but that is outside the skill and this article did not attach to it.)

The smallest example is giving it a one-sentence mission.

What you say — typed in Korean, meaning "trade Bitcoin and make me a profit. And explain why you did what you did."

비트코인을 거래해서 수익을 내줘. 그리고 왜 그렇게 했는지 설명해줘.

What comes back (measured — the fields a person looks at first, out of the 36)

BTC Balanced Trend Compounding  (BTC稳健趋势复利策略)
  direction       long_bias 0.5        -> both ways
  leverage        base 10x / max 15x
  signal weights  trend 0.35 · momentum 0.25 · mean reversion 0.10 · volume 0.15 · volatility 0.15
  entry/exit      entry 0.25 / exit 0.10
  moving averages 10 / 50            RSI 14   MACD 12/26/9   Bollinger 20 x 2.0
  stop/target     ATR x 2.0 / RR 3.0   trailing stop on (triggers at 2%, ATR x 1.5)
  rolling         on (reinvest 50% of unrealized gains at 30%, max 2 times)
  regime sensitivity  0.65, exit when the regime turns

Moss filling in all 36 fields

The defining picture of this article. The only thing the human supplied is the one blue line; everything else is the tool's output. Three places to look — the yellow entry_threshold, long_bias and base_leverage are the fields that actually decide "aggressive or conservative", and the red trend_strength_min, rsi_overbought and rsi_oversold are filled in dutifully but never read by the engine (counted in section 5). And the 36 at the bottom — all of them filled at once, with no field-by-field questions.

And it attaches the "why" in its own words.

"사용자가 구체적인 위험 성향을 제시하지 않았기 때문에, 비트코인의 상승과 하락을 모두 거래하는 중립적 추세추종 전략으로 설정했습니다. … 10배 레버리지와 ATR 기반 손절, 이동 손절을 사용하고 수익이 난 포지션만 제한적으로 롤링해 수익 확대와 손실 관리의 균형을 맞췄습니다." — Moss's own output, in Korean (2026-09-21). In English: "Because the user gave no specific risk preference, I set this up as a neutral trend-following strategy that trades both bitcoin's rises and its falls. … It uses 10x leverage, an ATR-based stop and a trailing stop, and rolls only positions already in profit, in a limited way, to balance growing the gains against managing the losses."

This is what it looks like when it works. All 36 fields filled, nothing left blank, and a "why" attached.

Next the skill grades itself with its own backtest. Here is the result against the bundled CSV (2025-10-06 to 2026-03-03, BTC/USDT 15-minute candles, 148 days, capital 10,000).

total_return 1.14%   sharpe 0.125   max_drawdown 17.88%
win_rate 34.6%       profit_factor 1.008   total_trades 280

Moss running its own backtest

The self-grading running. Two places to look — the 2.626 total at the top: 148 days of 15-minute candles finishes in 2.6 seconds. And the red profit_factor 1.0079… below: it barely clears 1. This screen came from re-running the same parameters against the same bundled CSV the next day, and it matched the previous day's value to the last decimal. The calculator itself is deterministic.

Win rate 34.6%, profit factor 1.008. Remember those numbers. They come back in the very next section.


4. The best way to use it — measuring the self-grading once more

This tool's real value is not "it fills 36 fields" but "it fills them in and grades itself." Except nobody looks at what assumptions that grading rests on. In the whole of scripts/core/backtest.py, not one string relating to fees, slippage or the order book appears.

grep -rniE "fee|commission|slippage|taker|maker" core/*.py *.py
# (no output — exit code 1)

So the self-grading is zero fees, zero slippage, and stops and targets fill exactly at that price inside the candle. The profit factor of 1.008 in section 3 is a number from that world, and it means "pay a single unit of fee and it goes negative."

So I put the same parameters, the same instrument and the same 30 days into two engines. I fetched 2026-08-22 to 09-20 fresh with Moss's fetch_data.py, ran the Moss backtest, and ran the same window through a weltiq replay.

Moss self-grading weltiq replay
Period · instrument · candle 2026-08-22 ~ 09-20 · BTC/USDT · 15 min same (2,877 candles)
Leverage 10x none (the strategy container has no field for it)
Fees 0 exchange profile (USDT-M taker 5bp)
Fills stop and target at exactly that price inside the candle on candle close, only protective stops execute between candles
Trades 65 52
Result −3.02% (PF 0.866, win rate 26.2%) realized P&L −98.02 · fees −247.83 → net −345.86 (−3.46%)

Zero fee strings and the two engines compared

Look at the single line at the top — across the entire backtest engine, fee, commission, slippage, taker and maker appear not once (it is a 344-line file). Below that is the same configuration run in two worlds; -3.02% and -3.46% look similar, but the small print under each line is completely different.

The two numbers look similar and their insides are nothing alike. Moss's −3.02% is a loss produced by moving hard at 10x leverage; weltiq's −3.46% was produced with no leverage at all, and 70% of the loss is fees (−247.83 out of −345.86).

Keeping the fill times, sizes and prices and swapping only the rate makes the structure clearer still (measured, shortened).

497 fills · turnover 237,578 USDT · actual fees 137.68 (average 5.795bp)
  binance-usdm  taker 5.0bp -> 118.79   (-13.7% vs actual)
  bybit-linear  taker 5.5bp -> 130.67   (-5.1% vs actual)
  if all of it had filled as maker -> 47.52
assumption: same prices, same sizes; the fills themselves are not re-simulated

All maker and the fees would be a third. In other words this strategy's cost structure is dominated by hitting the market often, not by the rate. The maker figure is only arithmetic, though, and whether it would really have been filled at that quote is not answered (execution_resimulation: false).

One thing that cannot be done: there is no way to put fees into Moss. Neither the parameters nor the code has a field for it.


5. Moving it to weltiq — an integration experiment

The order a person carries it in

Moss's conclusion is 36 parameters, not an order. So carrying it over means "rewriting those numbers as a rule document," and four steps do it.

(1) write the rule document   POST /v1/strategy-rules
(2) write the thesis yourself POST /v1/ai/thesis
(3) set the stop conditions   POST /v1/containers (stop_max_loss and stop_after_hours required)
(4) it runs                   unattended. The container keeps to the rule with both the human and Moss switched off

Steps (2) and (3) cannot be skipped. Leave them out and the stop side returns {"loc":["body","stop_max_loss"],"msg":"Field required"}, and the thesis side returns {"code":"thesis_required"} with three questions — write in one sentence why this strategy makes money, under what market conditions the logic breaks, and the invalidation condition as a number. Those two gates are the boundary of the autonomy.

How many of the 36 carry over — from 2 to 25

The first time the same 36 went into a template-based container, what crossed over was fast_ma_period 10 and slow_ma_period 50 — two, and nothing else. The other 34 were recorded as "no field" rather than approximated.

Then POST /v1/strategy-rules, the entrance for submitting the internal rule grammar with an API key, opened, so I carried the same 36 over again. I read Moss's decision function, core/decision.py, confirmed what calculation each parameter actually feeds into, and rewrote the same calculation as a weltiq computation graph — I moved the formulas, not eyeballed values. The document that came out has 277 nodes and 4 order rules, holding the weighted composition of five signals, the regime modulation, the ATR stop, the RR target and the trailing stop.

Count Which fields
Carried over 25 5 signal weights · 2 entry/exit thresholds · direction (long_bias) · 2 moving averages · RSI period · 3 MACD · 2 Bollinger · risk per trade · max weight · ATR stop · RR target · 3 trailing stop · 2 regime
Could not be carried 11 below

The 11 that could not be carried are three kinds, and the distinction matters.

Count Fields Why
Fields Moss does not use either 3 trend_strength_min rsi_overbought rsi_oversold They are in the schema and the LLM fills them, but nothing anywhere in the engine code reads them (0 references). There was nothing to carry in the first place
Fields weltiq does not have 3 base_leverage max_leverage supertrend_mult There is no leverage field, and supertrend is a recursive band with no counterpart in the allowed operation list
Fields whose meaning changes 5 the 5 rolling_* Staged entry (up to 3 stages) exists in the grammar, but Moss's rolling trigger is unrealized gain at 30% of the leveraged margin, which is not the same statement on a side with no leverage. And staged entry requires fixed-quantity sizing, so it and risk_per_trade are one or the other

2 → 25. And 3 of the 11 that did not make it are not Moss's loss either. The real blanks are 8.

The three places where something was approximated, stated precisely. - max_position_pct 0.5 was carried over as a fixed quantity cap based on the price on the observation day (0.0602 BTC). Moss's side is a ratio of equity, so if the price moves a lot they diverge - Moss's Bollinger standard deviation is the sample one (÷n−1) and weltiq's is the population one (÷n). At a period of 20 the difference is small, but it is not zero - The smoothing on the regime call (192 candles) was not carried over. Moss requires the regime to hold for 192 candles before it accepts a change; the weltiq document accepts it on the candle where it changes

So the best combination is this. Give Moss only the job of "filling the 36 fields," and leave the grading in a world with costs and fills to weltiq. What this combination does not give you is leverage. Moss's 10x becomes 1x on weltiq's side, which means the sizes of the two P&L figures were never comparable to begin with.

How far it went round — and where it stopped

I built a rule document from the 25 that carried over, drew the boundary (BTC/USDT futures, capital 10,000, stop at 200 cumulative loss, auto-terminate after 2 hours) and brought up a container. Here is the 30-day replay.

n_bars 2877 · n_fills 105 · n_trades 52
pnl -98.02  fees 247.83     (realized P&L and fees come back separately)

I handed this output back to Moss unprocessed and asked it to decide again. The only thing the human did was carry it across.

"외부 기록에서는 52개 거래와 105회 체결로 총 수수료 247.83이 발생했고, 총손익 98.02의 손실보다 수수료 부담이 커 비용과 과도한 거래 빈도가 핵심 문제로 보였다. 레버리지는 해당 venue에서 적용되지 않았고 supertrend와 rolling도 실행되지 않았으므로, 이번 조정은 실제로 적용된 신호와 위험관리 파라미터에 집중했다. 진입 임계값과 이동평균 기간을 소폭 높여 저확신 신호를 줄이고, 손실 위험 및 최대 포지션을 낮췄다. 목표 위험보상비는 조금 높여 거래당 비용을 감당할 수 있는 수익 여지를 확보했다." — Moss's own output, in Korean (2026-09-21 21:15 KST). In English: "In the external record, 52 trades and 105 fills produced 247.83 in total fees, and since the fee burden is larger than the 98.02 total loss, cost and excessive trading frequency looked like the core problem. Leverage was not applied on that venue and supertrend and rolling did not execute either, so this adjustment concentrated on the signal and risk-management parameters that were actually applied. I raised the entry threshold and the moving-average periods slightly to cut low-conviction entries, and lowered the loss risk and the maximum position. I raised the target reward-to-risk ratio a little to secure room for profit that can absorb the per-trade cost."

Moss changing six fields after receiving weltiq's record

The revision in progress. The single blue line at the top is everything that was handed over (unprocessed), and below is the tool's answer. Look at the word 수수료 — "fees" — highlighted in yellow: an item that does not even exist in its own backtest is in the reasoning for five of the six fields. The red risk_per_trade and max_position_pct are fields Moss itself declares "locked during the evolution pass", and they changed anyway.

Field Before After Moss's stated reason
entry_threshold 0.25 0.275 "cuts low-conviction entries and unnecessary fills"
fast_ma_period 10 11 "slows the reaction to short-term noise slightly"
slow_ma_period 50 55 "strengthens trend confirmation and reduces frequent direction changes"
risk_per_trade 0.08 0.072 "lowers per-trade risk given the loss confirmed in external execution"
max_position_pct 0.5 0.45 "lowers the position cap to limit exposure to volatility and fill costs"
tp_rr_ratio 3.0 3.3 "widens the room to absorb costs when taking profit, given the high fee burden"

Five of the six reasons contain "fees." It revised its settings looking at a cost that does not even exist in its own backtest — feedback its own world could never produce. (risk_per_trade and max_position_pct are locked in Moss's own evolution rules as "character parameters — change them and the code reverts them", and Moss's LLM changed them anyway. Following the principle that a tool's decision is not corrected, I carried them across as they were.)

I rebuilt the document from the revised 25 fields, submitted it, wrote a new thesis and brought up a new container.

The weltiq strategy container detail — the revised 25 fields as one rule line

One image covers weltiq's side. The 25 fields Moss revised, hardened into one rule line and attached to the container. Three places to look — the 0.275 and × 3.3 in the grey line under the title are exactly the values Moss just produced, and 보호 손절 12% (a 12% protective stop) is the boundary the grammar enforces. The ai tag below that marks this container as created through a tool path (source=ai) rather than by hand. ORDERS 0, FILLS 0 and the user in the Auto-stop field are exactly as they were, undressed — it means a person stopped it before the 2-hour limit ran out and before the 15-minute warm-up had even finished.

This is what was confirmed here. Decision → rule → replay record → decide again → a new container created.

I cannot write that the loop closed. What was fed back to Moss was not a record left by a resident run but a 30-day replay result, and the two containers both had zero fills — I stopped the second before its 15-minute warm-up had even finished. "Took the record a resident run left behind and ran it resident again" is unverified in this article.

Whether the revised configuration was actually better also could not be measured. From the second replay onward, orders were rejected in bulk (accepted 105 first, then accepted 55, direction_conflict 166). The lock that prevents holding a long and a short on the same instrument at once persists at the account level, and because the first replay ended with an open position, the long-side lock was never released. Putting two numbers from a contaminated state side by side is not a comparison, so this stays unverified — it is a weltiq-side known issue.


6. After using it

What was good

  1. One sentence fills 36 fields. The decision not to ask field by field is bold, and it really does come back with no blanks
  2. It does not touch anything outside its own folder. No package beyond the bundled requirements.txt, no environment variables read
  3. It always attaches a "why". And when it revises, a reason per field. There is no better output shape for running feedback
  4. It is fast and deterministic. A 148-day 15-minute-candle backtest takes 2.6 seconds, and re-running it the next day matched to the last decimal. MIT-0, so not even an attribution obligation

What fell short

  1. Its self-grading has no fees and no slippage. That is why a profit factor of 1.008 comes out, and it is stated nowhere in the README or the output. The biggest weakness
  2. Stops and targets fill at exactly that price inside the candle. That is the single largest divergence from real fills, and the assumption is never surfaced
  3. 3 of the 36 parameters are never used. The LLM dutifully fills trend_strength_min, rsi_overbought and rsi_oversold, and the engine never reads them. The user is led to believe they tuned something
  4. Its own LLM breaks its own evolution rules. The character parameters are documented as locked, and the evolution pass changed two of them. When you carry it outside, a person has to look

Cost

Item Value
Code · market data Free (MIT-0)
Model $0.005365 for this entire article (agent LLM calls)
Time One exchange from mission to 36 fields · 148-day self-backtest in 2.6 seconds

Who it does not fit is anyone who would trust the score it produces and commit capital on it. This tool's score is a score from a world without fees, and that is not a criticism of the tool but a matter of knowing where a score came from.


7. Coming next

Part 16 is OpenAlice (★7.1k).

Where Moss "fills 36 fields and leaves execution on its own platform," OpenAlice is a thing whose README tells you itself to "start with the simulator or paper." They come in at a different place — Moss meshed through the output format of its decision, OpenAlice through the order of the execution stages. And the round trip this part could not get, part 16 actually gets.

Getting ready for weltiq — 3 lines 1. Sign up: {{CTA_URL}} 2. My page → Connections, issue an API key 3. claude mcp add weltiq --header "Authorization: Bearer <key>" https://weltiq.ai/mcp

That is where to look when you want the 36 fields Moss filled re-measured in a world that charges fees.


Every command, output and number in this article came from actual runs on 2026-09-21 (commands) and 2026-09-22 (screens). No real money moved; everything is simulated. None of it is a trading opinion. The trial and error, raw logs and per-field detail not printed here are in the verification record.