"""Type definitions for the Hibachi Python SDK.
This module contains type definitions, enums, and dataclasses used throughout
the SDK, organized into logical sections for clarity.
"""
import re
from dataclasses import dataclass, field
from decimal import Decimal
from enum import Enum
from typing import (
Any,
Callable,
Coroutine,
Dict,
List,
Self,
TypeAlias,
Union,
overload,
)
from hibachi_xyz.errors import (
ExchangeError,
HibachiApiError, # noqa: F401
ValidationError,
)
# ============================================================================
# TYPE ALIASES
# ============================================================================
# Core ID types
Nonce: TypeAlias = int
OrderId: TypeAlias = int
# JSON type hierarchy
JsonObject: TypeAlias = dict[str, "JsonValue"]
JsonArray: TypeAlias = list["JsonValue"]
JsonValue: TypeAlias = None | bool | int | float | str | JsonObject | JsonArray
# Although JsonArray is technically first class json and can be root, for the purposes of this SDK we decode responses as dict only
Json: TypeAlias = JsonObject
# Hibachi input types
HibachiIntegralInput: TypeAlias = str | int
HibachiNumericInput: TypeAlias = Decimal | str | float | int
# WebSocket event handler
WsEventHandler: TypeAlias = Callable[[Json], Coroutine[None, None, None]]
# ============================================================================
# NUMERIC CONVERSION UTILITIES
# ============================================================================
DECIMAL_PATTERN = re.compile(r"^\d+(\.\d+)?$")
[docs]
def full_precision_string(n: HibachiNumericInput) -> str:
"""Convert a numeric input to a full precision string representation."""
if isinstance(n, str):
if not DECIMAL_PATTERN.match(n):
raise ValidationError(f"Invalid numeric input {n}")
return n
if isinstance(n, (int, float)):
n = Decimal(str(n))
if not isinstance(n, Decimal):
raise ValidationError(f"Invalid numeric input type {n} - {type(n)}")
return format(n, "f")
@overload
def numeric_to_decimal(n: HibachiNumericInput) -> Decimal: ...
@overload
def numeric_to_decimal(n: None) -> None: ...
[docs]
def numeric_to_decimal(n: HibachiNumericInput | None) -> Decimal | None:
"""Convert various numeric input types to Decimal, or None if input is None."""
if n is None:
return n
if isinstance(n, str):
if not DECIMAL_PATTERN.match(n):
raise ValidationError(f"Invalid numeric input {n}")
return Decimal(n)
if isinstance(n, (int, float)):
n = Decimal(str(n))
if not isinstance(n, Decimal):
raise ValidationError(f"Invalid numeric input type {n} - {type(n)}")
return n
# ============================================================================
# CORE ENUMS
# ============================================================================
[docs]
class Interval(Enum):
"""Time intervals for klines/candlestick data."""
ONE_MINUTE = "1min"
FIVE_MINUTES = "5min"
FIFTEEN_MINUTES = "15min"
ONE_HOUR = "1h"
FOUR_HOURS = "4h"
ONE_DAY = "1d"
ONE_WEEK = "1w"
[docs]
class Side(Enum):
"""Order side (buy/sell)."""
BID = "BID"
ASK = "ASK"
SELL = "SELL"
BUY = "BUY"
[docs]
class OrderType(Enum):
"""Order type."""
LIMIT = "LIMIT"
MARKET = "MARKET"
[docs]
class OrderStatus(Enum):
"""Order status."""
PENDING = "PENDING"
CHILD_PENDING = "CHILD_PENDING"
FILLED = "FILLED"
CANCELLED = "CANCELLED"
REJECTED = "REJECTED"
SCHEDULED_TWAP = "SCHEDULED_TWAP"
PLACED = "PLACED"
PARTIALLY_FILLED = "PARTIALLY_FILLED"
[docs]
class OrderFlags(Enum):
"""Order execution flags."""
PostOnly = "POST_ONLY"
Ioc = "IOC"
ReduceOnly = "REDUCE_ONLY"
[docs]
class TriggerDirection(Enum):
"""Trigger direction for conditional orders."""
HIGH = "HIGH"
LOW = "LOW"
[docs]
class TakerSide(Enum):
"""Taker side in a trade."""
Buy = "Buy"
Sell = "Sell"
[docs]
class WebSocketSubscriptionTopic(Enum):
"""WebSocket subscription topics."""
MARK_PRICE = "mark_price"
SPOT_PRICE = "spot_price"
FUNDING_RATE_ESTIMATION = "funding_rate_estimation"
TRADES = "trades"
KLINES = "klines"
ORDERBOOK = "orderbook"
ASK_BID_PRICE = "ask_bid_price"
# ============================================================================
# ORDER CONFIGURATION TYPES
# ============================================================================
[docs]
@dataclass
class OrderIdVariant:
"""Represents either a nonce or order_id for order identification."""
nonce: Nonce | None
order_id: OrderId | None
[docs]
@classmethod
def from_nonce(cls, nonce: Nonce) -> Self:
"""Create an OrderIdVariant from a nonce.
Args:
nonce: The nonce value to use for order identification.
Returns:
OrderIdVariant instance with nonce set and order_id as None.
Raises:
ValueError: If nonce is None.
"""
if nonce is None:
raise ValidationError("nonce cannot be None")
return cls(nonce=nonce, order_id=None)
[docs]
@classmethod
def from_order_id(cls, order_id: OrderId) -> Self:
"""Create an OrderIdVariant from an order_id.
Args:
order_id: The order ID value to use for order identification.
Returns:
OrderIdVariant instance with order_id set and nonce as None.
Raises:
ValueError: If order_id is None.
"""
if order_id is None:
raise ValidationError("order_id cannot be None")
return cls(nonce=None, order_id=order_id)
[docs]
def to_dict(self) -> Dict[str, Any]:
"""Convert OrderIdVariant to dictionary representation.
Returns:
Dictionary with either 'nonce' or 'orderId' key and string value.
Raises:
ValueError: If both nonce and order_id are None.
"""
if self.nonce is not None:
return {"nonce": str(self.nonce)}
elif self.order_id is not None:
return {"orderId": str(self.order_id)}
raise ValidationError("Empty OrderIdVariant: no nonce or order_id set")
[docs]
class TWAPQuantityMode(Enum):
"""TWAP quantity distribution mode."""
FIXED = "FIXED"
RANDOM = "RANDOM"
[docs]
class TWAPConfig:
"""Configuration for TWAP (Time-Weighted Average Price) orders."""
duration_minutes: int
quantity_mode: TWAPQuantityMode
def __init__(self, duration_minutes: int, quantity_mode: TWAPQuantityMode):
"""Initialize TWAP configuration.
Args:
duration_minutes: Total duration for TWAP execution in minutes.
quantity_mode: Quantity distribution mode (FIXED or RANDOM).
"""
self.duration_minutes = duration_minutes
self.quantity_mode = quantity_mode
[docs]
def to_dict(self) -> Dict[str, Any]:
"""Convert TWAP configuration to dictionary representation.
Returns:
Dictionary with 'twapDurationMinutes' and 'twapQuantityMode' keys.
"""
return {
"twapDurationMinutes": self.duration_minutes,
"twapQuantityMode": self.quantity_mode.value,
}
[docs]
class TPSLConfig:
"""Configuration for Take-Profit/Stop-Loss orders."""
[docs]
class Type(Enum):
"""TP/SL order type."""
TP = "TP"
SL = "SL"
[docs]
@dataclass
class Leg:
"""Individual TP/SL leg configuration."""
order_type: "TPSLConfig.Type"
price: Decimal
quantity: Decimal | None
def __init__(self) -> None:
"""Initialize an empty TP/SL configuration.
The configuration starts with no legs. Use add_take_profit() and
add_stop_loss() methods to add individual TP/SL legs.
"""
self.legs: List[TPSLConfig.Leg] = []
[docs]
def add_take_profit(
self, price: HibachiNumericInput, quantity: HibachiNumericInput | None = None
) -> Self:
"""Add a take-profit leg to the configuration."""
self.legs.append(
TPSLConfig.Leg(
order_type=TPSLConfig.Type.TP,
price=numeric_to_decimal(price),
quantity=numeric_to_decimal(quantity),
)
)
return self
[docs]
def add_stop_loss(
self, price: HibachiNumericInput, quantity: HibachiNumericInput | None = None
) -> Self:
"""Add a stop-loss leg to the configuration."""
self.legs.append(
TPSLConfig.Leg(
order_type=TPSLConfig.Type.SL,
price=numeric_to_decimal(price),
quantity=numeric_to_decimal(quantity),
)
)
return self
def _as_requests(
self,
*,
parent_symbol: str,
parent_quantity: HibachiNumericInput,
parent_side: "Side",
parent_nonce: Nonce,
max_fees_percent: HibachiNumericInput,
) -> List["CreateOrder"]:
"""Convert TP/SL configuration to a list of order requests.
Args:
parent_symbol: Symbol of the parent order.
parent_quantity: Quantity of the parent order.
parent_side: Side (BID/ASK) of the parent order.
parent_nonce: Nonce of the parent order for linking.
max_fees_percent: Maximum fees as a percentage.
Returns:
List of CreateOrder instances representing the TP/SL legs.
"""
order_requests = []
for leg in self.legs:
side = Side.BID if parent_side == Side.ASK else Side.ASK
trigger_direction = TriggerDirection.HIGH
if (leg.order_type == TPSLConfig.Type.TP and parent_side == Side.ASK) or (
leg.order_type == TPSLConfig.Type.SL and parent_side == Side.BID
):
trigger_direction = TriggerDirection.LOW
order_requests.append(
CreateOrder(
symbol=parent_symbol,
side=side,
quantity=leg.quantity or numeric_to_decimal(parent_quantity),
max_fees_percent=numeric_to_decimal(max_fees_percent),
trigger_price=numeric_to_decimal(max_fees_percent),
trigger_direction=trigger_direction,
parent_order=OrderIdVariant.from_nonce(parent_nonce),
order_flags=OrderFlags.ReduceOnly,
)
)
return order_requests
# ============================================================================
# ORDER TYPES
# ============================================================================
[docs]
@dataclass
class Order:
"""Represents an order in the exchange."""
accountId: int
availableQuantity: str
contractId: int | None
creationTime: int | None
finishTime: int | None
numOrdersRemaining: int | None
numOrdersTotal: int | None
orderFlags: OrderFlags | None
orderId: int
orderType: OrderType
price: str | None
quantityMode: str | None
side: Side
status: OrderStatus
symbol: str
totalQuantity: str | None
triggerPrice: str | None
def __init__(
self,
accountId: int,
availableQuantity: str,
orderId: str | int,
orderType: str,
side: str,
status: str,
symbol: str,
numOrdersRemaining: int | None = None,
numOrdersTotal: int | None = None,
quantityMode: str | None = None,
finishTime: int | None = None,
price: str | None = None,
totalQuantity: str | None = None,
creationTime: int | None = None,
contractId: int | None = None,
orderFlags: str | None = None,
triggerPrice: str | None = None,
):
"""Initialize an Order instance.
Args:
accountId: Account ID associated with the order.
availableQuantity: Remaining quantity available for the order.
orderId: Unique order identifier (string or int).
orderType: Type of order (LIMIT, MARKET, etc.).
side: Order side (BID, ASK, BUY, SELL).
status: Current status of the order.
symbol: Trading symbol for the order.
numOrdersRemaining: Number of child orders remaining (for TWAP).
numOrdersTotal: Total number of child orders (for TWAP).
quantityMode: Quantity distribution mode (for TWAP).
finishTime: Timestamp when the order finished (if completed).
price: Limit price for the order.
totalQuantity: Total quantity of the order.
creationTime: Timestamp when the order was created.
contractId: Contract ID associated with the order.
orderFlags: Additional order flags (POST_ONLY, IOC, REDUCE_ONLY).
triggerPrice: Trigger price for conditional orders.
"""
self.accountId = accountId
self.availableQuantity = availableQuantity
self.contractId = contractId
self.creationTime = creationTime
self.finishTime = finishTime
self.numOrdersRemaining = numOrdersRemaining
self.numOrdersTotal = numOrdersTotal
self.orderId = int(orderId)
self.orderType = OrderType(orderType)
self.price = price
self.quantityMode = quantityMode
self.side = Side(side)
self.status = OrderStatus(status)
self.symbol = symbol
self.totalQuantity = totalQuantity
self.triggerPrice = triggerPrice
self.orderFlags = OrderFlags(orderFlags) if orderFlags else None
[docs]
class CreateOrder:
"""Request to create a new order."""
action: str = "place"
symbol: str
side: Side
quantity: Decimal
max_fees_percent: Decimal
price: Decimal | None
trigger_price: Decimal | None
trigger_direction: TriggerDirection | None
twap_config: TWAPConfig | None
creation_deadline: Decimal | None
parent_order: OrderIdVariant | None
order_flags: OrderFlags | None
def __init__(
self,
symbol: str,
side: Side,
quantity: HibachiNumericInput,
max_fees_percent: HibachiNumericInput,
price: HibachiNumericInput | None = None,
trigger_price: HibachiNumericInput | None = None,
twap_config: TWAPConfig | None = None,
creation_deadline: HibachiNumericInput | None = None,
parent_order: OrderIdVariant | None = None,
order_flags: OrderFlags | None = None,
trigger_direction: TriggerDirection | None = None,
):
"""Initialize a CreateOrder request.
Args:
symbol: Trading symbol for the order.
side: Order side (BID/ASK, BUY/SELL normalized to BID/ASK).
quantity: Order quantity (converted to Decimal).
max_fees_percent: Maximum fees as percentage (converted to Decimal).
price: Limit price for the order (converted to Decimal).
trigger_price: Trigger price for conditional orders (converted to Decimal).
twap_config: TWAP configuration for time-weighted execution.
creation_deadline: Deadline for order creation (converted to Decimal).
parent_order: Parent order reference for linked orders.
order_flags: Additional order flags (POST_ONLY, IOC, REDUCE_ONLY).
trigger_direction: Trigger direction (HIGH/LOW) for conditional orders.
"""
if side == Side.BUY:
side = Side.BID
elif side == Side.SELL:
side = Side.ASK
self.symbol = symbol
self.side = side
self.quantity = numeric_to_decimal(quantity)
self.max_fees_percent = numeric_to_decimal(max_fees_percent)
self.price = numeric_to_decimal(price)
self.trigger_price = numeric_to_decimal(trigger_price)
self.twap_config = twap_config
self.creation_deadline = numeric_to_decimal(creation_deadline)
self.parent_order = parent_order
self.order_flags = order_flags
self.trigger_direction = trigger_direction
[docs]
class UpdateOrder:
"""Request to update an existing order."""
action: str = "modify"
order_id: int
# needed for creating the signature
symbol: str
# needed for creating the signature
side: Side
quantity: Decimal
max_fees_percent: Decimal
price: Decimal | None
trigger_price: Decimal | None
parent_order: OrderIdVariant | None
order_flags: OrderFlags | None
creation_deadline: Decimal | None
def __init__(
self,
order_id: int,
symbol: str,
side: Side,
quantity: HibachiNumericInput,
max_fees_percent: HibachiNumericInput,
price: HibachiNumericInput | None = None,
trigger_price: HibachiNumericInput | None = None,
creation_deadline: HibachiNumericInput | None = None,
parent_order: OrderIdVariant | None = None,
order_flags: OrderFlags | None = None,
):
"""Initialize an UpdateOrder request.
Args:
order_id: ID of the order to update.
symbol: Trading symbol (required for signature).
side: Order side (BID/ASK, BUY/SELL normalized to BID/ASK).
quantity: Updated order quantity (converted to Decimal).
max_fees_percent: Maximum fees as percentage (converted to Decimal).
price: Updated limit price (converted to Decimal).
trigger_price: Updated trigger price (converted to Decimal).
creation_deadline: Deadline for order update (converted to Decimal).
parent_order: Parent order reference for linked orders.
order_flags: Additional order flags (POST_ONLY, IOC, REDUCE_ONLY).
"""
if side == Side.BUY:
side = Side.BID
elif side == Side.SELL:
side = Side.ASK
self.order_id = order_id
self.symbol = symbol
self.side = side
self.quantity = numeric_to_decimal(quantity)
self.max_fees_percent = numeric_to_decimal(max_fees_percent)
self.price = numeric_to_decimal(price)
self.trigger_price = numeric_to_decimal(trigger_price)
self.creation_deadline = numeric_to_decimal(creation_deadline)
self.parent_order = parent_order
self.order_flags = order_flags
[docs]
class CancelOrder:
"""Request to cancel an order."""
action: str = "cancel"
order_id: int | None
nonce: int | None
def __init__(self, order_id: int | None = None, nonce: int | None = None):
"""Initialize a CancelOrder request.
Args:
order_id: ID of the order to cancel.
nonce: Nonce of the order to cancel.
Note:
Either order_id or nonce should be provided to identify the order.
"""
self.order_id = order_id
self.nonce = nonce
# ============================================================================
# BATCH ORDER RESPONSE TYPES
# ============================================================================
[docs]
@dataclass
class CreateOrderBatchResponse:
"""Success response to a create order request."""
nonce: Nonce
orderId: str
creationTime: str
creationTimeNsPartial: str
[docs]
@dataclass
class UpdateOrderBatchResponse:
"""Success response to an update order request."""
orderId: str
[docs]
@dataclass
class CancelOrderBatchResponse:
"""Success response to a cancel order request."""
nonce: str
[docs]
@dataclass
class ErrorBatchResponse:
"""Error response for batch operations."""
errorCode: int
message: str
status: str
[docs]
def as_exception(self) -> ExchangeError:
"""Convert error response to an ExchangeError exception.
Returns:
ExchangeError instance with formatted error details.
"""
return ExchangeError(
f"Action failed: {self.errorCode=} {self.status=} {self.message=}"
)
BatchResponseOrder: TypeAlias = (
CreateOrderBatchResponse
| UpdateOrderBatchResponse
| CancelOrderBatchResponse
| ErrorBatchResponse
)
[docs]
def deserialize_batch_response_order(
data: JsonObject,
) -> BatchResponseOrder:
"""Deserialize a batch response order based on which fields are present.
Logic:
- If 'errorCode' is present -> ErrorBatchResponse
- If both 'nonce' and 'orderId' are present -> CreateOrderBatchResponse
- If only 'orderId' is present -> UpdateOrderBatchResponse
- If only 'nonce' is present -> CancelOrderBatchResponse
Args:
data: JSON object containing the batch response order data.
Returns:
Appropriate batch response type based on the fields present in data.
Raises:
DeserializationError: If the data cannot be deserialized into any known type.
"""
from hibachi_xyz.errors import DeserializationError
from hibachi_xyz.helpers import create_with
try:
for k in list(data.keys()): # snapshot keys once
if data[k] is None:
del data[k]
if "errorCode" in data:
return create_with(ErrorBatchResponse, data)
elif "nonce" in data and "orderId" in data:
return create_with(CreateOrderBatchResponse, data)
elif "orderId" in data:
return create_with(UpdateOrderBatchResponse, data)
elif "nonce" in data:
return create_with(CancelOrderBatchResponse, data)
else:
raise DeserializationError(
f"Unknown batch response order format - missing required fields: {data}"
)
except (TypeError, KeyError, ValueError) as e:
raise DeserializationError(
f"Failed to deserialize batch response order: {data}"
) from e
[docs]
@dataclass
class BatchResponse:
"""Response containing multiple order operations."""
orders: list[BatchResponseOrder]
[docs]
@dataclass
class PendingOrdersResponse:
"""Response containing pending orders."""
orders: List[Order]
# ============================================================================
# EXCHANGE INFORMATION TYPES
# ============================================================================
[docs]
@dataclass
class FeeConfig:
"""Fee configuration for the exchange."""
depositFees: str
instantWithdrawDstPublicKey: str
instantWithdrawalFees: List[List[Union[int, float]]]
tradeMakerFeeRate: str
tradeTakerFeeRate: str
transferFeeRate: str
withdrawalFees: str
[docs]
@dataclass
class FutureContract:
"""Future contract specification."""
displayName: str
id: int
minNotional: str
minOrderSize: str
orderbookGranularities: List[str]
initialMarginRate: str
maintenanceMarginRate: str
settlementDecimals: int
settlementSymbol: str
status: str
stepSize: str
symbol: str
tickSize: str
underlyingDecimals: int
underlyingSymbol: str
marketCloseTimestamp: str | None = field(default=None)
marketOpenTimestamp: str | None = field(default=None)
marketCreationTimestamp: str | None = field(default=None)
[docs]
@dataclass
class WithdrawalLimit:
"""Withdrawal limits."""
lowerLimit: str
upperLimit: str
[docs]
@dataclass
class MaintenanceWindow:
"""Scheduled maintenance window."""
begin: float
end: float
note: str
[docs]
@dataclass
class ExchangeInfo:
"""Exchange configuration and status information."""
feeConfig: FeeConfig
futureContracts: List[FutureContract]
instantWithdrawalLimit: WithdrawalLimit
maintenanceWindow: List[MaintenanceWindow]
# can be NORMAL, MAINTENANCE
status: str
[docs]
@dataclass
class CrossChainAsset:
"""Cross-chain asset information."""
chain: str
exchangeRateFromUSDT: str
exchangeRateToUSDT: str
instantWithdrawalLowerLimitInUSDT: str
instantWithdrawalUpperLimitInUSDT: str
token: str
[docs]
@dataclass
class TradingTier:
"""Trading tier information."""
level: int
lowerThreshold: str
title: str
upperThreshold: str
[docs]
@dataclass
class MarketInfo:
"""Market information for a specific contract."""
category: str
markPrice: str
price24hAgo: str
priceLatest: str
tags: List[str]
[docs]
@dataclass
class Market:
"""Market combining contract and info."""
contract: FutureContract
info: MarketInfo
[docs]
@dataclass
class InventoryResponse:
"""Complete inventory information response."""
crossChainAssets: List[CrossChainAsset]
feeConfig: FeeConfig
markets: List[Market]
tradingTiers: List[TradingTier]
# ============================================================================
# MARKET DATA TYPES
# ============================================================================
[docs]
@dataclass
class FundingRateEstimation:
"""Estimated funding rate information."""
estimatedFundingRate: str
nextFundingTimestamp: int
[docs]
@dataclass
class PriceResponse:
"""Price information for a symbol."""
askPrice: str
bidPrice: str
fundingRateEstimation: FundingRateEstimation
markPrice: str
spotPrice: str
symbol: str
tradePrice: str
[docs]
@dataclass
class StatsResponse:
"""24-hour statistics for a symbol."""
high24h: str
low24h: str
symbol: str
volume24h: str
[docs]
@dataclass
class Trade:
"""Individual trade information."""
price: str
quantity: str
takerSide: TakerSide
timestamp: int
def __init__(
self,
price: str,
quantity: str,
takerSide: str | TakerSide,
timestamp: int,
):
"""Initialize a Trade instance.
Args:
price: Trade price as string.
quantity: Trade quantity as string.
takerSide: Taker side (Buy or Sell), as string or TakerSide enum.
timestamp: Trade timestamp.
"""
self.price = price
self.quantity = quantity
self.takerSide = (
TakerSide(takerSide) if isinstance(takerSide, str) else takerSide
)
self.timestamp = timestamp
[docs]
@dataclass
class TradesResponse:
"""Response containing recent trades."""
trades: List[Trade]
[docs]
@dataclass
class Kline:
"""Candlestick/kline data."""
close: str
high: str
low: str
open: str
interval: str
timestamp: int
volumeNotional: str
[docs]
@dataclass
class KlinesResponse:
"""Response containing kline data."""
klines: List[Kline]
[docs]
@dataclass
class OpenInterestResponse:
"""Open interest information."""
totalQuantity: str
[docs]
@dataclass
class OrderBookLevel:
"""Single orderbook price level."""
price: str
quantity: str
[docs]
@dataclass
class OrderBook:
"""Orderbook containing bid and ask levels."""
ask: List[OrderBookLevel]
bid: List[OrderBookLevel]
# ============================================================================
# ACCOUNT TYPES
# ============================================================================
[docs]
@dataclass
class Asset:
"""Asset balance information."""
quantity: str
symbol: str
[docs]
@dataclass
class Position:
"""Position information."""
direction: str
entryNotional: str
markPrice: str
notionalValue: str
openPrice: str
quantity: str
symbol: str
unrealizedFundingPnl: str
unrealizedTradingPnl: str
[docs]
@dataclass
class AccountInfo:
"""Complete account information."""
assets: List[Asset]
balance: str
maximalWithdraw: str
numFreeTransfersRemaining: int
positions: List[Position]
totalOrderNotional: str
totalPositionNotional: str
totalUnrealizedFundingPnl: str
totalUnrealizedPnl: str
totalUnrealizedTradingPnl: str
tradeMakerFeeRate: str
tradeTakerFeeRate: str
[docs]
@dataclass
class AccountSnapshot:
"""Snapshot of account state."""
account_id: int
balance: str
positions: List[Position]
[docs]
@dataclass
class AccountTrade:
"""Individual account trade record."""
askAccountId: int
askOrderId: int
bidAccountId: int
bidOrderId: int
fee: str
id: int
orderType: str
price: str
quantity: str
realizedPnl: str
side: str
symbol: str
timestamp: int
[docs]
@dataclass
class AccountTradesResponse:
"""Response containing account trades."""
trades: List[AccountTrade]
[docs]
@dataclass
class Settlement:
"""Settlement information."""
direction: str
indexPrice: str
quantity: str
settledAmount: str
symbol: str
timestamp: int
[docs]
@dataclass
class SettlementsResponse:
"""Response containing settlements."""
settlements: List[Settlement]
# ============================================================================
# CAPITAL MANAGEMENT TYPES
# ============================================================================
[docs]
@dataclass
class CapitalBalance:
"""Account capital balance."""
balance: str
[docs]
@dataclass
class Transaction:
"""Transaction record."""
id: int
assetId: int
quantity: str
status: str
timestampSec: int
transactionType: str
transactionHash: Union[str, str] | None
token: str | None
etaTsSec: int | None
blockNumber: int | None
chain: str | None
instantWithdrawalChain: str | None
instantWithdrawalToken: str | None
isInstantWithdrawal: bool | None
withdrawalAddress: str | None
receivingAccountId: int | None
receivingAddress: str | None
srcAccountId: int | None
srcAddress: str | None
def __init__(
self,
id: int,
assetId: int,
quantity: str,
status: str,
timestampSec: int,
transactionType: str,
transactionHash: Union[str, str] | None = None,
token: str | None = None,
etaTsSec: int | None = None,
blockNumber: int | None = None,
chain: str | None = None,
instantWithdrawalChain: str | None = None,
instantWithdrawalToken: str | None = None,
isInstantWithdrawal: bool | None = None,
withdrawalAddress: str | None = None,
receivingAddress: str | None = None,
receivingAccountId: int | None = None,
srcAccountId: int | None = None,
srcAddress: str | None = None,
):
"""Initialize a Transaction instance.
Args:
id: Unique transaction identifier.
assetId: Asset identifier for the transaction.
quantity: Transaction amount.
status: Current status of the transaction.
timestampSec: Transaction timestamp in seconds.
transactionType: Type of transaction (deposit, withdrawal, transfer).
transactionHash: Blockchain transaction hash.
token: Token symbol.
etaTsSec: Estimated time of arrival in seconds.
blockNumber: Blockchain block number.
chain: Blockchain network name.
instantWithdrawalChain: Chain used for instant withdrawal.
instantWithdrawalToken: Token used for instant withdrawal.
isInstantWithdrawal: Whether this is an instant withdrawal.
withdrawalAddress: Destination address for withdrawal.
receivingAddress: Receiving address for transfer.
receivingAccountId: Receiving account ID for internal transfer.
srcAccountId: Source account ID for internal transfer.
srcAddress: Source address for transfer.
"""
self.id = id
self.assetId = assetId
self.quantity = quantity
self.status = status
self.timestampSec = timestampSec
self.transactionType = transactionType
self.transactionHash = transactionHash
self.token = token
self.etaTsSec = etaTsSec
self.blockNumber = blockNumber
self.chain = chain
self.instantWithdrawalChain = instantWithdrawalChain
self.instantWithdrawalToken = instantWithdrawalToken
self.isInstantWithdrawal = isInstantWithdrawal
self.withdrawalAddress = withdrawalAddress
self.receivingAddress = receivingAddress
self.receivingAccountId = receivingAccountId
self.srcAccountId = srcAccountId
self.srcAddress = srcAddress
[docs]
@dataclass
class CapitalHistory:
"""Transaction history."""
transactions: List[Transaction]
[docs]
@dataclass
class WithdrawRequest:
"""Withdrawal request."""
accountId: int
coin: str
withdrawAddress: str
network: str
quantity: Decimal
maxFees: Decimal
signature: str
def __init__(
self,
accountId: int,
coin: str,
withdrawAddress: str,
network: str,
quantity: HibachiNumericInput,
maxFees: HibachiNumericInput,
signature: str,
):
"""Initialize a WithdrawRequest instance.
Args:
accountId: Account ID initiating the withdrawal.
coin: Coin/token symbol to withdraw.
withdrawAddress: Destination withdrawal address.
network: Blockchain network for the withdrawal.
quantity: Amount to withdraw (converted to Decimal).
maxFees: Maximum withdrawal fees (converted to Decimal).
signature: Cryptographic signature for the withdrawal.
"""
self.accountId = accountId
self.coin = coin
self.withdrawAddress = withdrawAddress
self.network = network
self.quantity = numeric_to_decimal(quantity)
self.maxFees = numeric_to_decimal(maxFees)
self.signature = signature
[docs]
@dataclass
class WithdrawResponse:
"""Withdrawal response."""
orderId: str
[docs]
@dataclass
class TransferRequest:
"""Transfer request."""
accountId: int
coin: str
fees: Decimal
nonce: int
quantity: Decimal
dstPublicKey: str
signature: str
def __init__(
self,
accountId: int,
coin: str,
fees: HibachiNumericInput,
nonce: int,
quantity: HibachiNumericInput,
dstPublicKey: str,
signature: str,
):
"""Initialize a TransferRequest instance.
Args:
accountId: Source account ID initiating the transfer.
coin: Coin/token symbol to transfer.
fees: Transfer fees (converted to Decimal).
nonce: Unique nonce for the transfer (defaults to current epoch timestamp in μs).
quantity: Amount to transfer (converted to Decimal).
dstPublicKey: Destination account public key.
signature: Cryptographic signature for the transfer.
"""
self.accountId = accountId
self.coin = coin
self.fees = numeric_to_decimal(fees)
self.nonce = nonce
self.quantity = numeric_to_decimal(quantity)
self.dstPublicKey = dstPublicKey
self.signature = signature
[docs]
@dataclass
class TransferResponse:
"""Transfer response."""
status: str
[docs]
@dataclass
class DepositInfo:
"""Deposit information."""
depositAddressEvm: str
# ============================================================================
# WEBSOCKET TYPES
# ============================================================================
[docs]
@dataclass
class WebSocketSubscription:
"""WebSocket subscription configuration."""
symbol: str
topic: WebSocketSubscriptionTopic
[docs]
@dataclass
class WebSocketMarketSubscriptionListResponse:
"""List of WebSocket subscriptions."""
subscriptions: List[WebSocketSubscription]
[docs]
@dataclass
class WebSocketResponse:
"""Generic WebSocket response."""
id: int | None
result: Dict[str, Any] | None
status: int | None
subscriptions: List[WebSocketSubscription] | None
[docs]
@dataclass
class WebSocketEvent:
"""WebSocket event notification."""
account: str
event: str
data: Dict[str, Any]
# WebSocket Request Parameter Types
[docs]
@dataclass
class WebSocketOrderCancelParams:
"""Parameters for WebSocket order cancellation."""
orderId: str
accountId: str
nonce: int
[docs]
@dataclass
class WebSocketOrderModifyParams:
"""Parameters for WebSocket order modification."""
orderId: str
accountId: str
symbol: str
quantity: str
price: str
maxFeesPercent: str
[docs]
@dataclass
class WebSocketOrderStatusParams:
"""Parameters for WebSocket order status query."""
orderId: str
accountId: str
[docs]
@dataclass
class WebSocketOrdersCancelParams:
"""Parameters for WebSocket bulk order cancellation."""
accountId: str
nonce: str
contractId: int | None = None
[docs]
@dataclass
class WebSocketBatchOrder:
"""WebSocket batch order operation."""
action: str
nonce: int
symbol: str
orderType: str
side: str
quantity: str
price: str
maxFeesPercent: str
signature: str
orderId: str | None = None
updatedQuantity: str | None = None
updatedPrice: str | None = None
[docs]
@dataclass
class WebSocketOrdersBatchParams:
"""Parameters for WebSocket batch order operations."""
accountId: str
orders: List[WebSocketBatchOrder]
[docs]
@dataclass
class WebSocketStreamStartParams:
"""Parameters to start WebSocket stream."""
accountId: str
[docs]
@dataclass
class WebSocketStreamPingParams:
"""Parameters for WebSocket stream ping."""
accountId: str
listenKey: str
timestamp: int
[docs]
@dataclass
class WebSocketStreamStopParams:
"""Parameters to stop WebSocket stream."""
accountId: str
listenKey: str
timestamp: int
[docs]
@dataclass
class AccountStreamStartResult:
"""Result from starting account stream."""
accountSnapshot: AccountSnapshot
listenKey: str
# ============================================================================
# REST API PARAMETER TYPES
# ============================================================================
[docs]
@dataclass
class OrderPlaceParams:
"""Parameters for placing an order via REST."""
symbol: str
quantity: Decimal
side: Side
orderType: OrderType
price: Decimal | None
trigger_price: Decimal | None
twap_config: TWAPConfig | None
maxFeesPercent: Decimal
orderFlags: str | None
creation_deadline: Decimal | None
trigger_direction: TriggerDirection | None
def __init__(
self,
symbol: str,
quantity: HibachiNumericInput,
side: Side,
orderType: OrderType,
maxFeesPercent: HibachiNumericInput,
price: HibachiNumericInput | None = None,
trigger_price: HibachiNumericInput | None = None,
twap_config: TWAPConfig | None = None,
orderFlags: str | None = None,
creation_deadline: int | None = None,
trigger_direction: TriggerDirection | None = None,
):
"""Initialize OrderPlaceParams for placing an order via REST.
Args:
symbol: Trading symbol for the order.
quantity: Order quantity (converted to Decimal).
side: Order side (BID/ASK/BUY/SELL).
orderType: Type of order (LIMIT/MARKET).
maxFeesPercent: Maximum fees as percentage (converted to Decimal).
price: Limit price for the order (converted to Decimal).
trigger_price: Trigger price for conditional orders (converted to Decimal).
twap_config: TWAP configuration for time-weighted execution.
orderFlags: Additional order flags (POST_ONLY, IOC, REDUCE_ONLY).
creation_deadline: Deadline timestamp for order creation.
trigger_direction: Trigger direction (HIGH/LOW) for conditional orders.
"""
self.symbol = symbol
self.quantity = numeric_to_decimal(quantity)
self.side = side
self.orderType = orderType
self.price = numeric_to_decimal(price)
self.trigger_price = numeric_to_decimal(trigger_price)
self.twap_config = twap_config
self.maxFeesPercent = numeric_to_decimal(maxFeesPercent)
self.orderFlags = orderFlags
self.creation_deadline = numeric_to_decimal(creation_deadline)
self.trigger_direction = trigger_direction
[docs]
@dataclass
class OrderCancelParams:
"""Parameters for canceling an order."""
orderId: str
accountId: str
nonce: int
[docs]
@dataclass
class OrderModifyParams:
"""Parameters for modifying an order."""
orderId: str
accountId: int
symbol: str
quantity: Decimal
price: Decimal
side: Side
maxFeesPercent: Decimal
nonce: int | None
def __init__(
self,
orderId: str,
accountId: int,
symbol: str,
quantity: HibachiNumericInput,
price: HibachiNumericInput,
side: Side,
maxFeesPercent: HibachiNumericInput,
nonce: int | None = None,
):
"""Initialize OrderModifyParams for modifying an order.
Args:
orderId: ID of the order to modify.
accountId: Account ID that owns the order.
symbol: Trading symbol of the order.
quantity: Updated order quantity (converted to Decimal).
price: Updated order price (converted to Decimal).
side: Order side (BID/ASK/BUY/SELL).
maxFeesPercent: Maximum fees as percentage (converted to Decimal).
nonce: Optional nonce for the modification (defaults to current epoch timestamp in μs).
"""
self.orderId = orderId
self.accountId = accountId
self.symbol = symbol
self.quantity = numeric_to_decimal(quantity)
self.price = numeric_to_decimal(price)
self.side = side
self.maxFeesPercent = numeric_to_decimal(maxFeesPercent)
self.nonce = nonce
[docs]
@dataclass
class OrderStatusParams:
"""Parameters for querying order status."""
orderId: str
accountId: str
[docs]
@dataclass
class OrdersCancelParams:
"""Parameters for bulk order cancellation."""
accountId: str
nonce: str
contractId: int | None = None
[docs]
@dataclass
class BatchOrder:
"""Batch order operation."""
action: str
nonce: int
symbol: str | None = None
orderType: OrderType | None = None
side: Side | None = None
quantity: str | None = None
price: str | None = None
maxFeesPercent: str | None = None
orderId: str | None = None
updatedQuantity: str | None = None
updatedPrice: str | None = None
signature: str | None = None
[docs]
@dataclass
class OrdersBatchParams:
"""Parameters for batch order operations."""
accountId: str
orders: List[BatchOrder]
[docs]
@dataclass
class EnableCancelOnDisconnectParams:
"""Parameters to enable cancel-on-disconnect."""
nonce: int
# ============================================================================
# REST API RESPONSE TYPES
# ============================================================================
[docs]
@dataclass
class OrderResponse:
"""Order information in response."""
accountId: str
availableQuantity: str
orderId: str
orderType: OrderType
price: str
side: Side
status: OrderStatus
symbol: str
totalQuantity: str
[docs]
@dataclass
class OrderPlaceResponseResult:
"""Result of order placement."""
orderId: str
[docs]
@dataclass
class OrderPlaceResponse:
"""Response from placing an order."""
id: int
result: OrderPlaceResponseResult
status: int
[docs]
@dataclass
class OrderStatusResponse:
"""Response containing single order status."""
id: int
result: Order
status: int | None