Skip to main content

Contract Guide

This guide explains the core logic of BigONE's Contract API. Unlike Spot trading, Contract trading involves complex concepts like Leverage, Margin Modes, and Positions.

Prerequisites

  • Base URL: https://api.big.one/api/contract/v2
  • Authentication: Requires Bearer Token (JWT).
  • Data Types: Unlike Spot API, most numeric fields in Contract API (like price, size, leverage) are JSON Numbers (Integers or Floats), not Strings.

Lesson 1: Margin Modes & Leverage

Before opening a position, you must define how your collateral is used. This is configured per contract symbol (e.g., BTCUSD).

Endpoint: PUT /positions/{symbol}/margin

Concepts

  • isCross (Boolean):
    • true (Cross Margin): Uses your entire account balance to avoid liquidation. Risk is shared.
    • false (Isolated Margin): Risk is limited to the specific margin assigned to this position.
  • leverage (Number): The multiplier (e.g., 10, 100).
  • margin (Number): Used only in Isolated Mode to add/remove collateral. Set to 0 if just changing leverage.

Logic: Setting 20x Cross Leverage

You usually do this once before starting your strategy.

import requests
import json

BASE_URL = "https://api.big.one/api/contract/v2"
headers = {"Authorization": "Bearer YOUR_JWT", "Content-Type": "application/json"}

# Set BTCUSD to Cross Margin with 20x Leverage
payload = {
"isCross": True,
"leverage": 20,
"margin": 0
}

response = requests.put(f"{BASE_URL}/positions/BTCUSD/margin", json=payload, headers=headers)
print("Leverage Set:", response.json()['leverage'])

Lesson 2: Placing Orders

Contract orders have specific fields that don't exist in Spot trading.

Endpoint: POST /orders

Key Parameters

  • symbol: e.g., BTCUSD.
  • size (Integer): Number of contracts.
    • Inverse Contract (BTCUSD): 1 contract = 1 USD.
    • Linear Contract (BTCUSDT): 1 contract = Contract multiplier units of the base asset. Check instrument specs.
  • reduceOnly (Boolean):
    • true: This order ensures you are closing an existing position. If the order size exceeds your position, the system automatically resizes or cancels it. Always use this for Take Profit / Stop Loss.

Example: Open Long (Buy)

We want to open a long position of 100 contracts at $50,000.

payload = {
"symbol": "BTCUSD",
"side": "BUY", # Long
"type": "LIMIT",
"price": 50000, # Number!
"size": 100, # Number! (100 Contracts = $100 value for BTCUSD)
"reduceOnly": False
}

response = requests.post(f"{BASE_URL}/orders", json=payload, headers=headers)
order = response.json()
print(f"Order {order['id']} Status: {order['status']}")

Lesson 3: Closing Positions

To close a position, you simply place an order in the opposite direction.

The "Reduce-Only" Rule

To prevent accidentally flipping your position (e.g., selling too much and becoming Short when you meant to just Close Long), always set reduceOnly: true.

Logic: Close All Longs

  1. Check current position size.
  2. Place SELL order with reduceOnly: true.
# 1. Get Position
accounts = requests.get(f"{BASE_URL}/accounts", headers=headers).json()
# Find BTCUSD position inside the nested structure
# (Simplified for clarity - actual parsing depends on response structure)
# Assume we found: position_size = 100

# 2. Close It
close_payload = {
"symbol": "BTCUSD",
"side": "SELL", # Opposite of Long
"type": "MARKET", # Close immediately
"size": 100,
"reduceOnly": True # Safety flag
}

requests.post(f"{BASE_URL}/orders", json=close_payload, headers=headers)

Lesson 4: Position Data

Monitoring your PnL (Profit and Loss) and Liquidation Price is vital.

Endpoint: GET /accounts

This returns a complex structure containing cash (balances) and positions.

Key Fields in positions:

  • unrealizedPnl: Float profit/loss based on current Mark Price.
  • liquidatePrice: The price at which your position will be forcibly closed.
  • marginRate: If this approaches 100%, you are close to liquidation.
  • entryPrice: Your average cost basis.
// Example Position Object
{
"symbol": "BTCUSD",
"size": 100,
"entryPrice": 50000,
"markPrice": 51000,
"unrealizedPnl": 0.000039, // BTC amount
"liquidatePrice": 42000,
"leverage": 20
}

Complete Example

This script demonstrates the correct sequence: Set Leverage -> Open Position -> Place Stop Loss.

import requests
import time
import jwt

# --- Config ---
BASE_URL = "https://api.big.one/api/contract/v2"
API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
SYMBOL = "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_contract_bot():
print(f"--- Contract Bot: {SYMBOL} ---")

# 1. Set Leverage (Crucial Step)
print("1. Setting Leverage (5x Cross)...")
lev_payload = {"isCross": True, "leverage": 5, "margin": 0}
requests.put(f"{BASE_URL}/positions/{SYMBOL}/margin", json=lev_payload, headers=get_headers())

# 2. Place Market Long (Open Position)
print("2. Opening Long Position...")
# NOTE: Numbers, not Strings for Contract API
open_payload = {
"symbol": SYMBOL,
"side": "BUY", # Long
"type": "MARKET",
"size": 100, # 100 Contracts
"reduceOnly": False
}
res = requests.post(f"{BASE_URL}/orders", json=open_payload, headers=get_headers())

if res.status_code != 200:
print("Open Failed:", res.json())
return

order = res.json()
print(f" Open Order {order['id']} Status: {order['status']}")

# Wait for fill logic would go here... assume filled for demo
time.sleep(1)

# 3. Get Position Details
print("3. Checking Position...")
acct = requests.get(f"{BASE_URL}/accounts", headers=get_headers()).json()
# Find position (simplified parsing)
position = None
for a in acct:
for p in a.get('positions', []):
if p['symbol'] == SYMBOL:
position = p
break

if position and position['size'] > 0:
entry_price = position['entryPrice']
print(f" Long Size: {position['size']}, Entry: {entry_price}")

# 4. Place Stop Loss (Reduce Only)
# Stop at 2% below entry
stop_price = int(entry_price * 0.98)
print(f"4. Placing Stop Loss at {stop_price}...")

sl_payload = {
"symbol": SYMBOL,
"side": "SELL", # Opposite of Long
"type": "LIMIT", # Or STOP/MARKET depending on needs
"price": stop_price,
"size": position['size'], # Close full size
"reduceOnly": True # SAFETY: Ensure we don't open a Short
}
sl_res = requests.post(f"{BASE_URL}/orders", json=sl_payload, headers=get_headers())
print(f" SL Order Placed: {sl_res.json().get('id')}")

if __name__ == "__main__":
run_contract_bot()

Conclusion

Contract trading offers powerful tools for leverage and hedging, but requires strict attention to detail. Unlike the Spot API, the Contract API relies on JSON Numbers and explicit Margin Mode configuration.

Key Takeaways:

  • Data Types: Always send price, size, and leverage as Numbers (Integers/Floats).
  • Safety First: Configure your leverage and isCross mode before opening positions.
  • Closing: Use reduceOnly: true to safely close positions without accidentally opening new ones.

Next Steps:

  • Review the Contract API Reference for advanced order types like IOC and FOK.
  • Implement a WebSocket listener to monitor your Liquidation Price in real-time.