Install
$ agentstack add skill-himanshuj16-algo-trading-skills-binance-futures-testnet-to-mainnet-promotion ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Binance Futures Testnet to Mainnet Promotion
When to Use
Invoke this when a strategy that has been running on the Binance Futures testnet is about to route orders against a mainnet base URL. The promotion step itself is the hazard: the same code, pointed at a different host with different credentials, moves from fake balances to real leveraged capital with liquidation risk. This skill supplies the gate that must pass before an order router is handed a mainnet ExchangeConfig, plus the account-level reconciliation steps that testnet cannot exercise.
Use it for both USDⓈ-M (fapi) and COIN-M (dapi) futures.
When NOT to Use
- Spot or Margin promotion: Binance spot uses different hosts (
api.binance.com) and a
different testnet; the host allowlist and the leverage/position-mode checks here do not apply.
- Brokers with a single endpoint for both environments: If environments are distinguished
only by credentials, the host-binding logic is inapplicable — see alpaca-paper-live-key-separation for the credential-prefix variant of this pattern.
- Backtesting or offline simulation: No live endpoint is involved, so environment
segregation is irrelevant. Use demo-account-realism-gap-assessment to judge whether the testnet record is meaningful at all.
- As a substitute for a general go-live decision: This gate checks environment wiring and
configured risk limits. It does not judge whether the strategy's performance justifies live capital — that is paper-to-live-promotion-checklist.
- As a runtime risk control: This runs once at promotion. Continuous drawdown and exposure
enforcement belongs to kill-switch-and-drawdown-circuit-breakers.
Prerequisites
- Python 3.10+ (standard library only; this module performs no network I/O).
- Separate Binance Futures testnet and mainnet API keys, held in distinctly named
environment variables. Testnet keys are issued from a separate registration flow and are not valid on mainnet — if the same value appears in both configs, one leg is wrong.
- Mainnet key with Futures trading permission enabled and, where the account allows it, an
IP allowlist. Binance's API-key permission and expiry rules have changed more than once; confirm the current rules in Binance's API management docs rather than assuming.
- A testnet track record produced against a testnet host (verify this — it is the first
thing the gate checks).
Workflow
- Build both configurations: Construct
ExchangeConfigfor testnet and mainnet.
MainnetPromotionManager.__init__ rejects, as ValueError, any config whose environment enum is wrong, any pair that shares an api_key or api_secret, and any nonsensical risk ceiling (e.g. max_capital_risk_pct=2, the percent-vs-fraction slip).
- Bind each URL to its environment:
verify_api_connectivityrequires HTTPS and an
exact hostname match against the allowlist for the declared environment. Both legs are checked — a TESTNET-labelled config pointing at fapi.binance.com means the "paper" track record was produced with real orders, so it invalidates the promotion rather than merely warning. Exact matching is deliberate: a startswith/endswith comparison accepts https://fapi.binance.com.attacker.example.
- Validate risk parameters, failing closed:
validate_risk_parametersrejects a missing
key rather than defaulting it, rejects NaN/Inf, rejects non-integer leverage (Binance accepts integer leverage only), and requires hard_stop_loss_enabled to be the boolean True — not any truthy value, because a config loader yielding the string "false" is truthy.
- Require explicit authorization:
allow_live_promotiondefaults toFalse. Wire it
from an operator-controlled deployment flag at the call site (allow_live_promotion=os.environ.get("BINANCE_ALLOW_MAINNET_PROMOTION") == "true"). The module deliberately does not read the environment itself, so the decision stays explicit and the gate stays deterministic under test.
- Reconcile mainnet account state before the first order — this is the part testnet
cannot cover, because these are per-account, per-environment settings that do not travel with your code:
- Position mode:
GET /fapi/v1/positionSide/dual. If it disagrees with testnet, change it
before opening anything — POST /fapi/v1/positionSide/dual is rejected with -4067 when open orders exist and -4068 when a position exists.
- Multi-assets margin mode (
/fapi/v1/multiAssetsMargin) and per-symbol margin type
(/fapi/v1/marginType, which returns -4046 when already set to the requested value).
- Leverage: set it with
POST /fapi/v1/leverageand read the response back. Check the
permitted brackets via GET /fapi/v1/leverageBracket; the leverage your testnet config assumed may exceed what this account and notional tier allow, and Binance has applied lower caps to newly opened futures accounts.
- Symbol filters: re-read
GET /fapi/v1/exchangeInfoon mainnet.LOT_SIZE(stepSize,
minQty), MIN_NOTIONAL, PRICE_FILTER (tickSize) and symbol availability are not guaranteed to match testnet, so quantities that were accepted on testnet can be rejected live.
- Promote: Call
promote_to_mainnet(strategy_params). Every call re-runs the full
pre-flight sequence; a prior success never short-circuits a later parameter set.
- Pilot, then scale: Run minimum-notional size first and compare realized slippage,
funding, and fees against the testnet assumptions before increasing allocation. See incremental-capital-deployment-for-new-strategies.
> Full step-by-step procedure with endpoint-level detail: see references/workflows.md. > Cited Binance API surface for this skill: see references/standards.md. > Printable sign-off checklist: see assets/checklist.md.
Common Pitfalls
- Treating any
https://URL as safe: HTTPS says nothing about which venue you reached.
Bind the host to the declared environment and compare hostnames exactly.
- Reusing one credential pair across both configs: If the shared value is the mainnet key,
the "testnet" phase was live trading. If it is the testnet key, mainnet auth simply fails — the harmless direction, which is why the dangerous direction goes unnoticed.
- Defaulting a missing risk limit:
params.get("leverage", 0)turns a typo'd key into a
pass. On a promotion gate, absent means reject.
- Comparing against NaN:
float("nan") > max_leverageisFalse, so a NaN risk parameter
passes a naive bounds check. Test finiteness explicitly.
- Truthiness checks on safety flags: the string
"false"from an env var or YAML loader is
truthy and will silently disable a stop-loss requirement.
- Treating "already promoted" as idempotent: returning the mainnet config on a repeat call
without re-validating lets a later, over-leveraged parameter set inherit an earlier approval.
- Assuming account settings carry over: position mode, multi-assets mode, margin type and
leverage are per-account and per-environment. Changing position mode after you already hold a position or open order fails (-4067/-4068), so reconcile before the first order.
- Assuming testnet symbol filters match mainnet: differing
stepSize/minNotionalproduce
live -2010 rejections for sizes that worked on testnet.
- Logging config objects: a plain dataclass
reprprintsapi_secretverbatim into logs
and tracebacks. ExchangeConfig here redacts it; do the same for any config you add.
- Trusting the testnet fill model: Binance testnet order books are thin and synthetic.
Slippage, partial fills, and funding observed there are not evidence about mainnet.
- Retrying an ambiguous order on the first live orders: a timed-out
POST /fapi/v1/order
may already have been accepted. Send a client-supplied newClientOrderId (^[\.A-Z\:/a-z0-9_-]{1,36}$) and reconcile before resubmitting — see order-placement-idempotency.
Verification
- Run the unit suite:
python -m unittest discover -s skills/binance-futures-testnet-to-mainnet-promotion/scripts. - Point a TESTNET-labelled config at
https://fapi.binance.comand confirm
run_pre_flight_checks returns False.
- Set
base_urltohttps://fapi.binance.com.attacker.exampleand confirm rejection. - Construct a manager with the same
api_keyin both configs and confirmValueError. - Omit
leveragefromstrategy_paramsand confirm rejection; repeat with
capital_risk_pct=float("nan") and with hard_stop_loss_enabled="false".
- Leave
allow_live_promotionat its default and confirmpromote_to_mainnetraises
PromotionError.
- Promote successfully, then call again with
leverage=50and confirmPromotionError. - Confirm
repr(config)andstr(config)contain no secret material. - Against the live account: confirm
POST /fapi/v1/leverageechoes back the leverage you
requested, and that GET /fapi/v1/exchangeInfo filters for every traded symbol match the quantities your sizing logic emits.
Related Skills
paper-to-live-promotion-checklistalpaca-paper-live-key-separationdemo-account-realism-gap-assessmentsandbox-vs-production-endpoint-driftperpetual-futures-funding-rate-handlingkill-switch-and-drawdown-circuit-breakersorder-placement-idempotencyincremental-capital-deployment-for-new-strategies
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: HimanshuJ16
- Source: HimanshuJ16/Algo-Trading-Skills
- License: Apache-2.0
- Homepage: https://skills.himanshujangir.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.