How can I do derivatives trading with the Jupyter Notebook?

Published on Sep 28, 2023Updated on Oct 25, 20249 min read78

Find out how you can do simple derivatives trading with the same tools. Let's use the comprehensive features available in python-okx at a higher level!

Derivatives Types

There are three types of derivatives available for trading on OKX:

  • Expiry

  • Perpetual

  • Options

You can head over to Bitcoin derivatives, explained: Expiry, perpetual and options to learn about the characteristics of different types of derivatives on OKX. In this tutorial, we'll use Perpetual as an example.

FAQ

1. How can I get the market data from Get market data?

You can also replace instType with EXPIRY or OPTION for your information.

Python
     import okx.MarketData as MarketData

   flag = "1"  # live trading: 0, demo trading: 1

   marketDataAPI = MarketData.MarketAPI(flag = flag)

   result = marketDataAPI.get_tickers(instType = "SWAP")
   print(result)

2. How can I get available trading pairs from Get instruments?

As in the same manner, choose the instType that you'd like to get information for.

Python
import okx.PublicData as PublicData

if __name__ == '__main__':

    flag = "1"  # live trading: 0, demo trading: 1

    publicDataAPI = PublicData.PublicAPI(flag = flag)

    result = publicDataAPI.get_instruments(instType = "SWAP")
    print(result)

2.1 Calculate the notional value of a derivative contract with the instrument parameter ctVal and ctMult

To calculate the notional value of a derivative contract (i.e. future, perpetual swaps and options), you need ctVal (contract value) and ctMult (contract multiplier) from the instrument parameters.

The notional value of a derivative contract can be calculated as ctVal * ctMult (unit: ctValCcy);

For example, from the instrument parameters shown below, we can calculate the notional value of an LTC-USD perpetual contract as: ctVal * ctMult (unit:ctValccy) = 10 * 1 USD = 10 USD

JSON
        "instType":"SWAP",
        "instId":"LTC-USD-SWAP",
        "instFamily":"LTC-USD",
        "uly":"LTC-USD",
        "settleCcy":"LTC",
        "ctVal":"10",
        "ctMult":"1",
        "ctValCcy":"USD"

3. How can I check your balance from Get balance?

Python
import okx.Account as Account
flag = "1"  # live trading:0, demo trading: 1

accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)

result = accountAPI.get_account_balance()
print(result)

4. What's an account mode and margin/trade mode that is eligible to trade derivatives?

As mentioned in our last tutorial, in unified account, there are four account modes as we mentioned in the last tutorial:

  • Spot mode,

  • Spot and futures mode,

  • Multi-currency margin mode,

  • Portfolio margin mode.

Note that only the last three margin modes, namely, spot and futures, multi-currency margin and portfolio margin, are eligible for derivatives trading. Please refer to how to set up the account mode to understand the differences between the four modes and how to switch between them through our Web UI.

4.1 Get the current account configuration from the acctLv parameter in Get account configuration

Make sure that you're in the correct account mode to trade derivatives.

Python
import okx.Account as Account

flag = "1"  # live trading: 0, demo trading: 1

accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)
result = accountAPI.get_account_config()
print(result)

if result['code'] == "0":
    acctLv = result["data"][0]["acctLv"]
    if acctLv == "1":
        print("Simple mode")
    elif acctLv == "2":
        print("Single-currency margin mode")
    elif acctLv == "3":
        print("Multi-currency margin mode")
    elif acctLv == "4":
        print("Portfolio margin mode")

5. How can I set leverage via Set account leverage?

One important parameter we need to set when trading derivatives is leverage.

Leverage allows traders to enter a position which is worth much more by committing only a small amount of money. The gains or losses are therefore greatly magnified.

Traders can have as much as 125x leverage when trading derivatives on OKX. You can read references of setting leverage for different levels of leverage allowed under different tiers of positions.

CT-web-derivativestrading-howtoapi-6

Here are what what the glossaries shown above mean:

  • Max. Leverage: The maximum times multiple of borrowed capital to increase the potential return of an investment.

  • Initial margin ratio (IMR): Margin required for holding current positions.

  • Maintenance margin ratio (MMR): Minimum margin required to maintain current positions. Liquidation will occur if the account equity drops below the maintenance margin.

For example, when you want to trade 3000 ETHUSDT perpetual contracts, you can leverage a maximum of 75 times the capital you own. IMR = 1 / 75 = 1.3%, and you must maintain 0.8% MMR or above to avoid liquidation.

There are 9 different scenarios for leverage settings via OKX open APIs. Please refer to Set leverage scenarios for different cases.

For perpetual swaps, there are 3 different scenarios for leverage setting:

  • Set leverage for SWAP instruments under cross-margin trade at contract level.

  • Set leverage for SWAP instruments under isolated-margin trade mode and buy/sell position mode at contract level.

  • Set leverage for SWAP instruments under isolated-margin trade mode and long/short position mode at contract and position side level.

The following example shows how to set leverage for a single SWAP contract and position side, as compared to across all the SWAP contracts for a certain underlying.

Bash
# Set leverage to be 5x for all cross-margin BTC-USDT SWAP positions,
# by providing the SWAP instId
result = accountAPI.set_leverage(
    instId = "BTC-USDT-SWAP",
    lever = "5",
    mgnMode = "cross"
)
print(result)

