How to Place a 50% Market Close Long Order for Perpetual Contracts on OKX Using Python and the CCXT Module

·

Automating cryptocurrency trading through APIs has become essential for traders seeking precision, speed, and efficiency. One of the most popular tools for this purpose is the CCXT library, a powerful open-source Python module that supports over 100 exchanges — including OKX, one of the world’s leading crypto derivatives platforms.

This guide walks you through how to use the CCXT module in Python to programmatically close 50% of your long perpetual contract position on OKX using a market order. Whether you're building a risk management system or refining your trading bot logic, this step-by-step tutorial delivers practical code and best practices.


Understanding the Core Concepts

Before diving into the implementation, let's clarify key terms relevant to this operation:

Core Keywords

These keywords naturally align with user search intent around automated trading strategies on OKX using Python.


Step 1: Install and Configure CCXT

The first step is installing the CCXT library, which enables seamless interaction with OKX’s REST API.

pip install ccxt

Once installed, import the library and initialize the OKX exchange instance with your API credentials:

import ccxt

# Initialize OKX exchange
exchange = ccxt.okx({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET',
    'password': 'YOUR_PASSWORD',
    'enableRateLimit': True,
    'options': {
        'defaultType': 'swap',  # Use 'swap' for perpetual contracts
    },
})
🔐 Security Tip: Never hardcode credentials in production scripts. Use environment variables or secure vaults instead.

👉 Learn how to securely manage API keys and automate trades on OKX today.


Step 2: Fetch Your Current Position

To close 50% of a long position, you must first retrieve your current holdings. CCXT provides fetch_positions() to get all active positions.

def get_position(symbol):
    positions = exchange.fetch_positions([symbol])
    for pos in positions:
        if pos['symbol'] == symbol:
            return pos
    return None

# Example: ETH/USDT perpetual contract
symbol = 'ETH/USDT:USDT'
position = get_position(symbol)

if position:
    size = position['contracts']
    side = position['side']  # 'long' or 'short'
    print(f"Current position size: {size}, Side: {side}")
else:
    print("No position found.")

This function checks whether you're currently long and retrieves the total contract size.


Step 3: Calculate 50% of Position Size

After retrieving the position, calculate half of the current size:

if side == 'long' and size > 0:
    close_amount = size * 0.5  # Close 50%
    close_amount = exchange.amount_to_precision(symbol, close_amount)
    print(f"Closing {close_amount} contracts")
else:
    print("No long position to close.")

Using amount_to_precision() ensures the value adheres to OKX’s lot size rules.


Step 4: Execute Market Order to Close 50% Long

Now place a market order to sell half of your long position:

try:
    order = exchange.create_order(
        symbol=symbol,
        type='market',
        side='sell',
        amount=float(close_amount),
        params={'posSide': 'long'}  # Ensures it reduces long side
    )
    print("Order placed successfully:", order)
except Exception as e:
    print("Error placing order:", e)
⚠️ Note: On OKX, setting posSide in parameters ensures the order correctly offsets the long side in a one-way mode position.

Frequently Asked Questions (FAQ)

Q1: Can I use CCXT to trade other types of contracts on OKX?

Yes. CCXT supports spot, futures, and perpetual swaps on OKX. Just adjust the defaultType option:

'options': {'defaultType': 'future'}  # For futures
'options': {'defaultType': 'spot'}   # For spot trading

Q2: What does “posSide” mean in OKX API orders?

posSide defines the side of your position (long or short) in one-way mode. When closing part of a long position, specify 'posSide': 'long' so the sell order reduces only the long side.

Q3: How can I avoid accidental full liquidation when closing positions?

Always validate the order amount before submission. You can simulate with small sizes first and double-check:

👉 Discover advanced position management tools and practice safe automated trading on OKX.

Q4: Does CCXT support testnet or sandbox environments for OKX?

Yes. You can enable OKX’s demo trading by setting the testnet URL:

exchange.urls['api'] = 'https://www.okx.com/join/8265080api/v5'
# Or switch to demo:
# exchange.urls['api'] = 'https://testnet.okx.com/api/v5'

Refer to OKX’s official documentation for testnet access.

Q5: How often should I check my position status?

For live bots, use rate-limited polling every 5–10 seconds. Avoid excessive requests to stay within API limits. Consider using WebSocket feeds via CCXT Pro for real-time updates (paid extension).

Q6: Is it safe to run automated scripts with market orders?

Market orders guarantee execution but not price. During high volatility, slippage may occur. Use limit orders if price control is critical, or implement slippage checks before market execution.


Best Practices for Robust Trading Scripts

  1. Error Handling: Wrap all API calls in try-except blocks.
  2. Logging: Record trades, errors, and balance changes for audit trails.
  3. Rate Limiting: Enable enableRateLimit: True to avoid bans.
  4. Position Validation: Always confirm direction (long/short) before closing.
  5. Dry Runs: Test logic with minimal funds or in demo mode.

Final Code Example: Complete Script

Here’s a complete script integrating all steps:

import ccxt

exchange = ccxt.okx({
    'apiKey': 'YOUR_KEY',
    'secret': 'YOUR_SECRET',
    'password': 'YOUR_PASS',
    'enableRateLimit': True,
    'options': {'defaultType': 'swap'},
})

symbol = 'ETH/USDT:USDT'

def close_50_percent_long():
    position = exchange.fetch_positions([symbol])[0]
    
    if not position or not position['side'] == 'long':
        print("No long position to close.")
        return
    
    size = position['contracts']
    close_amount = exchange.amount_to_precision(symbol, size * 0.5)
    
    try:
        order = exchange.create_order(
            symbol=symbol,
            type='market',
            side='sell',
            amount=float(close_amount),
            params={'posSide': 'long'}
        )
        print("Successfully closed 50%:", order['id'])
    except Exception as e:
        print("Failed to close:", e)

close_50_percent_long()

Conclusion

Using Python with CCXT, you can efficiently manage your OKX perpetual contract positions, including partial closures like selling 50% of a long at market price. This approach empowers traders to build responsive, rule-based systems for profit-taking, risk reduction, or portfolio rebalancing.

Automation brings power — and responsibility. Always test strategies thoroughly and monitor performance closely.

👉 Start building smarter trading workflows with real-time data and secure API access on OKX.