### Example Usage of WssOrderManagementService Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Demonstrates how to create an instance of WssOrderManagementService, start it, and run the service to begin receiving order updates. Uses a demo WebSocket URL with a brokerId. ```python oms = WssOrderManagementService(url="wss://ws.okx.com:8443/ws/v5/private?brokerId=9999") oms.start() oms.run_service() ``` -------------------------------- ### Install Dependencies Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/README.md Command to install project dependencies from the requirements.txt file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install Dependencies and Run Market Maker Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md Commands to install project dependencies and run the market maker strategy from the command line. ```bash # Install dependencies pip install -r requirements.txt # Run the market maker python3 -m okx_market_maker.run_sample_market_maker # Or directly python3 okx_market_maker/run_sample_market_maker.py ``` -------------------------------- ### Get Nested Strategy Parameter (Commented Example) Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/06-configuration.md Illustrates how to retrieve a deeply nested parameter from the strategy configuration. This example is commented out and assumes a specific YAML structure. ```python # Nested parameter (if YAML structure allowed) # num_orders = loader.get_strategy_params("market_making", "num_orders") ``` -------------------------------- ### Market Maker Entry Point Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md This is the main entry point for running the SampleMM strategy. It initializes the strategy and starts its execution loop. ```python from okx_market_maker.strategy.SampleMM import SampleMM if __name__ == "__main__": strategy = SampleMM() strategy.run() ``` -------------------------------- ### WssPositionManagementService Run Service Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Starts the WebSocket service to subscribe to account, positions, and balance_and_position channels. Updates are pushed to global containers. ```python pms = WssPositionManagementService(url="wss://ws.okx.com:8443/ws/v5/private?brokerId=9999") pms.start() pms.run_service() ``` -------------------------------- ### Example Usage of PlaceOrderRequest Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Demonstrates how to create and use a PlaceOrderRequest object to place a limit buy order for BTC-USDT-SWAP. Ensure necessary enums and utility functions are imported. ```python from okx_market_maker.order_management_service.model.OrderRequest import PlaceOrderRequest from okx_market_maker.utils.OkxEnum import OrderSide, OrderType, TdMode, PosSide from okx_market_maker.utils.WsOrderUtil import get_request_uuid req = PlaceOrderRequest( inst_id="BTC-USDT-SWAP", td_mode=TdMode.CROSS, side=OrderSide.BUY, ord_type=OrderType.LIMIT, size="1", price="26000", pos_side=PosSide.net, client_order_id=get_request_uuid("order") ) strategy.place_orders([req]) ``` -------------------------------- ### API Credentials Setup in Settings Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/06-configuration.md Populate your OKX API credentials directly within the settings.py file. It's recommended to use paper trading for initial testing. ```python API_KEY = "your_okx_api_key" API_KEY_SECRET = "your_okx_api_secret" API_PASSPHRASE = "your_okx_passphrase" IS_PAPER_TRADING = True # Recommended for testing ``` -------------------------------- ### API Credentials Setup via Environment Variables Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/06-configuration.md Set OKX API credentials as environment variables for better security and management. Update settings.py to read these variables. ```bash export OKX_API_KEY="your_key" export OKX_API_SECRET="your_secret" export OKX_API_PASSPHRASE="your_passphrase" ``` ```python import os API_KEY = os.getenv("OKX_API_KEY", "") API_KEY_SECRET = os.getenv("OKX_API_SECRET", "") API_PASSPHRASE = os.getenv("OKX_API_PASSPHRASE", "") ``` -------------------------------- ### Trading Instrument Configuration Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md Specify the trading instrument ID and trading mode in settings.py. This example uses BTC-USDT-SWAP in cross mode. ```python TRADING_INSTRUMENT_ID = "BTC-USDT-SWAP" TRADING_MODE = "cross" ``` -------------------------------- ### Getting Positions Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Retrieve all open positions. This method is essential for monitoring your current market exposure. ```APIDOC ## Getting Positions ### Description Retrieves all open positions. This method is essential for monitoring your current market exposure. ### Method `get_positions()` ### Usage ```python positions = self.get_positions() # Raises ValueError if not ready ``` ### Example ```python positions = strategy.get_positions() pos_map = positions.get_position_map() # Dict[position_id: str, Position] for pos_id, position in pos_map.items(): if position.inst_id == "BTC-USDT-SWAP": print(f"Long position: {position.pos}") print(f"Avg entry: {position.avg_px}") print(f"Mark price: {position.mark_px}") print(f"Unrealized P&L: {position.upl}") ``` ``` -------------------------------- ### Create Market Data Services for Instruments Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Initialize and start market data services for each instrument defined. This ensures real-time data is available for all legs of the strategy. ```python for inst_id in INSTRUMENTS: mds = WssMarketDataService(url="...", inst_id=inst_id) mds.start() mds.run_service() ``` -------------------------------- ### Example Usage of CancelOrderRequest Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Shows how to instantiate a CancelOrderRequest and use it to cancel an order through the strategy object. Verify that the correct instrument and order identifiers are provided. ```python from okx_market_maker.order_management_service.model.OrderRequest import CancelOrderRequest req = CancelOrderRequest( inst_id="BTC-USDT-SWAP", client_order_id="myorder123" ) strategy.cancel_orders([req]) ``` -------------------------------- ### Run WssMarketDataService Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Starts the subscription to order book updates. This method passes subscription arguments and a callback to the parent class, which updates the global order book on receiving data. ```python def run_service(self) -> None: pass ``` -------------------------------- ### Get Account Info Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Retrieve the account object to access overall financial metrics. Raises ValueError if the account is not ready. ```python # In strategy code: account = self.get_account() # Raises ValueError if not ready ``` -------------------------------- ### run_service Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Starts the subscription to order updates by subscribing to the 'orders' channel for all instrument types. Updates are then pushed to the global orders_container. ```APIDOC ## Method: run_service ### Description Start subscription to order updates. Subscribes to "orders" channel for all instrument types (instType=ANY). Updates are pushed to global orders_container. ### Method Signature ```python def run_service(self) -> None ``` ### Parameters None ### Returns None ### Example ```python oms = WssOrderManagementService(url="wss://ws.okx.com:8443/ws/v5/private?brokerId=9999") oms.start() # Assuming start() is a method inherited or available oms.run_service() ``` ``` -------------------------------- ### Verify API Connectivity Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md Check the status of the exchange API to ensure connectivity. This example queries the 'ongoing' status. ```python status = strategy.status_api.status("ongoing") print(f"Exchange status: {status}") ``` -------------------------------- ### Get Account Info Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Retrieves the current account information. This method can raise a ValueError if the account is not ready. ```APIDOC ## Get Account Info ### Description Retrieves the current account information. This method can raise a ValueError if the account is not ready. ### Method ```python account = self.get_account() ``` ### Usage Example ```python account = strategy.get_account() print(f"Total equity: {account.total_eq}") print(f"Update time: {account.u_time}") print(f"Margin ratio: {account.mgn_ratio}") # Access per-currency details btc_detail = account.details.get("BTC") if btc_detail: print(f"BTC equity: {btc_detail.eq}") print(f"BTC available: {btc_detail.avail_eq}") print(f"BTC frozen: {btc_detail.frozen_bal}") ``` ### Account Fields - `u_time` (int): Update timestamp in milliseconds. - `total_eq` (float): Total equity in USD. - `iso_eq` (float): Isolated margin equity. - `adj_eq` (float): Adjusted equity. - `ord_frozen` (float): Margin frozen by orders. - `imr` (float): Initial margin requirement. - `mmr` (float): Maintenance margin requirement. - `notional_usd` (float): Total notional value in USD. - `mgn_ratio` (float): Margin ratio. - `details` (Dict[ccy: str, AccountDetail]): A dictionary containing details for each currency. ``` -------------------------------- ### run_service Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Starts the subscription to order book updates. This method handles the actual connection and data reception, updating the local order book. ```APIDOC ## run_service ### Description Subscribe to order book updates. Passes subscription arguments and callback to parent WsPublic.subscribe(). ### Method Signature ```python def run_service(self) -> None ``` ### Returns None ### Updates Calls _callback() which updates the OrderBook in global order_books[inst_id] on each snapshot or incremental update. ``` -------------------------------- ### Example Error Handling for get_order_book Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Demonstrates how to handle ValueError exceptions when retrieving an order book. If the order book is not ready, an error message is printed, and the main loop will retry. ```python try: order_book = strategy.get_order_book() except ValueError as e: print(f"Order book not ready: {e}") # Main loop will retry in 5 seconds ``` -------------------------------- ### Get All Strategy Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Retrieve a copy of all currently cached strategy orders. Useful for monitoring and debugging. ```python orders = strategy.get_strategy_orders() for client_id, order in orders.items(): print(f"Order {client_id}: {order.side.value} {order.size} @ {order.price}") ``` -------------------------------- ### Example Usage of AmendOrderRequest Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Demonstrates how to create an AmendOrderRequest object and use it to amend an order via the strategy object. Ensure the necessary imports are present. ```python from okx_market_maker.order_management_service.model.OrderRequest import AmendOrderRequest req = AmendOrderRequest( inst_id="BTC-USDT-SWAP", client_order_id="myorder123", new_price="26100", req_id="amend_req_001" ) strategy.amend_orders([req]) ``` -------------------------------- ### Implement Custom Strategy Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md Extend the BaseStrategy class to create a custom trading strategy. This example demonstrates a simple spread widening logic based on volatility. ```python from okx_market_maker.strategy.BaseStrategy import BaseStrategy from okx_market_maker.order_management_service.model.OrderRequest import PlaceOrderRequest, AmendOrderRequest, CancelOrderRequest from okx_market_maker.utils.OkxEnum import OrderSide, OrderType, TdMode, PosSide from okx_market_maker.utils.WsOrderUtil import get_request_uuid from okx_market_maker.utils.InstrumentUtil import InstrumentUtil from typing import Tuple, List from decimal import Decimal class MyCustomStrategy(BaseStrategy): def order_operation_decision(self) -> Tuple[List[PlaceOrderRequest], List[AmendOrderRequest], List[CancelOrderRequest]]: """ Simple spread widening based on volatility. If bid-ask spread is narrow, place wider orders. If spread is wide, cancel and re-place. """ order_book = self.get_order_book() instrument = InstrumentUtil.get_instrument("BTC-USDT-SWAP") # Calculate spread bid = order_book.best_bid_price() ask = order_book.best_ask_price() spread = ask - bid spread_pct = spread / ((bid + ask) / 2) place_list = [] amend_list = [] cancel_list = [] # If spread < 0.05%, place own orders at 0.1% from mid if spread_pct < 0.0005: mid = order_book.middle_price() # Get current orders current_buy = self.get_bid_strategy_orders() current_sell = self.get_ask_strategy_orders() # Cancel current orders if too close to mid for order in current_buy + current_sell: cancel_list.append( CancelOrderRequest( inst_id=instrument.inst_id, client_order_id=order.client_order_id ) ) # Place new orders at wider spread order_size = "1" # 1 contract buy_price = InstrumentUtil.price_trim_by_tick_sz(mid * 0.999, OrderSide.BUY, instrument) sell_price = InstrumentUtil.price_trim_by_tick_sz(mid * 1.001, OrderSide.SELL, instrument) place_list.append(PlaceOrderRequest( inst_id=instrument.inst_id, td_mode=TdMode.CROSS, side=OrderSide.BUY, ord_type=OrderType.LIMIT, price=buy_price, size=order_size, pos_side=PosSide.net, client_order_id=get_request_uuid("order") )) place_list.append(PlaceOrderRequest( inst_id=instrument.inst_id, td_mode=TdMode.CROSS, side=OrderSide.SELL, ord_type=OrderType.LIMIT, price=sell_price, size=order_size, pos_side=PosSide.net, client_order_id=get_request_uuid("order") )) return place_list, amend_list, cancel_list if __name__ == "__main__": strategy = MyCustomStrategy() strategy.run() ``` -------------------------------- ### Monitor Trading Performance Metrics Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/00-index.md Provides an example of how to access and display key performance indicators for the trading strategy. This includes net filled quantity, trading volume, realized profit and loss, and exposure. ```python measurement = strategy.get_strategy_measurement() print(f"Net Position: {measurement.net_filled_qty}") print(f"Trading Volume: {measurement.trading_volume}") print(f"P&L: {measurement.pnl_in_usd_since_running}") print(f"Exposure: {measurement.trading_instrument_exposure_in_base} {measurement.trading_inst_exposure_ccy}") ``` -------------------------------- ### Price Precision Handling Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Demonstrates how to use `price_trim_by_tick_sz` to round prices according to the instrument's tick size for both buy and sell orders. Shows example output for different input prices. ```python from okx_market_maker.utils.InstrumentUtil import InstrumentUtil from okx_market_maker.utils.OkxEnum import OrderSide from decimal import Decimal inst = InstrumentUtil.get_instrument("BTC-USDT") # BTC-USDT might have tick_sz = 0.01 prices = [26000.1, 26000.15, 26000.99, 26001.0] for price in prices: buy_price = InstrumentUtil.price_trim_by_tick_sz(price, OrderSide.BUY, inst) sell_price = InstrumentUtil.price_trim_by_tick_sz(price, OrderSide.SELL, inst) print(f"Price {price}: Buy={buy_price}, Sell={sell_price}") # Output example: # Price 26000.1: Buy=26000.10, Sell=26000.10 # Price 26000.15: Buy=26000.14, Sell=26000.15 # Price 26000.99: Buy=26000.98, Sell=26000.99 # Price 26001.0: Buy=26001.00, Sell=26001.00 ``` -------------------------------- ### Example Market Maker Output Log Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md This log shows the typical output during market maker operation, including subscription status, order placements, risk summaries, and order amendments. ```text [2023-06-23 15:37:21] subscribing [2023-06-23 15:37:22] Subscription confirmed, order book synced PLACE ORDER limit buy BTC-USDT-SWAP 2.0 @ 26441.4 PLACE ORDER limit buy BTC-USDT-SWAP 2.0 @ 26414.9 PLACE ORDER limit buy BTC-USDT-SWAP 2.0 @ 26388.4 PLACE ORDER limit buy BTC-USDT-SWAP 2.0 @ 26362.0 PLACE ORDER limit buy BTC-USDT-SWAP 2.0 @ 26335.5 PLACE ORDER limit sell BTC-USDT-SWAP 2.0 @ 26494.5 PLACE ORDER limit sell BTC-USDT-SWAP 2.0 @ 26521.0 PLACE ORDER limit sell BTC-USDT-SWAP 2.0 @ 26547.5 PLACE ORDER limit sell BTC-USDT-SWAP 2.0 @ 26573.9 PLACE ORDER limit sell BTC-USDT-SWAP 2.0 @ 26600.4 ==== Risk Summary ==== Time: 2023-06-23 15:37:53 Inception: 2023-06-23 15:37:21 P&L since inception (USD): 10.89 Asset Value Change since inception (USD): -51.25 Trading Instrument: BTC-USDT-SWAP (SWAP) Trading Instrument Exposure (BTC): -0.0060 Trading Instrument Exposure (USDT): -179.91 Net Traded Position: -6 Net Trading Volume: 18 ==== End of Summary ==== AMEND ORDER orderaFZBngCqMjsxVHjDtD2TBC with new size 0 or new price 26444.7, req_id is amend9J9HQCeQbuCrRRDS4LLzpk AMEND ORDER order7edCnqJf8LSaASr7aUF8Ep with new size 0 or new price 26418.2, req_id is amendhqggfxytoEgwZWRmGN4otE ... ``` -------------------------------- ### Get Order Book Instance Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Retrieve the order book instance within a strategy. This method raises a ValueError if the order book is not yet ready. ```python from okx_market_maker.strategy.BaseStrategy import BaseStrategy # In strategy code: order_book = self.get_order_book() # Raises ValueError if not ready ``` -------------------------------- ### Run Strategy Main Event Loop Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Starts the main event loop for the strategy. It initializes services, periodically checks exchange status and account health, makes trading decisions, and executes orders. The loop runs until a KeyboardInterrupt. ```python strategy = SampleMM() strategy.run() # Blocks until KeyboardInterrupt ``` -------------------------------- ### Get Ask Strategy Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Retrieve all SELL orders managed by the strategy, sorted by price in ascending order (lowest price first). ```python def get_ask_strategy_orders(self) -> List[StrategyOrder] ``` -------------------------------- ### Get Positions and Iterate Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Retrieve all open positions and iterate through them to access specific details like instrument ID, quantity, average entry price, and unrealized P&L. Raises ValueError if not ready. ```python # In strategy code: positions = self.get_positions() # Raises ValueError if not ready ``` ```python positions = strategy.get_positions() pos_map = positions.get_position_map() # Dict[position_id: str, Position] for pos_id, position in pos_map.items(): if position.inst_id == "BTC-USDT-SWAP": print(f"Long position: {position.pos}") print(f"Avg entry: {position.avg_px}") print(f"Mark price: {position.mark_px}") print(f"Unrealized P&L: {position.upl}") ``` -------------------------------- ### Add Custom Strategy Metrics Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Extend the StrategyMeasurement class to include custom metrics like inventory skew and spread tracking. The calculate_inventory_skew method provides an example of how to compute these metrics. ```python class StrategyMeasurement: # ... existing fields ... inventory_skew: float = 0 # (buy_volume - sell_volume) / total_volume spread_tracking: List[float] = field(default_factory=list) def calculate_inventory_skew(self): total = self.buy_filled_qty + self.sell_filled_qty if total == 0: self.inventory_skew = 0 else: self.inventory_skew = (self.buy_filled_qty - self.sell_filled_qty) / total ``` -------------------------------- ### Custom Strategy Monitoring Hook Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Implement custom monitoring by overriding the log_metrics method in a subclass of BaseStrategy. This example logs key metrics like total equity, net filled quantity, and PnL to a file every 60 seconds. ```python import time class MonitoredStrategy(BaseStrategy): def order_operation_decision(self): # ... normal logic ... # Custom monitoring if int(time.time()) % 60 == 0: # Every 60 seconds self.log_metrics() return place_list, amend_list, cancel_list def log_metrics(self): measurement = self.get_strategy_measurement() account = self.get_account() with open("metrics.log", "a") as f: f.write(f"{time.time()}, {account.total_eq}, {measurement.net_filled_qty}, {measurement.pnl_in_usd_since_running}\n") ``` -------------------------------- ### Run Sample Market Maker Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/README.md Command to execute the main script for the sample market maker. ```bash python3 -m okx_market_maker.run_sample_market_maker ``` -------------------------------- ### get_asset_exposure_ccy Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Get the exposure currency (base currency) of an instrument. ```APIDOC ## get_asset_exposure_ccy ### Description Get the exposure currency (base currency) of an instrument. ### Method `@classmethod get_asset_exposure_ccy(cls, instrument: Instrument) -> str` ### Parameters #### Path Parameters - **instrument** (Instrument) - Yes - Instrument object ### Return - **—** (str) - Base currency (first part of inst_id) ### Example: ```python inst = InstrumentUtil.get_instrument("BTC-USDT-SWAP") base = InstrumentUtil.get_asset_exposure_ccy(inst) # "BTC" ``` ``` -------------------------------- ### Instantiate SampleMM Strategy Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Initializes the SampleMM strategy. It calls the parent constructor with default settings. ```python from okx_market_maker.strategy.SampleMM import SampleMM strategy = SampleMM() strategy.run() ``` -------------------------------- ### Query Tickers and Get Specific Data Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Access ticker data and retrieve specific information such as the last traded price, bid, and ask prices for a given instrument ID. Also provides methods to get currency conversion prices, optionally using the mid-price or last price. ```python tickers = strategy.get_tickers() # Get ticker by instrument ID ticker = tickers.get_ticker_by_inst_id("BTC-USDT") if ticker: print(f"Last: {ticker.last}, Bid: {ticker.bid_px}, Ask: {ticker.ask_px}") # Get price for currency conversion usdt_price = tickers.get_usdt_price_by_ccy("BTC", use_mid=True) # float # Using alternative quote currencies # If BTC-USDT doesn't exist, tries BTC-USDC, BTC-ETH (with ETH-USDT), etc. usdt_price = tickers.get_usdt_price_by_ccy("ETH", use_mid=False) # Uses last price ``` -------------------------------- ### Get Position Map Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Returns all open positions keyed by their unique position ID. ```APIDOC ## Method: get_position_map ### Description Returns all open positions keyed by their unique position ID. ### Signature ```python def get_position_map(self) -> Dict[str, Position] ``` ### Return Value - **Type**: Dict[str, Position] - **Description**: A dictionary where keys are position IDs and values are `Position` objects. Returns an empty dictionary if no positions are open. ``` -------------------------------- ### Complete Order Placement with Utilities Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Demonstrates a comprehensive order placement flow using various utility functions for instrument data, price/quantity rounding, and unique ID generation. ```python from okx_market_maker.utils.InstrumentUtil import InstrumentUtil from okx_market_maker.utils.WsOrderUtil import get_request_uuid from okx_market_maker.utils.OkxEnum import OrderSide, OrderType, TdMode, PosSide, InstType from okx_market_maker.order_management_service.model.OrderRequest import PlaceOrderRequest # Get instrument specs inst = InstrumentUtil.get_instrument("BTC-USDT-SWAP") # Calculate price and quantity target_buy_price = 26000.5 target_buy_qty = 2.7 # Round to tick/lot sizes rounded_price = InstrumentUtil.price_trim_by_tick_sz( target_buy_price, OrderSide.BUY, inst ) rounded_qty = InstrumentUtil.quantity_trim_by_lot_sz( target_buy_qty, inst ) # Create order request req = PlaceOrderRequest( inst_id="BTC-USDT-SWAP", td_mode=TdMode.CROSS, side=OrderSide.BUY, ord_type=OrderType.LIMIT, price=rounded_price, size=rounded_qty, pos_side=PosSide.net, client_order_id=get_request_uuid("order") ) # Place order strategy.place_orders([req]) ``` -------------------------------- ### Initialize WssOrderManagementService Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Instantiates the WssOrderManagementService. Requires the WebSocket URL and optionally API credentials and server time usage. The brokerId can be appended to the URL for demo environments. ```python def __init__( self, url: str, api_key: str = API_KEY, passphrase: str = API_PASSPHRASE, secret_key: str = API_KEY_SECRET, useServerTime: bool = False ) -> None: pass ``` -------------------------------- ### Check Account Equity and Position Details Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/00-index.md Illustrates how to retrieve account information, including total equity and detailed balances for specific currencies like BTC. It also shows how to access and print details of open positions for a given instrument. ```python account = strategy.get_account() total_equity = account.total_eq btc_detail = account.details.get("BTC") print(f"BTC Balance: {btc_detail.eq}, Available: {btc_detail.avail_eq}") positions = strategy.get_positions() for pos_id, pos in positions.get_position_map().items(): if pos.inst_id == "BTC-USDT-SWAP": print(f"Position: {pos.pos}, P&L: {pos.upl}") ``` -------------------------------- ### Get Active Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Retrieves all orders that are currently in a LIVE or PARTIALLY_FILLED state. These are orders that are still active in the market. ```python def get_active_orders(self) -> Dict[str, Order] ``` -------------------------------- ### get_strategy_measurement Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Get current strategy measurement object containing P&L, net position, and exposure metrics. ```APIDOC ## get_strategy_measurement ### Description Get current strategy measurement object containing P&L, net position, and exposure metrics. ### Method Signature ```python def get_strategy_measurement(self) -> StrategyMeasurement ``` ### Parameters None ### Response #### Success Response - **return value** (StrategyMeasurement) - Current performance metrics ``` -------------------------------- ### Initialize BaseStrategy Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Instantiate the BaseStrategy class with API credentials and paper trading preference. Ensure API keys and passphrases are correctly configured. ```python from okx_market_maker.strategy.BaseStrategy import BaseStrategy class MyStrategy(BaseStrategy): def order_operation_decision(self): # Implement custom logic return [], [], [] strategy = MyStrategy( api_key="your_api_key", api_key_secret="your_secret", api_passphrase="your_passphrase", is_paper_trading=True ) ``` -------------------------------- ### Get Single-Level Strategy Parameter Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/06-configuration.md Retrieves a top-level parameter from the loaded strategy configuration. Ensure the ParamsLoader is initialized before calling. ```python # Single-level parameter step_pct = loader.get_strategy_params("step_pct") ``` -------------------------------- ### run Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Main event loop. Initializes services, enters infinite loop calling order_operation_decision() every second. Handles health checks, order updates, and clean shutdown on exception. ```APIDOC ## run ### Description Main event loop. Initializes services, enters infinite loop calling order_operation_decision() every second. Handles health checks, order updates, and clean shutdown on exception. ### Method Signature ```python def run(self) -> None ``` ### Parameters None ### Event Loop 1. Check exchange status via status_api 2. Load dynamic parameters via params_loader 3. Perform health check (order book freshness, account freshness) 4. Calculate risk summary 5. Update strategy order status from exchange updates 6. Call order_operation_decision() 7. Execute place/amend/cancel operations 8. Sleep 1 second, repeat ### Exception Handling On exception, attempts cancel_all() then sleeps 20 seconds before retry. ### Example ```python strategy = SampleMM() strategy.run() # Blocks until KeyboardInterrupt ``` ``` -------------------------------- ### Get Exposure Currency Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Retrieves the exposure currency (base currency) of an instrument. This is typically the first part of the instrument ID. ```python inst = InstrumentUtil.get_instrument("BTC-USDT-SWAP") base = InstrumentUtil.get_asset_exposure_ccy(inst) # "BTC" ``` -------------------------------- ### WssPositionManagementService Constructor Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Initializes the WebSocket service for position and account management. Requires WebSocket URL and optionally API credentials and server time usage. ```python def __init__( self, url: str, api_key: str = API_KEY, passphrase: str = API_PASSPHRASE, secret_key: str = API_KEY_SECRET, useServerTime: bool = False ) -> None ``` -------------------------------- ### Get Instrument Quote Currency Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Retrieves the quote currency for a given instrument. The quote currency is the second part of the instrument ID. ```python inst = InstrumentUtil.get_instrument("BTC-USDT-SWAP") quote = InstrumentUtil.get_asset_quote_ccy(inst) # "USDT" ``` -------------------------------- ### WssMarketDataService Constructor Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Initializes the WebSocket service for receiving real-time order book updates for a specific instrument. It sets up the connection and subscription parameters. ```APIDOC ## WssMarketDataService Constructor ### Description Initializes the WebSocket service for receiving real-time order book updates for a specific instrument. It sets up the connection and subscription parameters. ### Method Signature ```python def __init__( self, url: str, inst_id: str, channel: str = "books5" ) -> None ``` ### Parameters #### Path Parameters - **url** (str) - Required - WebSocket URL (wss://ws.okx.com:8443/ws/v5/public or with brokerId=9999 for demo) - **inst_id** (str) - Required - Instrument ID to subscribe to (e.g., "BTC-USDT-SWAP") - **channel** (str) - Optional - Default: "books5" - Channel type: "books5" (top 5), "books" (all levels), "bbo-tbt" (best bid/ask tick-by-tick), "books50-l2-tbt", "books-l2-tbt" ### Returns None ### Example ```python from okx_market_maker.market_data_service.WssMarketDataService import WssMarketDataService mds = WssMarketDataService( url="wss://ws.okx.com:8443/ws/v5/public?brokerId=9999", inst_id="BTC-USDT-SWAP", channel="books" ) mds.start() mds.run_service() ``` ``` -------------------------------- ### Access Account Details Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Print key account fields like total equity, update time, and margin ratio. Also shows how to access specific currency details. ```python account = strategy.get_account() print(f"Total equity: {account.total_eq}") print(f"Update time: {account.u_time}") print(f"Margin ratio: {account.mgn_ratio}") # Access per-currency details btc_detail = account.details.get("BTC") if btc_detail: print(f"BTC equity: {btc_detail.eq}") print(f"BTC available: {btc_detail.avail_eq}") print(f"BTC frozen: {btc_detail.frozen_bal}") ``` -------------------------------- ### Get Inactive Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Retrieves orders that are in a final state, specifically FILLED or CANCELED. This method excludes orders that were partially filled and then canceled. ```python def get_inactive_orders(self) -> Dict[str, Order] ``` -------------------------------- ### Python OKX SDK Prerequisite Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/README.md Specifies the minimum required version for the 'python-okx' SDK. ```python python-okx>=0.1.9 ``` -------------------------------- ### WssOrderManagementService Constructor Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Initializes the WebSocket service for receiving real-time order updates. It requires the WebSocket URL and optionally accepts API credentials and a flag for using server time. ```APIDOC ## Constructor ### Description Initializes the WebSocket service for receiving real-time order updates from OKX. Extends OKX SDK's WsPrivate class. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method Signature ```python def __init__( self, url: str, api_key: str = API_KEY, passphrase: str = API_PASSPHRASE, secret_key: str = API_KEY_SECRET, useServerTime: bool = False ) -> None ``` ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | str | Yes | — | WebSocket URL (wss://ws.okx.com:8443/ws/v5/private or with brokerId=9999 for demo) | | api_key | str | No | API_KEY | OKX API key | | passphrase | str | No | API_PASSPHRASE | OKX API passphrase | | secret_key | str | No | API_KEY_SECRET | OKX API secret | | useServerTime | bool | No | False | Use server time for signing | ### Returns None ``` -------------------------------- ### Get Tickers in Strategy Code Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Retrieve ticker data within your strategy code. This method raises a ValueError if the data is not yet ready. ```python from okx_market_maker.market_data_service.model.Tickers import Tickers # In strategy code: tickers = self.get_tickers() # Raises ValueError if not ready ``` -------------------------------- ### Get Strategy Measurement Metrics Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Retrieve the current strategy measurement object, which includes P&L, net position, and exposure metrics. ```python def get_strategy_measurement(self) -> StrategyMeasurement ``` -------------------------------- ### Get Bid Strategy Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Retrieve all BUY orders managed by the strategy, sorted by price in descending order (highest price first). ```python def get_bid_strategy_orders(self) -> List[StrategyOrder] ``` -------------------------------- ### Configure API Keys and Trading Settings Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/00-index.md Edit the settings.py file to include your OKX API credentials and set trading parameters like instrument ID and trading mode. ```python API_KEY = "your_okx_api_key" API_KEY_SECRET = "your_secret" API_PASSPHRASE = "your_passphrase" IS_PAPER_TRADING = True TRADING_INSTRUMENT_ID = "BTC-USDT-SWAP" TRADING_MODE = "cross" ``` -------------------------------- ### WssPositionManagementService Constructor Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Initializes the WebSocket service for position and account management. It requires the WebSocket URL and optionally accepts API credentials and a flag for server time usage. ```APIDOC ## WssPositionManagementService Constructor ### Description Initializes the WebSocket service for position and account management. It requires the WebSocket URL and optionally accepts API credentials and a flag for server time usage. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```python def __init__( self, url: str, api_key: str = API_KEY, passphrase: str = API_PASSPHRASE, secret_key: str = API_KEY_SECRET, useServerTime: bool = False ) -> None ``` ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | url | str | Yes | — | WebSocket URL (wss://ws.okx.com:8443/ws/v5/private or with brokerId=9999 for demo) | | api_key | str | No | API_KEY | OKX API key | | passphrase | str | No | API_PASSPHRASE | OKX API passphrase | | secret_key | str | No | API_KEY_SECRET | OKX API secret | | useServerTime | bool | No | False | Use server time for signing | ### Returns None ``` -------------------------------- ### Enable Paper Trading Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Set this flag to True to enable paper trading mode. All orders will be executed on OKX demo servers with simulated fills, useful for testing strategies without financial risk. ```python IS_PAPER_TRADING = True ``` -------------------------------- ### Get Filled Orders Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/03-order-api.md Retrieves all orders that have reached a terminal state, including FILLED, PARTIALLY_FILLED, or CANCELED. This provides a history of completed or stopped orders. ```python def get_filled_orders(self) -> Dict[str, Order] ``` -------------------------------- ### Load Strategy Parameters Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/06-configuration.md Instantiate ParamsLoader and retrieve strategy parameters. These parameters control aspects like spread, order counts, and position limits. ```python from okx_market_maker.strategy.params.ParamsLoader import ParamsLoader loader = ParamsLoader() step_pct = loader.get_strategy_params("step_pct") # 0.001 num_orders = loader.get_strategy_params("num_of_order_each_side") # 5 ``` -------------------------------- ### Get Instrument Mark Price Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/07-utility-functions.md Fetches the current mark price for a specified instrument ID from a global container. Returns 0 if the instrument is not found. ```python mark_px = InstrumentUtil.get_instrument_mark_px("BTC-USDT-SWAP") if mark_px > 0: print(f"Current mark price: {mark_px}") ``` -------------------------------- ### Order Placement Flow Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Illustrates the sequence of events and state changes during the order placement process, from initial request to acknowledgment and potential errors. ```pseudocode PlaceOrderRequest ↓ REST API sends request (printed: "PLACE ORDER...") ↓ StrategyOrder created with status=SENT, added to cache ↓ ├─ If API returns error (sCode != '0'): │ StrategyOrder removed from cache │ (No order created on exchange) │ └─ If API succeeds (sCode = '0'): StrategyOrder.order_id = exchange_ord_id StrategyOrder.status = ACK (Waits for OMS update) ↓ OMS sends Order with state=LIVE StrategyOrder.status = LIVE ``` -------------------------------- ### Place Limit Order for BTC-USDT Swap Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/00-index.md Demonstrates how to place a limit buy order for BTC-USDT perpetual swap using the `PlaceOrderRequest` model. It specifies order details like instrument ID, trading mode, side, order type, price, size, position side, and a unique client order ID. ```python from okx_market_maker.order_management_service.model.OrderRequest import PlaceOrderRequest from okx_market_maker.utils.OkxEnum import OrderSide, OrderType, TdMode, PosSide from okx_market_maker.utils.WsOrderUtil import get_request_uuid req = PlaceOrderRequest( inst_id="BTC-USDT-SWAP", td_mode=TdMode.CROSS, side=OrderSide.BUY, ord_type=OrderType.LIMIT, price="26000", size="1", pos_side=PosSide.net, client_order_id=get_request_uuid("order") ) strategy.place_orders([req]) ``` -------------------------------- ### Get Position Map Method Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md The `get_position_map` method returns all open positions, keyed by their unique position ID. Returns an empty dictionary if no positions are open. ```python def get_position_map(self) -> Dict[str, Position] ``` -------------------------------- ### Initialize WssMarketDataService Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Initializes the WebSocket service for receiving order book updates. Specify the WebSocket URL, instrument ID, and optionally the channel type. The service automatically validates CRC32 checksums and maintains a local OrderBook. ```python def __init__( self, url: str, inst_id: str, channel: str = "books5" ) -> None: pass ``` ```python from okx_market_maker.market_data_service.WssMarketDataService import WssMarketDataService mds = WssMarketDataService( url="wss://ws.okx.com:8443/ws/v5/public?brokerId=9999", inst_id="BTC-USDT-SWAP", channel="books" ) mds.start() mds.run_service() ``` -------------------------------- ### Mark Price Access Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/04-market-data-api.md Provides access to mark prices for instruments, crucial for derivatives trading. It also offers a utility to get the current USDT to USD conversion rate. ```APIDOC ## Getting Mark Prices ### Description Accesses the mark price cache, which is populated by the RESTMarketDataService. ### Method `mark_px_container[0]` ### Parameters None ### Response Example ```python from okx_market_maker import mark_px_container mark_px_cache = mark_px_container[0] ``` ## Querying Mark Prices ### Description Retrieves the mark price for a specific instrument or the USDT to USD conversion rate. ### Method `get_mark_px(inst_id: str)` Retrieves the mark price object for a given instrument ID. `get_usdt_to_usd_rate()` Retrieves the current conversion rate from USDT to USD. ### Parameters - **inst_id** (str) - Required - The instrument ID for which to get the mark price (e.g., "BTC-USDT-SWAP"). ### Response Example ```python mark_px_obj = mark_px_cache.get_mark_px("BTC-USDT-SWAP") if mark_px_obj: print(f"Mark price: {mark_px_obj.mark_px}") usdt_to_usd_rate = mark_px_cache.get_usdt_to_usd_rate() ``` ### Mark Price Fields ### Description Details of the fields available within a Mark Price object. ### Fields - **mark_px** (float) - The current mark price. ``` -------------------------------- ### Profile Strategy Execution with cProfile Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/09-advanced-topics.md Use Python's cProfile module to identify performance bottlenecks in your trading strategy's execution cycle. Sort stats by cumulative time to find the slowest functions. ```python import cProfile import pstats def run_strategy(): strategy = SampleMM() strategy.run() profiler = cProfile.Profile() profiler.enable() # ... run for a bit ... profiler.disable() stats = pstats.Stats(profiler) stats.sort_stats('cumulative') stats.print_stats(20) ``` -------------------------------- ### Monitor Positions and P&L in Python Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/08-running-and-examples.md This strategy monitors account positions and P&L, logging the information every 5 seconds. It extends the base SampleMM class and overrides the order_operation_decision method. ```python from okx_market_maker.strategy.SampleMM import SampleMM import time class MonitoringStrategy(SampleMM): def order_operation_decision(self): # Call parent implementation place_list, amend_list, cancel_list = super().order_operation_decision() # Log position and P&L every 5 seconds if int(time.time()) % 5 == 0: try: positions = self.get_positions() account = self.get_account() measurement = self.get_strategy_measurement() print(f"\n=== Position Monitor ===") print(f"Account Equity: ${account.total_eq:.2f}") for pos_id, pos in positions.get_position_map().items(): if pos.pos != 0: print(f"{pos.inst_id}: {pos.pos} @ {pos.avg_px:.2f} (mark: {pos.mark_px:.2f}, U/L: ${pos.upl:.2f})") print(f"Net Position: {measurement.net_filled_qty}") print(f"P&L: ${measurement.pnl_in_usd_since_running:.2f}") except ValueError: pass return place_list, amend_list, cancel_list if __name__ == "__main__": strategy = MonitoringStrategy() strategy.run() ``` -------------------------------- ### SampleMM Order Operation Decision Logic Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Implements the core market-making logic for SampleMM. It determines which orders to place, amend, or cancel based on the order book, strategy parameters, and current inventory. ```python # From SampleMM order_operation_decision(): # If mid price is 26000 and step_pct is 0.001: # Buy orders: 26000*(1-0.001), 26000*(1-0.002), 26000*(1-0.003), ... # Sell orders: 26000*(1+0.001), 26000*(1+0.002), 26000*(1+0.003), ... ``` -------------------------------- ### Get Strategy Measurement Data Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Retrieve key metrics for a trading strategy, including net position, volumes, P&L, and asset value changes. This is useful for real-time performance monitoring. ```python measurement = strategy.get_strategy_measurement() print(f"Net position: {measurement.net_filled_qty}") print(f"Buy volume: {measurement.buy_filled_qty}") print(f"Sell volume: {measurement.sell_filled_qty}") print(f"Trading volume: {measurement.trading_volume}") print(f"P&L (USD): {measurement.pnl_in_usd_since_running}") print(f"Asset value change: {measurement.asset_value_change_in_usd_since_running}") ``` -------------------------------- ### Fetch Account Information from Cache Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/01-core-strategy-api.md Retrieve account details, including balances per currency, from the global cache. Raises a ValueError if account information is not yet ready. ```python @staticmethod def get_account() -> Account ``` -------------------------------- ### Position Fields Explained Source: https://github.com/okxapi/okx-sample-market-maker/blob/main/_autodocs/05-position-account-api.md Access individual fields of a position object to get detailed information such as position ID, instrument details, current P&L, margin requirements, and liquidation price. ```python position = positions_map.get(position_id) position.position_id # str, unique position ID position.inst_id # str, "BTC-USDT-SWAP" position.inst_type # InstType, SWAP, FUTURES, MARGIN, etc. position.pos_side # PosSide, long, short, or net position.pos # float, position quantity position.avg_px # float, average entry price position.mark_px # float, current mark price position.last # float, last traded price position.upl # float, unrealized P&L position.mgn_ratio # float, margin ratio position.lever # int, leverage (if any) position.liq_px # float, liquidation price position.imr # float, initial margin required position.mmr # float, maintenance margin required position.notional_usd # float, position notional value position.ccy # str, settlement currency position.u_time # int, last update timestamp ```