Cross-Market Integration Guide
This guide demonstrates how to build a complex trading application that coordinates actions between BigONE's Spot and Contract APIs.
We use a standard Cash and Carry Arbitrage scenario as our case study. This scenario is perfect for learning because it requires:
- Data Synchronization: Fetching and comparing prices from two different market systems.
- Type Handling: Managing the strict String requirements of Spot vs the Number requirements of Contract.
- Atomic-like Execution: Executing orders on two different engines simultaneously.
Note: This guide focuses on the technical implementation of API integration. It is not financial advice.
The Integration Logic
To successfully bridge the Spot and Contract markets, your application must handle the distinct behaviors of each API:
- Spot API: Uses Strings for precision. Accounts are separate.
- Contract API: Uses Numbers. Requires "Inverse" calculation logic.
- Coordination: You must calculate the "Basis" (Price Difference) to decide when to trigger the workflow.
Lesson 1: The Setup (Data & Calculation)
To execute this correctly, you must compare the Spot Price and the Contract Mark Price.
- Spot API:
GET https://api.big.one/api/v3/asset_pairs/{pair}/ticker - Contract API:
GET https://api.big.one/api/contract/v2/instruments
Fetching Data
import requests
# 1. Get Spot Price (BTC-USDT)
spot_res = requests.get("https://api.big.one/api/v3/asset_pairs/BTC-USDT/ticker")
spot_price = float(spot_res.json()['price'])
# 2. Get Contract Data (BTCUSD - Inverse Perpetual)
contract_res = requests.get("https://api.big.one/api/contract/v2/instruments")
instruments = contract_res.json()
target_contract = next(i for i in instruments if i['symbol'] == 'BTCUSD')
mark_price = target_contract['markPrice']
funding_rate = target_contract['fundingRate']
print(f"Spot: ${spot_price}, Contract: ${mark_price}")
print(f"Current Funding Rate: {funding_rate * 100}%")
Lesson 2: Position Sizing (The Math)
CRITICAL: This is where most developers fail. You must calculate the correct short size based on the contract type.
Scenario: BTCUSD (Inverse Contract)
- Type: Coin-Margined (Inverse).
- Unit: 1 Contract = 1 USD.
- Goal: Hedge 1 BTC.
Formula:
Contract Size (Contracts) = BTC Amount × BTC Price
Example:
- You hold 0.5 BTC.
- Price is $50,000.
- Value = $25,000.
- You must Short 25,000 Contracts.
Code Implementation
def calculate_hedge_size(btc_amount, price):
# For Inverse BTCUSD (1 Cont = 1 USD)
contract_size = int(btc_amount * price)
return contract_size
# Example
amount_to_hedge = 0.5 # BTC
execution_price = 50000
contracts_to_short = calculate_hedge_size(amount_to_hedge, execution_price)
print(f"To hedge {amount_to_hedge} BTC, Short {contracts_to_short} Contracts.")
# Output: Short 25000 Contracts
Lesson 3: Execution (The Hedge)
Now we execute the two legs. Note the difference in API Payload formats.
Step 1: Buy Spot (Long Leg)
- API: Spot V3
- Data Type: String (Strict precision).
# Spot Payload (Buy 0.5 BTC)
spot_payload = {
"asset_pair_name": "BTC-USDT",
"side": "BID",
"type": "MARKET",
"amount": "0.5" # String!
}
# requests.post(..., json=spot_payload)
Step 2: Short Contract (Short Leg)
- API: Contract V2
- Data Type: Number (Standard JSON numbers).
- Action: Transfer BTC to Contract Account first!
# Contract Payload (Short 25,000 Contracts)
contract_payload = {
"symbol": "BTCUSD",
"side": "SELL", # Shorting
"type": "MARKET",
"size": 25000, # Integer/Number!
"reduceOnly": False
}
# requests.post(..., json=contract_payload)
Notice that Spot API requires amount as a String ("0.5"), while Contract API accepts size as a Number (25000). Mixing these up is a common source of errors.
Lesson 4: Maintenance & Risks
Arbitrage is low risk, not zero risk.
1. Liquidation Risk
Even though you are hedged, your Contract position has a Liquidation Price.
- Inverse Contract: If Price Rises, your Short position loses BTC.
- Risk: If you run out of BTC margin, you get liquidated before you can sell your Spot BTC to cover.
- Solution: Keep leverage low (e.g., 1x or 2x). Do not use 100x leverage for arbitrage.
2. Funding Reversal
- If the Funding Rate turns negative, Shorts pay Longs. You will start losing money.
- Action: Monitor
fundingRate. If it stays negative, close both positions (Sell Spot, Buy-to-Cover Contract).
3. Rebalancing
- As price changes, your hedge ratio might drift slightly due to the non-linear nature of inverse contracts vs linear spot assets (though 1x hedge is usually stable).
- Periodically recalculate
Value = Amount * Priceand adjust the contract size.
Complete Example
This script calculates the correct hedge ratio and executes a Cash and Carry trade (Long Spot + Short Contract).
import requests
import time
import jwt
# --- Config ---
SPOT_BASE = "https://api.big.one/api/v3"
CONTRACT_BASE = "https://api.big.one/api/contract/v2"
API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
# TARGET: Hedge 0.01 BTC
TARGET_BTC = 0.01
SPOT_PAIR = "BTC-USDT"
CONTRACT_SYM = "BTCUSD"
def get_headers():
token = jwt.encode({
"sub": API_KEY,
"nonce": int(time.time() * 1000000),
"iat": int(time.time()),
"exp": int(time.time()) + 60
}, SECRET_KEY, algorithm="HS256")
return {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
def run_arbitrage():
print("--- Starting Arbitrage Execution ---")
# 1. Fetch Prices
print("1. Fetching Market Data...")
spot_ticker = requests.get(f"{SPOT_BASE}/asset_pairs/{SPOT_PAIR}/ticker").json()
spot_price = float(spot_ticker['price'])
contract_inst = requests.get(f"{CONTRACT_BASE}/instruments").json()
contract = next(i for i in contract_inst if i['symbol'] == CONTRACT_SYM)
mark_price = contract['markPrice']
basis = (mark_price - spot_price) / spot_price
print(f" Spot: {spot_price}, Mark: {mark_price}, Basis: {basis*100:.2f}%")
# 2. Calculate Sizes
# Spot: String, exact amount
spot_qty_str = f"{TARGET_BTC:.6f}"
# Contract (Inverse): Size = BTC * Price
# Hedge Value = 0.01 BTC * $50000 = $500 = 500 Contracts
contract_qty_int = int(TARGET_BTC * mark_price)
print(f"2. Calculation:")
print(f" Spot Leg: Buy {spot_qty_str} BTC")
print(f" Contract Leg: Short {contract_qty_int} Contracts")
# 3. Execution (Simultaneous-ish)
print("3. Executing...")
# Leg A: Buy Spot
spot_payload = {
"asset_pair_name": SPOT_PAIR,
"side": "BID",
"type": "MARKET",
"amount": spot_qty_str # String!
}
spot_res = requests.post(f"{SPOT_BASE}/viewer/orders", json=spot_payload, headers=get_headers())
print(f" Spot Order: {spot_res.status_code}")
# Leg B: Short Contract
contract_payload = {
"symbol": CONTRACT_SYM,
"side": "SELL", # Short
"type": "MARKET",
"size": contract_qty_int, # Integer!
"reduceOnly": False
}
cont_res = requests.post(f"{CONTRACT_BASE}/orders", json=contract_payload, headers=get_headers())
print(f" Contract Order: {cont_res.status_code}")
# In production, check for partial fills and adjust!
if __name__ == "__main__":
run_arbitrage()
Conclusion
The Cash and Carry arbitrage strategy is a classic low-risk method to earn yield from crypto markets. Success depends on precise execution and understanding the mechanics of Inverse Contracts.
Key Takeaways:
- Math Matters: For Inverse Contracts (like BTCUSD),
Position Size = BTC Amount * Price. - API Differences: Remember that Spot API expects Strings, while Contract API expects Numbers.
- Monitoring: Keep an eye on the Funding Rate. If it turns negative for an extended period, the strategy may lose profitability.
Next Steps:
- Automate the "rebalancing" logic to adjust your hedge as the asset price changes.
- Explore Spot-Contract Arbitrage with Linear Contracts (USDT-margined) for simpler calculations (
1 BTC = 1 Contract).