Setup Guide

Most users are up and running in dry-run mode within 10–20 minutes.

📄 Pro & Lifetime customers: check your purchase email for the full PDF guide with screenshots and troubleshooting.

Quick Start

Three steps. You need Docker and credentials from your exchange.

01 // GET

Unzip and log in to the registry

Your purchase email contains registry credentials (REGISTRY_USER, REGISTRY_PASSWORD) and your license key. Keep these private.

docker login registry.gitlab.com \
  -u YOUR_REGISTRY_USER \
  -p YOUR_REGISTRY_PASSWORD
02 // CONFIGURE

Create your .env file

Copy .env.example to .env and fill in at minimum the fields marked required below. Start with DRY_RUN=True.

cp .env.example .env
nano .env   # or any editor
03 // RUN

Start the bot

docker compose up -d
docker compose logs -f   # watch startup

The web dashboard is available at http://localhost:8080 (or your configured DASHBOARD_PORT).

Exchange API Keys

Bybit

Go to Account → API Management on bybit.com. Create a new key with these permissions:

For initial testing: use Bybit Testnet (testnet.bybit.com) with BYBIT_TESTNET=True. Testnet uses virtual funds — no real capital at risk.

Bitunix

Go to API Management on bitunix.com. Bitunix has no testnet — start with a small capital amount and DRY_RUN=True first.

Bitunix uses separate Spot and Futures wallets. Transfer USDT to both wallets before starting the bot (roughly 2/3 Spot, 1/3 Futures at 2× leverage).

Bitget

Go to Profile → API Management on bitget.com. Enable the same permissions as above. Bitget also requires a passphrase set at key creation time — add it as BITGET_PASSPHRASE in your .env.

The bot auto-detects your account's futures position mode (hedge or one-way) and composes orders accordingly — no manual setting required.

⚠ Never enable Withdrawal permissions on trading API keys. The bot only needs to read balances and place/cancel orders.

Configuration Reference

All settings live in your .env file. The defaults are conservative for a first run.

Essential — set before first run

VariableDefaultDescription
LICENSE_KEYrequiredYour license key from the purchase email. Required when DRY_RUN=False.
REGISTRY_USERrequiredDocker registry username from purchase email.
REGISTRY_PASSWORDrequiredDocker registry password from purchase email.
EXCHANGEbybitActive exchange: bybit, bitunix, bitget, or any CCXT exchange id (e.g. binanceusdm).
BITGET_PASSPHRASEoptionalRequired when EXCHANGE=bitget. Set at Bitget API key creation time.
BYBIT_API_KEYrequiredBybit API key (or Testnet key).
BYBIT_API_SECRETrequiredBybit API secret.
BYBIT_TESTNETTrueSet False for live trading on mainnet.
DRY_RUNTrueAlways start with True. No real orders are placed. Switch to False only after verifying dry-run logs.
DASHBOARD_PORT8080Port for the web dashboard.

Trading parameters

VariableDefaultDescription
TRADE_CAPITAL_USDT500Capital per position in USDT (spot leg size).
MAX_TOTAL_CAPITAL1000Total capital cap across all open positions.
MAX_POSITIONS2Maximum simultaneous open positions.
FUTURES_LEVERAGE2Leverage for the futures short leg (isolated margin). Keep at 2 unless you understand the liquidation mechanics.
FUNDING_ENTRY_THRESHOLD0.00025Minimum funding rate to open a position (0.00025 = 0.025% per 8h). Funding rates fluctuate — this is an entry filter, not a yield forecast.
FUNDING_EXIT_THRESHOLD0.000001Close position when rate falls below this.
EXIT_CONFIRMATION_TICKS60Consecutive ticks below exit threshold before closing. At 60s interval = 60 minutes — prevents exits on short dips.
MIN_VOLUME_USDT_24H5000000Minimum 24h futures volume to consider a symbol. Filters illiquid coins.
FEE_COVERAGE_FACTOR1.5Only enter if expected funding income ≥ round-trip fees × this factor. Reduces the likelihood of fee-losing entries in marginal conditions.

Advanced — safe to leave at defaults

VariableDefaultDescription
MARGIN_USAGE_MAX0.70Maximum fraction of USDT balance used for margin. Keeps a buffer against liquidation.
MONITOR_INTERVAL_SEC60How often the bot checks rates and positions (seconds).
POST_FUNDING_COOLDOWN_MIN30Minutes of no new entries after the 8h funding reset (rates are volatile right after).
MIN_MINUTES_BEFORE_FUNDING10Don't open a new position within N minutes of the next funding payment.
HOLD_FOR_PAYMENT_MIN60Suppress rate-based exits when a payment is due within N minutes.
SPOT_LIMIT_OFFSET0.0005Spot limit order price = mark × (1 − this). Targets maker fee.
SPOT_LIMIT_TIMEOUT_SEC30Cancel spot limit order after N seconds if unfilled.
HEDGE_REBALANCE_ENABLEDTrueAuto-correct small spot/futures imbalances caused by lot sizes or partial fills.

