Three opinionated bot-portfolio managers for StrategyFactory. They read BTC sentiment, rank hot copy-bots by rolling profit factor and win rate, and recommend which bots to add, pause, or keep in your account.
These are not trading bots. They pick the bots. Think of it like a fund-of-funds: the StrategyFactory copy-bots do the trading, the quants in this repo decide which copy-bots should be live in your account at any given moment.
Each quant has a different personality:
- 🔥
sf-quant-aggressive— the Momentum Manager - 🛡️
sf-quant-conservative— the Pension Manager - 🧠
sf-quant-regime— the Adaptive Manager (BTC-regime aware)
All three share the same plumbing — BTC sentiment, hot-strategy scanner, trade-history parser, rolling PF/WR calculator, dry-run-by-default action plan, and a hard one-bot-per-coin-pair collision rule. What differs is how strict the bar is and how fast they rotate.
- What problem this solves
- The three quants
- Side-by-side comparison
- How they work
- Quick start
- Installation
- Onboarding (one-time)
- Usage
- Example output
- Hard rules
- The same-symbol collision rule
- FAQ
- Repo layout
- Security notes
- License
If you copy-trade on StrategyFactory, you've probably noticed:
- There are dozens of "hot" strategies at any given time. Which ones actually have an edge versus which ones are noise?
- A strategy that worked great last quarter can stop working without warning. When do you cut it?
- The same strategy that's gold in a clean uptrend can be garbage in chop. How do you adapt?
This repo answers those questions with three different philosophies. Each one pulls the same data (BTC daily candles for sentiment, StrategyFactory's API for hot strategies and trade histories), then applies its own bar to decide what your lineup should look like.
Every recommendation is dry-run by default. You see the plan, you confirm, then it executes. There is no autonomous mode.
Trades like a momentum trader. Looks at the last 7–30 days and asks one question: is this thing working right now?
If a bot just had a great month, lean in. If a bot just had a bad month, cut it. Eight to ten bots, 5% allocation each, dynamic leverage on.
Guardrails:
- Law of large numbers — never touches a bot with fewer than 20 trades in the scoring window. No five-trade hot streaks.
- Hysteresis — has to clear the floor by 20% to add, drop below the floor by 20% to cut. So it doesn't flip-flop on noise.
Sentiment brake: only triggers when BTC is in a >15% drawdown from its 30-day high AND 14-day realized volatility is elevated. Otherwise, keep deploying.
Best for: chasing returns with a tolerance for rotation.
The exact opposite. Looks at the last 60–90 days, weights the old stuff heaviest, and demands 80 trades minimum before it'll even consider a bot.
Three to five bots, 2% allocation each, fixed 5x leverage. The bar is high:
- Profit factor ≥ 1.60
- Win rate ≥ 0.52
- Consistent across every window — no "great last quarter, ugly last month"
- Equity-curve max drawdown ≤ 25%
The most important thing about this bot: most days it does nothing. That is correct behavior. It's not trying to look busy. It rotates maybe one bot every few weeks, and only when the new candidate is clearly better than what's already there.
Best for: managing serious capital, low churn, sleeping at night.
Doesn't have a fixed personality. Reads BTC and changes personality on the fly.
Every run, classifies the market into one of four regimes:
| BTC Regime | Posture | Behavior |
|---|---|---|
TREND_UP |
OFFENSE | Acts aggressive. 7 bots, 5% each, dynamic leverage. |
RANGE |
BALANCED | 6 bots, 4% each, dynamic leverage. |
HIGH_VOL_CHOP |
DEFENSE | 4 bots, 3% each, fixed leverage 5x. |
TREND_DOWN |
BUNKER | 2 bots, 2% each, fixed leverage 3x. Often pauses everything. |
Thesis: the same copy-bot can be an edge in one market and noise in another. A momentum bot is gold in a trend and garbage in chop. A mean-reverter is the opposite. So instead of one fixed bar, the quant slides the bar with the market.
It also has a confidence score. If BTC is giving mixed signals, it cuts allocation in half and runs one fewer bot. It pays for uncertainty in size, not by skipping the opportunity entirely.
Best for: wanting a quant that handles the macro switching for you.
| Dimension | 🔥 Aggressive | 🛡️ Conservative | 🧠 Regime |
|---|---|---|---|
| Looks at | Last 7–30 days most | Last 60–90 days most | Depends on BTC |
| Window weights | 50/30/15/5 | 5/15/30/50 | Slides with regime |
| Profit factor floor | 1.25 | 1.60 | 1.30 → 1.65 |
| Win rate floor | 0.45 | 0.52 | 0.45 → 0.55 |
| Min trades | 20 | 80 | 25 → 80 |
| Consistency check | No | Yes (PF ≥ 1.10 every window) | No |
| Max-drawdown check | No | Yes (≤ 25%) | No |
| Lineup size | 7–10 bots | 3–5 bots | 2–7 bots |
| Allocation per bot | 5% | 2% | 2–5% |
| Leverage | Dynamic | Fixed 5x | Switches |
| Add hysteresis | Floor × 1.20 | Floor × 1.30 | Floor × 1.20–1.30 |
| Prune hysteresis | Floor × 0.80 | Floor × 0.90 | Floor × 0.80–0.90 |
| Rotation speed | Fast | Slow | Whatever the market wants |
| One bot per coin pair | ✅ Enforced | ✅ Enforced | ✅ Enforced |
All three believe the same thing:
Expected value over story, sample size over excitement, and the sidelines are a valid position. They just disagree on how patient to be.
Every quant does the same five things, every run:
- Read BTC sentiment — daily BTCUSDT candles from Bybit's free public REST. Compute 7-day / 14-day / 30-day returns, drawdown from 30-day high, 14-day realized volatility, and a regime label.
- Pull hot strategies —
GET /api/user-api/strategies/hoton StrategyFactory. - Score each candidate — for each strategy, fetch the full payload with trade
history (
GET /api/user-api/strategies/:id), compute rolling profit factor and win rate over 7d / 30d / 60d / 90d windows, score them against the personality's floors and weights. - Audit the user's current bots —
GET /api/user-api/bots, score each through the same lens. - Recommend — produce a KEEP / PAUSE / REACTIVATE / ADD plan, respecting:
- The one-bot-per-coin-pair collision rule
- The personality's hysteresis (no churn)
- The sentiment brake / regime posture
- The max-bots ceiling
The plan is printed to stdout and --apply actually calls the StrategyFactory API
to enact it. Always dry-run first.
# 1. Clone and install
git clone <this-repo>
cd <this-repo>
pip install requests
# 2. Set up StrategyFactory user-API credentials (one-time)
python sf-quant-aggressive/quant.py onboard
# 3. Try it
python sf-quant-aggressive/quant.py sentiment # read BTC market
python sf-quant-aggressive/quant.py scan # rank hot strategies
python sf-quant-aggressive/quant.py audit # score your current bots
python sf-quant-aggressive/quant.py recommend # full action plan (dry-run)
# 4. Execute when you're happy with the plan
python sf-quant-aggressive/quant.py recommend --applyThe same five subcommands exist on sf-quant-conservative/quant.py and
sf-quant-regime/quant.py.
Requirements:
- Python 3.10+ (uses
X | NonePEP 604 type hints) - The
requestslibrary
pip install requestsThat's it. There are no other runtime dependencies. No database, no Docker, no
node_modules. The quants are pure Python scripts; their only persistent state is
the SF user-API credentials in .env.
The StrategyFactory user API needs a key and a secret. These are different from exchange API keys — they only authenticate you to the StrategyFactory platform itself, so the quant can read your bots and ask for new ones to be created.
- Go to https://app.strategyfactory.ai/settings → User API
- Create an API key with these scopes:
- read: strategies
- read: bots
- read: exchanges
- write: bots (create + pause)
- Copy the key and secret somewhere temporary (you'll paste them in step 2)
python sf-quant-aggressive/quant.py onboard(Or sf-quant-conservative/quant.py onboard or sf-quant-regime/quant.py onboard
— they all share the same .env entry, so you only need to do this once.)
The helper:
- Prompts for the key + secret via
getpass(no echo to chat or shell history) - Verifies the credentials by calling
GET /exchanges - Writes them to
.envasSF_USER_API_KEYandSF_USER_API_SECRET - Sets the file mode to
0600(owner read/write only)
If credentials are already in .env, the helper no-ops unless you pass --force.
The quants need at least one exchange linked on your StrategyFactory account (Bybit, Blofin, Toobit, WEEX, etc). New bots are created on that exchange. If you haven't linked one yet:
- Add the exchange in the StrategyFactory UI: Settings → Exchanges
- Re-run
sentimentto confirm the quant can see it
Every quant exposes the same subcommands:
| Command | What it does |
|---|---|
onboard |
Set SF user-API key/secret (one-time, getpass). |
sentiment |
Read BTC market over last 30 days. |
scan |
Pull hot strategies, score them, sort by personality fit. |
audit |
Pull your current bots, score them through the personality's lens. |
recommend |
Full plan: KEEP / PAUSE / REACTIVATE / ADD. Dry-run by default. |
recommend --apply |
Execute the plan. Calls POST /bots and PATCH /bots/:id. |
Most commands accept --json for machine-readable output.
python sf-quant-aggressive/quant.py sentiment
python sf-quant-aggressive/quant.py scan --top 20
python sf-quant-aggressive/quant.py recommend --max-bots 8 --allocation-pct 5
python sf-quant-aggressive/quant.py recommend --applypython sf-quant-conservative/quant.py scan --top 50 # cast a wider net
python sf-quant-conservative/quant.py recommend --leverage 5
python sf-quant-conservative/quant.py recommend --applypython sf-quant-regime/quant.py sentiment # shows the posture too
python sf-quant-regime/quant.py recommend # auto-picks posture from BTC
python sf-quant-regime/quant.py recommend --regime BUNKER # force a posture for testing
python sf-quant-regime/quant.py recommend --applyHere's what recommend looks like for the aggressive quant on a clean uptrend day:
=== BTC SENTIMENT (last 30d) ===
regime : TREND_UP
7d / 14d / 30d : +1.83% / +6.74% / +9.92%
dd_from_30d_high: -1.59%
realized_vol_14d: 1.41%
aggressive_brake: OFF
=== CURRENT BOTS (4) — symbols covered: BTC, SOL, ETH, AVAX ===
KEEP [BTC ] trendhoo-v5-by-daviddtech-2543 pf30=1.84 wr30=0.51 score=+0.42
KEEP [SOL ] meanrev-spear-by-x-1029 pf30=1.61 wr30=0.58 score=+0.31
PAUSE [ETH ] vol-breakout-by-y-3344 pf30=0.92 wr30=0.38 (PF<floor-20%)
KEEP [AVAX ] crypto-momo-by-z-7711 pf30=1.40 wr30=0.47 score=+0.18
=== CANDIDATES TO ADD (3) ===
ADD [XRP ] new-edge-by-a-9012 pf30=2.10 wr30=0.59 n30= 87 score=+0.81
ADD [DOGE ] fast-mr-by-b-4421 pf30=1.78 wr30=0.55 n30=124 score=+0.62
ADD [LINK ] short-edge-by-c-1188 pf30=1.65 wr30=0.52 n30= 98 score=+0.49
=== REJECTED for symbol collision (2) ===
skip [BTC ] another-btc-momo-by-d-2200 symbol BTC already covered by current lineup
skip [SOL ] sol-fader-by-e-7700 symbol SOL already covered by current lineup
(dry run — re-run with --apply to execute)
The regime quant adds a posture block above the bot lineup:
=== BTC SENTIMENT (last 30d) ===
regime : HIGH_VOL_CHOP confidence=0.62
7d / 14d / 30d : -3.00% / -2.40% / +1.10%
dd_from_30d_high : -6.40%
realized_vol_14d : 5.10%
=== POSTURE: DEFENSE ===
PF≥1.5 WR≥0.55 min trades=50 in 30d
max_bots=4 alloc=3.0% lev=fixed (5x)
weights={'7d': 0.15, '30d': 0.35, '60d': 0.30, '90d': 0.20}
These rules are enforced in code, not just documented. They cannot be overridden at call time.
- Law of large numbers. A strategy must clear the personality's minimum trade count in the scoring window before it's eligible. Aggressive: 20 in 30d. Conservative: 80 in 90d. Regime: 25–80 depending on posture. No exceptions.
- No same-symbol collisions. See the next section.
- Hysteresis on every add and prune. Prevents flip-flopping on noise.
- Dry-run by default.
recommendonly prints the plan. You must pass--applyto execute, and you should always read the dry-run plan first. - No plain-text secrets in transcripts. Onboarding uses
getpass. The runtime reads.env(chmod 600) directly — credentials never appear in stdout, stderr, or logs. - Idempotent. Re-running
recommend --applyon the same plan should no-op. The API rejects duplicate bot creates, and the script skips strategies that already have an ACTIVE or PAUSED bot for the same symbol. - Sidelines count. If no candidates clear the buffer, the quant happily reports "no action." It does not invent rotations to look productive.
This rule deserves its own section because it's the rule most likely to catch you off guard if you don't know about it.
The quant will never run two bots on the same coin pair. Ever. In any personality. Under any market condition.
Two bots on the same symbol (say, two BTC bots) would fight each other for the same position on the exchange. One opens long, the other opens short, hedge mode gets confused, position sizes double up, and you end up with conflicting orders. This is a hard infrastructure constraint, not a preference.
Every recommend run:
- Builds an
occupied_symbolsset from your existing bots. ACTIVE and PAUSED and DRAFT bots all reserve their symbol — a paused bot can still have an open position on the exchange. - Normalizes symbol notation so different exchanges' formats collapse to
the same key:
BTCUSDT.P→btcBTC/USDT→btcETH-USDT-SWAP→eth1000PEPEUSDT→pepeMATIC-USDT-PERP→matic
- Rejects any candidate whose normalized symbol is already in
occupied_symbols. - Dedupes within new adds — only one BTC candidate can be added per run, even if three BTC strategies score above the buffer. The highest-scoring one wins.
- Rejects unknown-symbol candidates — if the quant can't identify what coin pair a strategy trades from the API response, it errs on the side of safety and refuses the add.
If your account already has two bots on the same symbol from before you started
using this skill, audit will surface it:
=== CURRENT BOTS (5) ===
[ACTIVE] [BTC ] trendhoo-v5-by-daviddtech-2543 pf30=1.84 ...
[ACTIVE] [BTC ] another-btc-by-x-9911 pf30=1.55 ... ⚠ DUP
The ⚠ DUP flag tells you which bot is the duplicate. Pause one in the
StrategyFactory UI to free the symbol.
When a candidate gets rejected for a collision, it's logged in a dedicated section so you can see why:
=== REJECTED for symbol collision (2) ===
skip [BTC ] another-btc-momo-by-d-2200 symbol BTC already covered by current lineup
skip [SOL ] sol-fader-by-e-7700 symbol SOL already covered by current lineup
- Chasing returns, comfortable with rotation →
sf-quant-aggressive - Capital preservation, low churn →
sf-quant-conservative - Want a quant that handles macro switching →
sf-quant-regime
Yes — they all share the same .env entry. You can point each at a different
exchange on your StrategyFactory account (--exchange-id) if you want them
isolated. Or run them one at a time and compare recommendations.
No. Two important distinctions:
- The quants don't open positions on your exchange. Each StrategyFactory bot does that itself once it's live. The quants only manage which bots are live.
- Even at the bot-management layer, nothing executes without
--apply. Everyrecommendis dry-run by default.
Law of large numbers. A bot can post a 65% win rate over 15 trades and it tells you basically nothing — random noise produces 65% in small samples regularly. Over 80 trades the number starts to be meaningful. Conservative refuses to be fooled by small samples; that's the entire point.
BTC daily candles, no machine learning. It's a simple rule-based classifier:
- 30-day return
- 14-day return
- Drawdown from 30-day high
- 14-day realized daily-return volatility
You can see the exact thresholds in sf-quant-regime/quant.py — function
classify_regime. It's transparent on purpose. Same input always produces the
same posture.
The quant rejects the add. The collision rule is hard — if we can't identify the symbol, we won't risk running two bots on the same coin pair by accident. This means some valid candidates may get rejected if StrategyFactory's API response omits the symbol field. If this happens to you in practice, file an issue and we'll add more symbol-extraction keys to the parser.
- Aggressive — daily or every other day is fine. The hysteresis means most runs won't actually rotate anything.
- Conservative — weekly is plenty. The bar is high enough that most runs produce "no action."
- Regime — daily makes sense, because BTC can flip regimes overnight and you want the posture to track. The hysteresis still prevents whipsaw.
Yes. The quant trades through StrategyFactory's user API, which routes to whatever exchange you've connected (Bybit, Blofin, Toobit, WEEX, etc). The only Bybit-specific thing is the BTC sentiment pull, which uses Bybit's free public REST as a universal data source. That's not your trading exchange — it's just a free price feed.
No. The StrategyFactory API only supports pause and reactivate on existing
bots — there's no way to change allocation or leverage in place. If a regime
change demands different leverage, the quant pauses the old bot and creates a
new one rather than editing in place.
.
├── Bot-Readme.md # this file
├── sf-quant-aggressive/
│ ├── SKILL.md # Claude-facing instructions
│ ├── quant.py # the executable
│ └── API.md # StrategyFactory user-API reference
├── sf-quant-conservative/
│ ├── SKILL.md
│ ├── quant.py
│ └── API.md
└── sf-quant-regime/
├── SKILL.md
├── quant.py
└── API.md
Each folder is self-contained. Each quant.py is about 850 lines, single-file
Python, no internal imports between them. You can copy any single folder elsewhere
and it will work standalone (just install requests and run onboard).
SKILL.md is written for Claude Code skill-style
discovery — if you use Claude Code as your dev environment, it'll auto-discover
the skills. If you don't, ignore the SKILL.md files and just run quant.py
directly.
API.md is a reformatted version of StrategyFactory's user-API documentation,
included in each folder so each skill is fully self-documenting.
.envis mode 0600 (owner read/write only) after onboarding. Never commit it to git. The bundled.gitignorecovers it.- The SF user-API secret never appears in chat, stdout, stderr, or logs.
Onboarding reads it via
getpass; the runtime reads it from.envand only injects it into request headers. - The quant can create and pause bots. That's it. It can't withdraw funds, it can't change exchange API keys, it can't modify your StrategyFactory account settings. The scope is intentionally narrow.
- Rate limits are respected. A small sleep between API calls keeps you under the 60/minute PATCH limit and the 10-second per-bot cooldown.
- No third-party telemetry. The quants call StrategyFactory and Bybit. That's the entire network surface.
MIT. Use it, fork it, ship it.
- StrategyFactory for the platform and the open user API.
- Bybit for the free public REST market-data feed.
- The mean-reverters and trend-followers whose strategies these quants are picking from.
Built for traders who would rather pick the bots than the trades.