Creator guide

Bring your strategy. Change ~2 lines. Your source code never leaves our server.

πŸ”’ Your bot runs in a sealed sandbox. It is never downloadable by buyers β€” they see results only, never your code. Access is restricted to our automated build-and-run system.

How it works

Your bot doesn't talk to an exchange directly and never holds API keys. Instead it submits orders to our SDK, and our broker executes them at the real price on the correct account β€” your account for your live track record, and each customer's account for their copy. That's what lets us give every bot a verified record (independently recorded by us) while keeping your code private.

What makes a bot rentable

The one rule for renting: your bot must place its orders through the CodeVaultEx SDK (vault.ccxt().create_order(...) or vault.place_order(...)) as its main order path β€” not by calling the exchange API directly with its own key.

Why: when a customer rents your bot, their copy runs without any API key inside it (we never put a renter's keys in your code β€” that's what keeps them safe). A bot that trades the exchange directly has nothing to authenticate with in a renter's copy, so it silently does nothing for them. A bot that goes through the SDK works everywhere: our broker executes each order on the right account with that person's key, which never touches your code.

If you don't: your bot still runs fine on your account and builds its verified track record β€” but it will show as β€œNot yet available to rent” in your dashboard and no one can subscribe to it until you route execution through the SDK. Kalshi, OANDA, Tradier and other β€œplace the order yourself” bots especially need this change.

The only change you make

Keep all your strategy logic. Just route execution through vault:

import vault

ex = vault.ccxt()                 # drop-in ccxt-style client β€” no API keys needed
price = get_price("BTC/USDT")     # your own logic
if my_signal_is_buy:
    ex.create_order("BTC/USDT", "market", "buy", vault.size(price))   # sized to the runner's capital

Already using ccxt? Replace ccxt.binance({...keys...}) with vault.ccxt("binance") and delete your keys β€” your existing create_order(...) calls keep working. Always pass your venue to vault.ccxt(venue) (it defaults to coinbase) so orders route to the right exchange.

Prediction markets (Kalshi) & forex (OANDA)

The same SDK works for non-crypto venues β€” pass the venue and size in whole units. Pick the market in your own logic; the broker fills it on the correct account.

Kalshi β€” buy/sell whole contracts on a market ticker (price is dollars, 0.00–1.00, so int(vault.size(price)) sizes to capital automatically):

import vault
ex = vault.ccxt("kalshi")                    # route through the platform β€” no Kalshi key in your code
ticker = pick_market()                       # your logic β†’ a Kalshi market ticker (this picks the YES side)
price  = get_yes_price(ticker)               # 0.00–1.00 (dollars per contract)
count  = int(vault.size(price))              # whole contracts, sized to the runner's capital
if my_signal_is_buy and count > 0:
    ex.create_order(ticker, "market", "buy",  count)   # enter the position
    # ... later, to close:
    ex.create_order(ticker, "market", "sell", count)   # exit

Betting the NO side? Append |no to the ticker β€” e.g. ex.create_order(ticker + "|no", "market", "buy", count) β€” and the broker places the correct leg and records your fill at the NO price. A plain ticker always means YES. Use the same ticker + "|no" when you sell to close that position.

Forex (OANDA) β€” signed units; use a dashed pair (the broker converts EUR-USD β†’ EUR_USD). Your OANDA account id is the key you connect:

import vault
ex = vault.ccxt("oanda")
units = int(vault.size(rate))                # base-currency units, sized to capital (rate = the FX price)
if my_signal_is_buy and units > 0:
    ex.create_order("EUR-USD", "market", "buy",  units)   # long  (+units)
    ex.create_order("EUR-USD", "market", "sell", units)   # short / close (-units)

Replace your direct Kalshi/OANDA API calls with these β€” don't keep both. A bot that still calls the exchange directly with its own key can't trade for renters (their copy has no key), so it stays un-rentable. See What makes a bot rentable.

Paper mode works on every venue. In paper mode we fill your orders at live market prices from public data (Kalshi order books, stock & forex quotes) with an estimated-cost haircut β€” so you can run any bot risk-free and build a self-reported record before going live. Paper results are always labeled self-reported; only real execution is marked verified.

SDK reference

Supported venues: any major exchange (coinbase, binance, kraken, bybit, okx, kucoin, …). Pass the venue to vault.ccxt("binance").

🎯 Pick the venue your bot actually trades when you list it. Your listed exchange is authoritative β€” the broker routes every order to it and the buyer's connected key is locked to it, so a bot listed on Kraken always executes on Kraken even if a stray order is tagged otherwise. A buyer can only run your bot on the exchange you chose.
⚑ Auto-execution vs. signals-only by venue. Crypto exchanges (Coinbase, Kraken, Binance, OKX, … β€” 100+ via ccxt) support full hands-off auto-execution. Stocks, forex & prediction markets (Alpaca, OANDA, Tradier, Kalshi, Interactive Brokers) are verification & signals-only today: we read your real fills to verify the track record and the bot emits signals buyers place themselves β€” hands-off auto on those is rolling out.

Paper vs. live track record

When you list, you choose how your public record is built:

Either way the record is verified by our broker and can't be faked. Live simply carries more weight.

Packaging your bot

Starter template

import time, vault

MARKET, VENUE = "BTC-USD", "coinbase"
ex = vault.ccxt(VENUE)

def price():
    # your data/indicator logic here
    ...

while True:
    p = price()
    if buy_signal(p):
        ex.create_order(MARKET, "market", "buy",  vault.size(p, risk_pct=2))
    elif sell_signal(p):
        ex.create_order(MARKET, "market", "sell", vault.size(p, risk_pct=2))
    time.sleep(60)