Dry-Run Verification

With DRY_RUN=True, the bot scans for opportunities and logs everything — but places no real orders. This is what healthy startup logs look like:

INFO License valid — plan=pro expires=2028-05-19 id=your_id
INFO Exchange: bybit | DRY_RUN=True
INFO Scanner started — interval 60s
INFO BTCUSDT rate=0.00041 vol=2.1B → ENTRY CANDIDATE
INFO [DRY] Would open spot long + futures short on BTCUSDT @ 500 USDT
INFO ETHUSDT rate=0.00031 vol=890M → ENTRY CANDIDATE
INFO [DRY] Would open spot long + futures short on ETHUSDT @ 500 USDT

If you see [DRY] lines with entry candidates, the bot is working correctly. If the scanner finds no candidates, rates are currently below your FUNDING_ENTRY_THRESHOLD — this is normal in calm markets.

✓ Let the bot run in dry-run for at least one full 8-hour funding cycle (funding payments happen at 00:00, 08:00, 16:00 UTC) before going live.

Going Live

Before switching DRY_RUN=False, work through this checklist:

Then:

# In your .env:
DRY_RUN=False
BYBIT_TESTNET=False

# Restart the bot:
docker compose down
docker compose up -d
docker compose logs -f

⚠ Start with a small TRADE_CAPITAL_USDT (e.g. 100–200 USDT) for your first live run. Scale up after confirming the first real positions open and close correctly.

VPS Deployment

Running the bot on your personal computer works, but it stops when your machine sleeps or reboots — leaving open positions unmonitored. A VPS keeps the bot running 24/7.

Recommended providers

ProviderPlanRAMCost
HetznerCX224 GB~€5/mo
Hostinger1CPU4 GB~€6/mo
DigitalOceanBasic Droplet2 GB~$6/mo
VultrCloud Compute2 GB~$6/mo

Ubuntu 22.04. Install Docker with curl -fsSL https://get.docker.com | sh, then follow the Quick Start steps above. Add restart: unless-stopped to both services in docker-compose.yml so the bot restarts automatically after reboots.

Dashboard access from a VPS

Use an SSH tunnel to access the dashboard without opening a public port:

ssh -L 8080:localhost:8080 user@YOUR_SERVER_IP

Then open http://localhost:8080 in your browser. The tunnel stays active while the SSH session is open.

✓ Pro & Lifetime customers: the full setup guide PDF includes a step-by-step VPS walkthrough with server hardening, non-root user setup, and firewall configuration.

Risk Disclosure

This is not financial advice. FundingArb is a software tool — not an investment product. No returns are promised or implied. You are solely responsible for your trading decisions and any resulting gains or losses.

Understand the following risks before running with real capital:

Only trade with capital you can afford to lose entirely.

FAQ

Why is my bot running but not opening any positions?

Two common causes:

1. Funding rates are below your threshold. The bot only enters when the current rate exceeds FUNDING_ENTRY_THRESHOLD. In sideways or bearish markets, rates can stay low for days — this is normal. Open the Scanner tab in the dashboard to see live rates. If rates are visible, the bot is working correctly.

2. Your configured capital exceeds your usable balance. The bot keeps an internal safety buffer and only deploys approximately 70% of your available balance. Rule of thumb:

Your actual exchange balance should be at least 1.4× your TRADE_CAPITAL_USDT setting. Example: for TRADE_CAPITAL_USDT=100, keep at least 140 USDT available in the trading wallet.

If this is the issue, logs will contain insufficient capital. Fix: deposit more USDT, or reduce TRADE_CAPITAL_USDT to ~70% of your current balance.

Will exchanges ban me for running this bot?

Funding arbitrage is a legitimate, widely-used strategy. Exchanges benefit from arbitrageurs because they provide liquidity to the futures market. There is no known case of an account being banned specifically for funding arbitrage. Use a dedicated API key with minimum required permissions and do not mix bot trading with manual trading on the same key.

Is my API key visible to anyone other than me?

No. FundingArb is self-hosted — your .env file never leaves your machine or server. The bot communicates directly with your exchange. There is no FundingArb server that handles your credentials or touches your funds. License validation runs fully offline (local signature check) — your bot never talks to a license server at all.

Can I run the bot on multiple machines?

No. Running the same license key on multiple instances simultaneously causes conflicts — both instances would attempt to manage the same positions independently. One instance per license.

Support

Pro & Lifetime customers: Email support is included. Response target: 48 hours.
Contact:

Starter customers: Community support only. Check the log output — the bot logs the reason for every decision (entry skipped, exit triggered, etc.).

Common issues to check first:

Affiliate disclosure: Some links below are referral links. If you sign up through them, FundingArb earns a small commission at no extra cost to you. We only list services we actually use and recommend. You are free to sign up directly instead.

Exchanges

VPS Providers