Market Ask Order Tutorial
This tutorial shows how to create a market sell order for digital assets that a user already holds, using the Upbit API.
The full code examples can be found in the Recipes menu.
Click the button above to navigate to the full code Recipe page of this tutorial.
Get Started
The typical steps an Upbit user follows when selling digital assets are as follows:
- Select the digital asset to sell from the user’s holdings.
- Check the tradability information of the selected digital asset to confirm the order conditions.
- Enter the quantity and place a market sell order.
- The order is executed.
- Verify the executed order.
In this guide, you will implement a scenario where the user retrieves their holdings and sells 50% of the selected digital asset at market price. Python example code is provided.
- Singapore (sg): https://sg-api.upbit.com
- Indonesia (id): https://id-api.upbit.com
- Thailand (th): https://th-api.upbit.com
Authentication Guide
Please refer to the Authentication document and the recipe below to add the authentication header for all Exchange API calls.
Check Owned Assets and Select Assets to Sell
Implement a function that calls Get Balances held in the user's Upbit account.
def get_pair_and_balance_from_account(currency: str) -> Mapping:
jwt_token = _create_jwt(access_key, secret_key)
url = "https://sg-api.upbit.com/v1/accounts"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers).json()
trading_pair_list = [item for item in response if item.get("currency") == currency]
if len(trading_pair_list) == 0:
raise ValueError("Currency {currency} is not found".format(currency=currency))
else:
pair = trading_pair_list[0]
return {
"pair": "{unit_currency}-{currency}".format(unit_currency=pair.get('unit_currency'), currency=pair.get('currency')),
"balance": pair.get('balance')
}
When the function runs, it retrieves information about all assets in the user’s Upbit account.
If the user holds an asset matching the input currency
, the function returns its trading pair and available quantity.
[
{
"currency": "SGD",
"balance": "1000000.0",
"locked": "0.0",
"avg_buy_price": "0",
"avg_buy_price_modified": false,
"unit_currency": "SGD"
},
{
"currency": "BTC",
"balance": "2.0",
"locked": "0.0",
"avg_buy_price": "101000",
"avg_buy_price_modified": false,
"unit_currency": "SGD"
}
]
Check Order Chance
Implement a function that calls the Get Available Order Information API to check whether the selected digital asset can be traded and to retrieve the order conditions required for creating a market sell order..
def get_order_chance(trading_pair: str) -> Mapping:
params = {
"market": trading_pair
}
query_string = _build_query_string(params)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/orders/chance"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers, params=params).json()
min_total = response.get("market").get("ask").get("min_total")
ask_types = response.get("market").get("ask_types")
if "market" not in ask_types:
raise ValueError("This pair does not support market order. {ask_types}".format(ask_types=ask_types))
else:
order_type_market = True
return {
"order_type_market": order_type_market,
"min_total": min_total
}
When the function is executed, the order availability information for the user-input pair can be checked.
{
"bid_fee": "0.0025",
"ask_fee": "0.0025",
"maker_bid_fee": "0.0025",
"maker_ask_fee": "0.0025",
"market": {
"id": "SGD-BTC",
"name": "BTC/SGD",
"order_types": [
"limit"
],
"order_sides": [
"ask",
"bid"
],
"bid_types": [
"best_fok",
"best_ioc",
"limit",
"limit_fok",
"limit_ioc",
"price"
],
"ask_types": [
"best_fok",
"best_ioc",
"limit",
"limit_fok",
"limit_ioc",
"market"
],
"bid": {
"currency": "SGD",
"min_total": "1"
},
"ask": {
"currency": "BTC",
"min_total": "1"
},
"max_total": "1000000",
"state": "active"
},
"bid_account": {
"currency": "SGD",
"balance": "0",
"locked": "0",
"avg_buy_price": "0",
"avg_buy_price_modified": true,
"unit_currency": "SGD"
},
"ask_account": {
"currency": "BTC",
"balance": "0",
"locked": "0",
"avg_buy_price": "0",
"avg_buy_price_modified": false,
"unit_currency": "SGD"
}
}
Create Order
To create a market sell order for a digital asset at the current price, the following values are required:
- The trading pair of the digital asset to sell (e.g., SGD-BTC)
- Order side (buy or sell)
- Order type (limit, market, etc.)
- Quantity of the digital asset to sell
This tutorial creates a market sell order, so the order side and order type are predefined. Therefore, you can calculate the pair and quantity of the digital asset to sell and create a market sell order.
Implement a function that creates a market sell order. This function calls the Create Order API and returns the UUID of the newly created order.
def create_order(
market: str,
volume: str
) -> str:
body = {
"market": market,
"side": "ask",
"ord_type": "market",
"volume": volume
}
query_string = _build_query_string(body)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/orders"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.post(url, headers=headers, json=body).json()
uuid = response.get('uuid')
if uuid is None:
raise ValueError("Please check the response. {response}".format(response=response))
else:
return uuid
Check Order Status
Implement a function that calls the Get Order API to check the current status of an order using the UUID returned at the time of creation..
def get_order(uuid: str) -> Mapping:
params = {
"uuid": uuid
}
query_string = _build_query_string(params)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/order"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers, params=params).json()
return response
When executed, the function returns the order details matching the UUID provided by the user.
You can check the current status of the order through the state
field, such as whether it is waiting or done.
{
"market": "SGD-BTC",
"uuid": "9ca023a5-851b-4fec-9f0a-48cd83c2eaae",
"side": "ask",
"ord_type": "limit",
"price": "153559.00",
"state": "done",
"created_at": "2025-07-04T15:00:00",
"volume": "1.0",
"remaining_volume": "0.0",
"executed_volume": "1.0",
"reserved_fee": "0.0",
"remaining_fee": "0.0",
"paid_fee": "383.8975",
"locked": "0.0",
"prevented_volume": "0",
"prevented_locked": "0",
"trades_count": 1,
"trades": [
{
"market": "SGD-BTC",
"uuid": "9e8f8eba-7050-4837-8969-cfc272cbe083",
"price": "153559.00",
"volume": "1.0",
"funds": "153559.00",
"side": "ask"
}
]
}
Full Code Example
The complete code for creating a market sell order is as follows. Using the currency value provided by the user, the code first checks whether the specified digital asset is held in the account and gets its available quantity. It then validates whether a market sell order can be created. If eligible, the code creates a market sell order for 50% of the available balance..
from urllib.parse import unquote, urlencode
from collections.abc import Mapping
from typing import Any
import hashlib
import uuid
import jwt # PyJWT
import requests
from decimal import Decimal, ROUND_DOWN
access_key = "<YOUR_ACCESS_KEY>"
secret_key = "<YOUR_SECRET_KEY>"
# Please add the logic here to generate the JWT authentication token.
def get_pair_and_balance_from_account(currency: str) -> Mapping:
jwt_token = _create_jwt(access_key, secret_key)
url = "https://sg-api.upbit.com/v1/accounts"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers).json()
trading_pair_list = [item for item in response if item.get("currency") == currency]
if len(trading_pair_list) == 0:
raise ValueError("Currency {currency} is not found".format(currency=currency))
else:
pair = trading_pair_list[0]
return {
"pair": "{unit_currency}-{currency}".format(unit_currency=pair.get('unit_currency'), currency=pair.get('currency')),
"balance": pair.get('balance')
}
def get_order_chance(trading_pair: str) -> Mapping:
params = {
"market": trading_pair
}
query_string = _build_query_string(params)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/orders/chance"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers, params=params).json()
min_total = response.get("market").get("ask").get("min_total")
ask_types = response.get("market").get("ask_types")
if "market" not in ask_types:
raise ValueError("This pair does not support market order. {ask_types}".format(ask_types=ask_types))
else:
order_type_market = True
return {
"order_type_market": order_type_market,
"min_total": min_total
}
def create_order(
trading_pair: str,
volume: str
) -> str:
body = {
"market": trading_pair,
"side": "ask",
"ord_type": "market",
"volume": volume
}
query_string = _build_query_string(body)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/orders"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.post(url, headers=headers, json=body).json()
uuid = response.get('uuid')
if uuid is None:
raise ValueError("Please check the response. {response}".format(response=response))
else:
return uuid
def get_order(uuid: str) -> Mapping:
params = {
"uuid": uuid
}
query_string = _build_query_string(params)
jwt_token = _create_jwt(access_key, secret_key, query_string)
url = "https://sg-api.upbit.com/v1/order"
headers = {
"Authorization": "Bearer {jwt_token}".format(jwt_token=jwt_token),
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers, params=params).json()
return response
# # If you uncomment and run this code, a real market sell order may be created. Please double-check before executing.
# if __name__ == "__main__":
# currency = "<Enter your currency>"
# account_info = get_pair_and_balance_from_account(currency)
# trading_pair = account_info.get("pair")
# balance = account_info.get("balance")
# order_chance = get_order_chance(trading_pair)
# fifty_percent_volume = str((Decimal(balance) * Decimal("0.5")).quantize(Decimal("1e-8"), rounding=ROUND_DOWN))
# if order_chance["order_type_market"]:
# order_uuid = create_order(market_pair, fifty_percent_volume)
# order_info = get_order(order_uuid)
# print("order_info: {order_info}".format(order_info=order_info))
# else:
# raise ValueError("This pair does not support market order. {order_chance}".format(order_chance=order_chance))
Updated 9 days ago