# In buy/sell position mode, set leverage to be 5x 
# for all isolated-margin BTC-USDT SWAP positions
# by providing the SWAP instId
result = accountAPI.set_leverage(
    instId = "BTC-USDT-SWAP",
    lever = "5",
    mgnMode = "isolated"
)
print(result)

# In long/short position mode, set leverage to be 5x
# for an isolated-margin BTC-USDT-SWAP long position;
# This does NOT affect the leverage of the BTC-USDT-SWAP
# short positions
result = accountAPI.set_leverage(
    instId = "BTC-USDT-SWAP",
    lever = "5",
    posSide = "long",
    mgnMode = "isolated"
)
print(result)

Note that the request parameter posSide is only required when margin mode is isolated in long/short position (order placement) mode for EXPIRY/PERPETUAL instruments (see scenario 6 and 9 in Set leverage scenarios).

6. How can I place orders under different position (order placement) modes: long/short and buy/sell?

There are two position (order placement) modes when trading EXPIRY and PERPETUAL: long/short and buy/sell (net).

You can change the position (order placement) mode between long/short and buy/sell (net), via the API Set position mode:

SQL
result = accountAPI.set_position_mode(
    posMode = "long_short_mode"
)
print(result)

Or alternatively, you can do it via Settings on the web as below:

CT-web-derivativestrading-howtoapi-9

In buy/sell (net) mode, the position of a certain contract is the net quantity of your buy and sell trades. When you place orders via Place order, the request parameter posSide is not mandatory. If you pass it through, the only valid value is net.

In long/short mode, Long and short positions of a certain contract will be independent from each other and need to be closed separately. When you place orders via Place order, the request parameter posSide is mandatory. Valid values are long or short. Showing below is how to set the parameter side (side of the trade) and posSide (side of the position) when you place an order under different scenarios:

  • Place a buy order and open/increase a long position: side = buy, posSide = long

  • Place a sell order and open/increase a short position: side = sell, posSide = short

  • Place a sell order and close/reduce a long position: side = sell, posSide = long

  • Place a buy order and close/reduce a short position: side = buy, posSide = short Then you're all set to place derivatives orders!

6.1 Place a limit order via Place order

Buying 100 BTC-USDT Swap contract at the price of 19000 USDT.

SQL
# limit order
result = tradeAPI.place_order(
    instId = "BTC-USDT-SWAP",
    tdMode = "isolated",
    side = "buy",
    posSide = "net",
    ordType = "limit",
    px = "19000",
    sz = "100"
)
print(result)

if result["code"] == "0":
    print("Successful order request,order_id = ",result["data"][0]["ordId"])
else:
    print("Unsuccessful order request,error_code = ",result["data"][0]["sCode"], ", Error_message = ", result["data"][0]["sMsg"])

6.2 Place a market order via Place order

Buying 100 BTC-USDT Swap contract at market price.

SQL
# market order
result = tradeAPI.place_order(
    instId = "BTC-USDT-SWAP",
    tdMode = "isolated",
    side = "buy",
    posSide = "net",
    ordType = "market",
    sz = "100"
)
print(result)

if result["code"] == "0":
    print("Successful order request,order_id = ",result["data"][0]["ordId"])
else:
    print("Unsuccessful order request,error_code = ",result["data"][0]["sCode"], ", Error_message = ", result["data"][0]["sMsg"])

7. How can I get details/state of a certain order (refer to Get order details)?

Other than ordId, you can also specify clOrdId to get order details.

SQL
result = tradeAPI.get_order(instId="BTC-USDT-SWAP", ordId="505073046126960640")
print(result)

8. How can I cancel an order via Cancel order?

Perl
You also use __clOrdId__ in place of __ordId__
result = tradeAPI.cancel_order(instId="BTC-USDT-SWAP", ordId="505073046126960640")
print(result)

9. How can I amend an order via Amend order?

You also use clOrdId in place of ordId. This example shows the revision of a new size.

SQL
result = tradeAPI.amend_order(
    instId = "BTC-USDT-SWAP", 
    ordId = "505073046126960640",
    newSz = "80"
)
print(result)

10. How can I get the list of open orders via Get order List?

SQL
result = tradeAPI.get_order_list()
print(result)

11. How can I get order history via Get order history (last 7 days) and Get order history (last 3 months)?

SQL
# Get order history (last 7 days)
result = tradeAPI.get_orders_history(
    instType = "SWAP"
)
print(result)

# Get order history (last 3 months)
result = tradeAPI.get_orders_history_archive(
    instType = "SWAP"
)
print(result)

12. How can I get transaction details via Get transaction details (last 3 days) and Get transaction details (last 3 months)?

SQL
# Get transaction details (last 3 days)
result = tradeAPI.get_fills()
print(result)

# Get transaction details (last 3 months)
result = tradeAPI.get_fills_history(
    instType = "SWAP"
)
print(result)

13. How can I get positions via Get positions?

When your account is in net mode, the net position of each contract will be displayed; when your account is in long/short mode, the long or short position of each contract will be displayed separately.

SQL
result = accountAPI.get_positions()
print(result)

For example, you can track your unrealized profit and loss through the response parameter upl.

More examples

For more examples, please download the full Jupyter Notebook here.

If you have any questions about our APIs, you can join our API community and raise them in the community.