Package: bookmap
Python API referenceWhat is Python API.The Python API gives you the ability to create your own custom Bookmap indicators using Python
directly within Bookmap, without the need to use an external IDE or a code editor.Needed is only a basic knowledge of Python and a clear idea of what you want to build.Please see thePython API Quick Guidefor a step-by-step guide on how to use Python API.Also see theexamplesdirectory for some examples of Python API usage.Technical requirementsTo run the addon only latest stable Bookmap version is required and Python >= 3.6 installed on the
machine.Python 2 is not supported.API referenceLibrary importEvery Bookmap API script has to import thebookmaplibrary. You may want to set the alias tobmfor convenience.importbookmapasbmAdditionally, since we use the type hints below to denote parameter types, you may want to import
thetypinglibrary. This is not required, but can make your code more readable.fromtypingimportAny,Callable,Dict,List,NoReturn,Optional,TupleBasic functionscreate_addon# Call this to initialize your addon state object.addon=bm.create_addon()This is usually the first thing to call. It creates and returns an addon object which is then used
as the entry point to other Bookmap Python API functionality. It must be called one time only.The returned addon state object is used in many other functions below.start_addon# Call this to start the communication between your addon and Bookmap.bm.start_addon(addon,handle_subscribe_instrument,handle_unsubscribe_instrument)It starts the communication between Bookmap and your Python script. Call it once you have added all
yourEvent handlers.handle_subscribe_instrumentis a function that you should define. It will be called each time you
enable the addon in Bookmap for a certain instrument. All handlers, including this one, must have
a proper signature (a list of parameters), as defined below.handle_unsubscribe_instrumentis similar to above, except is called when the user disables the addon
for a certain instrument.Example:importbookmapasbmdefhandle_subscribe_instrument(addon:Any,alias:str,full_name:str,is_crypto:bool,pips:float,size_multiplier:float,instrument_multiplier:floatsupported_features:Dict[str,object])->None:"""This function is called each time the user enables your addon for a certain instrument.:param addon: The addon state object that you received when calling `create_addon`.:param alias: The alias (name) of the instrument.:param full_name: The full name of the instrument.:param is_crypto: Whether the instrument is a crypto instrument (this can mostly be ignored).:param pips: The minimum price increment of the subscribed instrument.:param size_multiplier: Inverse of the minimum size increment of the subscribed instrument.:param instrument_multiplier: Contract size multiplier (useful for futures).:param supported_features: A dictionary, that represents features that are by particular instrument."""print("Subscribing to the instrument "+alias,flush=True)Exampleofsupported_features:{'trading':True,'oco':True,'oso':True,'depth':True,'mbo':False,'trailingStopsAsIndependentOrders':True,'trailingStopsAsBracketChildren':True,'brackets':True,'bracketTiers':False,'convertOrderToMkt':False,'supportedLimitDurations':['GTC','FOK','IOC','GTC_PO'],'supportedStopDurations':['GTC','FOK','IOC'],'supportedStopOrders':['LMT','MKT'],'negativeStopLimitOffset':True,'marketMode':False,'isBalanceSupported':True,'tradingStartKnown':False,'exchangeUsedForSubscription':False,'typeUsedForSubscription':False,'isDelayed':False,'clientSideFeatures':['TRAILING_STOPS_AS_BRACKET_CHILDREN','BRACKETS','OCO','OSO','TRAILING_STOPS_INDEPENDENT'],'isTradingSubscriptionSupported':False}defhandle_unsubscribe_instrument(addon:Any,alias:str)->None:"""This function is called each time the user disables your addon for a certain instrument.:param addon: The addon state object that you received when calling `create_addon`.:param alias: The alias (name) of the instrument."""print("Unsubscribing from the instrument "+alias,flush=True)if__name__=="__main__":addon=bm.create_addon()# start addon, requires 3 arguments - addon itself, handler for subscribe event# and handler for unsubscribe eventbm.start_addon(addon,handle_subscribe_instrument,handle_unsubscribe_instrument)bm.wait_until_addon_is_turned_off(addon)Important note: every time, when you see size in integer format instead of float, the actual size
is the product of multiplicationsize_multiplier*sizewait_until_addon_is_turned_off# Call this at the end of the main block, to wait until the addon is turned off.bm.wait_until_addon_is_turned_off(addon)This function is used to block main thread until addon is turned off. Call this function at the end
of the main block of your script.How Bookmap handles prices and sizesThe Bookmap API doesn't use floating point numbers to represent prices and sizes. Instead, it uses
integers, where each integer represents a certain number of the minimum price increments (pips) or
the minimum size increments (which is an inverse of thesize_multiplier). We call them a
"price level" and a "size level".How to convert these levels to a real price or size? The rule are simple:Every time you receive a "price level", simplymultiplyit by the instrument'spipsvalue
to get the price.Every time you receive a "size level", simplydivideit by the instrument'ssize_multipliervalue to get the size.Why aren't these levels and not prices / sizes directly? Floating point numbers in binary
computers cannot represent all decimal values precisely, so we want to avoid them until the last
moment.How to know what the instrument'spipsandsize_multipliervalues are? You receive them via thehandle_subscribe_instrumentcallback when the user subscribes to an instrument.Event handlersBelow are listed many more event handlers, similar to the ones above, which Bookmap calls to
give your addon certain data about the instrument (order book updates, trades, etc.).Each handler is responsible for handling a certain type of event. You should implement all handlers
that have the data you are interested in.There are two important requirements to handlers:Your handlers must follow the exact parameters specified here.Your handlers should never block for too long / do some complex time-consuming code.
All the handlers are called from the same thread, so if one handler blocks for too long, it
will block all other handlers as well. In other words, never dotime.time(...)or something
similar in your handlers, but instead spin up a separate thread to do time-consuming code.All handlers except two instart_addonare optional.Note that you are allowed to register more than one handler for each event, but it is not
recommended, to avoid making your addon code too complex.add_depth_handler# Call this if you need to receive depth (order book) events. Create your own `on_depth` function.bm.add_depth_handler(addon,on_depth)Adds handler for depth (order book) events. Each depth event represents change on the single price
level. For more details seesubscribe_depth.When first enabling the addon / subscribing to an instrument, Bookmap will send you the current
order book snapshot by calling your function for each order book price level.Example of handler:defon_depth(addon:Any,alias:str,is_bid:bool,price_level:int,size_level:int)->None:"""This function is called each time there is a change in the order book.:param addon:       The addon state object that you received when calling `create_addon`.:param alias:       The alias (name) of the instrument.:param is_bid:      Whether the price level is a bid (True) or an ask (False).:param price_level: The price level of the order book. Multiply it by `pips` to get the price.:param size_level:  The size level of the order book. Divide it by `size_multiplier` to get the size."""add_trades_handler# Call this if you need to receive trade events. Create your own `on_trade` function.bm.add_trades_handler(addon,on_trade)Adds a handler for trade events. It gets called every time a trade happens in the market.
Seesubscribe_to_trades.Example of handler:defhandle_trades(addon:Any,alias:str,price_level:float,size_level:int,is_otc:bool,is_bid:bool,is_execution_start:bool,is_execution_end:bool,aggressor_order_id:Optional[str],passive_order_id:Optional[str])->None:"""This function is called each time a trade happens in the market.:param addon:                The addon state object that you received when calling `create_addon`.:param alias:                The alias (name) of the instrument.:param price_level:          The price of the trade. Multiply it by `pips` to get the price.:param size_level:           The size of the trade. Divide it by `size_multiplier` to get the size.:param is_otc:               Whether the trade is OTC (True) or not (False), can mostly be ignored.:param is_bid:               Whether the trade was a buy (True) or a sell (False).:param is_execution_start:   Whether this is the start of a batch. Can mostly be ignored.:param is_execution_end:     Whether this is the end of a batch. Can mostly be ignored.:param aggressor_order_id:   Which order ID was aggressive. Available only in certain cases, for MBO data.:param passive_order_id:     Which order ID was passive. Available only in certain cases, for MBO data."""add_response_data_handler# Call this to receive a response from Bookmap that data has been successfully subscribed.bm.on_response_data_handler(addon,on_response_data)Called when Bookmap informs your addon that a certain handler has been successfully added. This is
response handler for requests such as:subscribe_to_depth,subscribe_to_trades,subscribe_to_mbo.It is not mandatory to handle it, but receiving response through this handler you can be sure that
your request was received by Bookmap successfully, and data you can expect your other handlers to be
called.Example of handler:defadd_subscribe_data_response_handler(addon:Any,req_id:int)->None:"""Gets called when Bookmap informs your addon that a certain handler has been successfully added.:param addon:  The addon state object that you received when calling `create_addon`.:param req_id: The request id specified in subscribe_* function."""add_on_interval_handler# Call this if you need to receive interval events. Create your own `on_interval` function.bm.add_on_interval_handler(addon,on_interval)Adds an interval event handler. Interval is a special type of event sent by Bookmap to the addon
every 0.1 second. This is useful handler if you have to do some actions (like updating of indicator,
calculating some value) every fixed time interval.Example of handler:defon_interval(addon:Anyalias:str)->None:"""This function is called at each 0.1 second time interval.:param addon: The addon state object that you received when calling `create_addon`.:param alias: The unique instrument name you receive in `handle_subscribe_instrument`."""add_indicator_response_handler# Call this if you need to receive indicator events. Create your own `handle_indicator_response` function.bm.add_indicator_response_handler(addon,handle_indicator_response)Adds a handler responsible that gets called after you create an indicator, in response toregister_indicator).Example of handler:# addon - entity received from create_addon function# request_id - int; id of the request specified in register_indicator function# indicator_id - int; dynamic integer value assigned to each registered indicator to identify it.#                   It is specified during each request to the registered indicator, so it should be remembered.defhandle_indicator_response(addon:Any,request_id:int,indicator_id:int)->None:"""This function is called after you create an indicator, in response to `register_indicator`.:param addon:        The addon state object that you received when calling `create_addon`.:param request_id:   The request id specified in `register_indicator`.:param indicator_id: The indicator id assigned to the indicator."""add_on_settings_change_handler# Call this if you need to receive settings change events. Create your own `on_settings_change_handler` function.bm.add_on_settings_change_handler(addon,on_settings_change_handler)Adds a handler that gets called each time a certain addon settings value is changed by the user.
You should ignore any settings changes which aren't supposed to be handled (TODO: clarify what this
means).Example of handler:liquidity_sizes={}# addon - entity received from create_addon function# alias - string; it defines unique name of respective instrument# fields_type - str; specifies exact type of the field, valid value: "NUMBER", "BOOLEAN", "COLOR", "STRING"# new_value - any; depending on field type can be int, bool, str or tuple representing colordefon_settings_change_handler(addon:Any,alias:str,setting_name:str,field_type:str,new_value:Any)->None:print("Received settings changed "+str(alias)+" "+str(setting_name)+" "+str(field_type)+" "+str(new_value),flush=True)ifsetting_name=="Liquidity size":liquidity_sizes[alias]=int(new_value)add_mbo_handler# Call this if you need to receive market-by-order (MBO) order book events. Create your own# `handle_mbo_event` function.# Only a small subset of exchanges / connectivities support such detailed order book data.bm.add_mbo_handler(addon,on_mbo)Adds handler for MBO events. MBO events are sent in case of provider supports MBO data. Seesubscribe_to_mbo.Example of handler:# addon - entity received from create_addon function# alias - string; it defines unique name of respective instrument# event_type - string; possible values can be#               ASK_NEW - new ASK order,#               BID_NEW - new BID order,#               REPLACE - order updated (size or price is changed),#               CANCEL - order removed# order_id - string; unique order id# price - int; integer price# size - int; integer sizedefon_mbo(addon:Any,alias:str,event_type:str,order_id:str,price_level:int,size_level:int)->None:"""This function is called each time there is a change in the order book.:param addon:       The addon state object that you received when calling `create_addon`.:param alias:       The alias (name) of the instrument.:param event_type:  The type of the MBO event.:param order_id:    The unique order id.:param price_level: The price level of the order book. Multiply it by `pips` to get the price.:param size_level:  The size level of the order book. Divide it by `size_multiplier` to get the size."""add_on_order_executed_handler# Call this if you need to receive events of yours order execution. Create your own# `on_order_executed` function.bm.add_on_order_executed_handler(addon,on_order_executed)Adds handler for order execution events. Seesubscribe_to_order_info.Example of handler:# addon - entity received from create_addon function# alias - string; it defines unique name of respective instrument# event - dictionary; it represents an order execution event. It has this structure:#               orderId: '3427547165' (string value)#               size: 1 (integer value) (size_multiplier applied here)#               price: 29232.3 (floating-point value)#               executionId: '87f74e91935c4b82983b86afeb9edd4a' (string value)#               time: 1691144611797 (integer value)#               isSimulated: False (boolean value)defon_order_executed(addon:Any,alias:str,event:Dict[str,Any])->None:"""This function is called each time there is a change in the order book.:param addon:   The addon state object that you received when calling `create_addon`.:param alias:   The alias (name) of the instrument.:param event:   The event dictionary representing an order execution event with the following keys:- 'orderId': (string) unique order id.- 'size': (int) integer size.- 'price': (float) floating-point price.- 'executionId': (string) execution id.- 'time': (int) integer timestamp.- 'isSimulated': (bool) boolean value representing whether the event is simulated."""add_on_order_updated_handler# Use this method to set up a handler that will be triggered whenever there is an update to one of your orders.# Create your own `on_order_updated` function to process the updated order information.bm.add_on_order_updated_handler(addon,on_order_updated)This function adds a handler for order update events. Whenever there is a change in the status
or attributes of an order, the on_order_updated function will be called.Example of the handler function:# addon - An entity received from the create_addon function# order_update - A dictionary representing the updated order. It has the following structure:#                {#                    'filledChanged': True/False (boolean value),#                    'unfilledChanged': True/False (boolean value),#                    'averageFillPriceChanged': True/False (boolean value),#                    'durationChanged': True/False (boolean value),#                    'statusChanged': True/False (boolean value),#                    'limitPriceChanged': True/False (boolean value),#                    'stopPriceChanged': True/False (boolean value),#                    'stopTriggeredChanged': True/False (boolean value),#                    'modificationTimeChanged': True/False (boolean value),#                    'instrumentAlias': 'TOMOUSDT@BNF' (string value),#                    'orderId': '36392434' (string value), USE THIS ID FOR ANY TRADING RELATED CALLS#                    'isBuy': True/False (boolean value),#                    'type': 'LMT' (string value),#                    'clientId': '36392434' (string value),#                    'doNotIncrease': True/False (boolean value),#                    'filled': 0 (integer value),#                    'unfilled': 5 (integer value),#                    'averageFillPrice': nan (float value),#                    'duration': 'GTC' (string value),#                    'status': 'WORKING' (string value),#                    'limitPrice': 1.0945 (float value),#                    'stopPrice': nan (float value),#                    'stopTriggered': True/False (boolean value),#                    'modificationUtcTime': 1691395710837 (integer value),#                    'isSimulated': False (boolean value),#                    'isDuplicate': False (boolean value)#                }defon_order_updated(addon:Any,order_update:Dict[str,Any])->None:"""This function is called whenever there is an update to one of your orders.:param addon:        The addon state object that you received when calling `create_addon`.:param order_update: The dictionary representing the updated order with various key-value pairs."""Using the add_on_order_updated_handler method, you can conveniently handle and respond to any changes or
updates in your orders within Bookmap.add_on_position_update_handler# Use this method to add a handler for position update events. When a position update occurs,# your custom `on_position_update` function will be called to process the updated position information.bm.add_on_position_update_handler(addon,on_position_update)This function adds a handler for position update events. The on_position_update function will be triggered
within particular interval. This is not a function that will be triggered ONLY if some changes in position
occurred.Example of the handler function:# addon - An entity received from the create_addon function# position_update - A dictionary representing the updated position. It has the following structure:#                   {#                       'instrumentAlias': 'BTCUSDT@BNF' (string value),#                       'unrealizedPnl': -4.179 (float value),#                       'realizedPnl': 1.888 (float value),#                       'position': 2 (integer value),          (size_multiplier applied here)#                       'averagePrice': 29276.95 (float value),#                       'volume': 0 (integer value),            (size_multiplier applied here)#                       'workingBuys': 0 (integer value),#                       'workingSells': 0 (integer value),#                       'isDuplicate': False (boolean value)#                   }defon_position_update(addon:Any,position_update:Dict[str,Any])->None:"""This function is called whenever there is an update to your position in an instrument.:param addon:           The addon state object that you received when calling `create_addon`.:param position_update: The dictionary representing the updated position with various key-value pairs."""With theadd_on_position_update_handlermethod, you can easily manage and respond to any changes in your
positions within Bookmap.add_on_balance_update_handler# Use this method to add a handler for balance update events. When a balance update occurs,# your custom `on_balance_update` function will be called to process the updated balance information.bm.add_on_balance_update_handler(addon,on_balance_update)Theadd_on_balance_update_handlerfunction is used to add a handler for balance update events.
This function allows you to specify a custom function,on_balance_update, that will be called whenever
there is a balance update event.Example of the handler function:# addon - The entity received from the create_addon function.# event - A dictionary representing the balancedefon_balance_update(addon:Any,event:Dict[str,Any])->None:"""This function is called each time there is a balance update event.:param addon:   The addon state object that you received when calling `create_addon`.:param event:   The event dictionary representing a balance update event with the following keys:- 'balancesInCurrency': (list) a list of dictionaries, each representing a currency balance with the following keys:- 'balance': (float) floating-point balance value.- 'realizedPnl': (float) floating-point realized profit and loss.- 'unrealizedPnl': (float) floating-point unrealized profit and loss.- 'previousDayBalance': (float) floating-point balance from the previous day.- 'netLiquidityValue': (float) floating-point net liquidity value.- 'currency': (string) currency code.- 'rateToBase': (float) floating-point exchange rate to the base currency."""Example of dictionary that represents the information about particular currency:'balance': 0.255, 
    'realizedPnl': nan, 
    'unrealizedPnl': nan, 
    'previousDayBalance': nan, 
    'netLiquidityValue': nan, 
    'currency': 'DOGE', 
    'rateToBase': 0.06203By adding anon_balance_updatehandler, you can customize how your addon responds to balance update events,
making it more flexible and tailored to your specific needs.Subscribe data (TODO: Move this higher)Below are examples of how to subscribe to market data. Note that you should always register your
handlersbeforesubscribing to data, otherwise you might miss certain events.The common approach is to trigger any of subscribe related methods fromhandle_subscribe_instrument.Note that Bookmap uses special alias to identify instruments. Hard-coding the alias of instrument
you wish to subscribe is bad error-prone practice. Always use alias received fromhandle_subscribe_instrument.subscribe_to_depth# Call this to subscribe to depth data. The `alias` is the instrument alias you receive in# `handle_subscribe_instrument`. The `req_id` is the request ID you can set yourself to identify# the subscription.bm.subscribe_to_depth(addon,alias,req_id)Sends a request for depth data. Depth data represents a flow of order book updates. Each update
depicts a price level and corresponding size. All depth events are always real time events, except
when first subscribing to depth data, in which case you first receive a snapshot of the order book.
To see how to handle depth events, checkadd_depth_handler.Once this function is triggered, the following two things occur:A message about a successful subscription is sent. It can be handled viaadd_response_data_handler. It will have the samereq_idas the
request.The initial depth events (snapshot) will be sent to reconstruct order book. You will receive many
depth events to populate the latest state of order book.Note that all events are received with integer price and size. See
[Prices and Sizes in Bookmap](#Prices and Sizes in Bookmap) for more details. For more info how to
keep tracking order book state on Python side seecreate_order_book.Sometimes even after getting response, you might not receive depth data even though depth is updated
on Bookmap chart. Often it means that your provider does not report depth data, but instead reports
MBO (market by order) data. Seesubscribe_to_mbo.subscribe_to_mbo# Call this to subscribe to MBO data. The `alias` is the instrument alias you receive in# `handle_subscribe_instrument`. The `req_id` is the request ID you can set yourself to identify# the subscription.bm.subscribe_to_mbo(addon,alias,req_id)Sends a request for depth data represented by MBO events. Each MBO event depicts a change in order
book. It shows a specific order change instead a whole price level change. With MBO data feed order
book can be represented as it is, as a set of independent orders constructing a market. MBO events
are always real time events, except when first subscribing, since you receive a snapshot of the
order book.To handle MBO events seeadd_mbo_handler. General rules applied to this function
are the same as forsubscribe_to_depthi.e. the same response will be sent
once it is subscribed, events for order book reconstruction will be sent as well.Note that depending on the provider, depth data can be sent together with MBO events, i.e. both
depth and MBO data can be supported. However, usually only one mode is supported either depth or
MBO.subscribe_to_trades# Call this to subscribe to trade data. The `alias` is the instrument alias you receive in# `handle_subscribe_instrument`. The `req_id` is the request ID you can set yourself to identify# the subscription.bm.subscribe_to_trades(addon,alias,req_id)Sends a request for trade data. Each trade event represents trade that happened in the market. Each
trade event is always a real time event. It operates in the same way assubscribe_to_depthi.e. it sends a response via special callback
once it is subscribed.subscribe_to_order_info# Use this method to subscribe to order data. The `alias` parameter represents the instrument alias you receive# in the `handle_subscribe_instrument` callback. The `req_id` is an identifier that you can set yourself to# uniquely identify this subscription.bm.subscribe_to_trades(addon,alias,req_id)Sends a request for order data. There are two core events related to your orders: order update and order execute.
Subscribing to order data automatically triggers theon_order_updated_handlerandon_order_executed_handlercallbacks, which are set up using theadd_on_order_updated_handlerandadd_on_order_executed_handlermethods, respectively.subscribe_to_position_updates# Use this method to subscribe to position update events. The `alias` parameter represents the instrument alias you receive# in the `handle_subscribe_instrument` callback. The `req_id` is an identifier that you can set yourself to# uniquely identify this subscription.bm.subscribe_to_position_updates(addon,alias,req_id)This function sends a request to subscribe to position update events. Each position update event provides
information about changes in your position for a specific instrument and is always a real-time event.
Similar to other subscription methods, a response is sent through a special callback once the
subscription is successfully established.Once subscribed to position updates, the system will automatically trigger theon_position_updatecallback,
which is set up using theadd_on_position_update_handlermethod.By utilizing thesubscribe_to_position_updatesmethod, you can stay informed about changes in your positions,
enabling you to make timely decisions and efficiently manage your trading portfolio.subscribe_to_balance_updates# Use this method to subscribe to balance update events. The `alias` parameter represents the instrument alias you receive# in the `handle_subscribe_instrument` callback. The `req_id` is an identifier that you can set yourself to# uniquely identify this subscription.bm.subscribe_to_balance_updates(addon,alias,req_id)Thesubscribe_to_balance_updatesfunction is used to subscribe to balance update events.
This function requires the addon, alias, and req_id parameters to subscribe to balance updates for a
specific instrument. Balance update events provide information about changes in your account
balances and are real-time events.Once subscribed to balance updates, the system will automatically trigger theon_balance_updatecallback, which is set up using theadd_on_balance_update_handlermethod.By utilizing thesubscribe_to_balance_updatesmethod, you can stay informed about changes
in your account balances, enabling you to make timely decisions and efficiently manage your trading portfolio.TradingThe callbacks below will allow you to create custom trading strategies within Python API.
Note that it is mandatory to checkIs trading strategycheckbox to allow addon to trade.send_orderdefsend_order(addon:Dict[str,Any],order_send_parameters:OrderSendParameters)->None:This function allows you to send different types of orders for a specific instrument in Bookmap.Parameters:addon: The addon state object that you received when callingcreate_addon.order_send_parameters: The class that represents an order you want to send.OrderSendParametersTheOrderSendParametersclass is designed to encapsulate the parameters required for placing
different types of trading orders within Bookmap. This class is used in conjunction with thesend_orderfunction to provide flexibility when creating various types of orders for a specific financial instrument.Class Attributes:alias(str): A unique instrument name for the order.is_buy(bool): A boolean value representing whether the order is a buy order (True) or a sell order (False).size(int): An integer representing the quantity of the order to be placed.
The actual size is calculated assize_multiplierfrom thehandle_subscribe_instrumentmultiplied bysize.
For example, if you choose a size multiplier of 0.001 on a specific instrument and setsizeto 5,
the order size will be calculated as 0.001 * 5 = 0.005.limit_price(float, optional): The float value representing the
limit price for limit or stop-limit orders.stop_price(float, optional): The float value representing the stop price for stop or stop-limit
orders.take_profit_offset(int, optional): The offset for setting the take-profit price, if applicable.stop_loss_offset(int, optional): The offset for setting the stop-loss price, if applicable.stop_loss_trailing_step(int, optional): The step value for trailing stop-loss orders, if applicable.take_profit_client_id(str, optional): The client identifier for take-profit orders, if applicable.stop_loss_client_id(str, optional): The client identifier for stop-loss orders, if applicable.duration(str, optional): A string representing the duration of the order (e.g., 'GTC' for Good
'Til Cancelled, 'IOC' for Immediate or Cancel). Supported order types include GTC, ATO, ATC, DAY, DYP,
FOK, GCP, GDP, GTD, GTT, IOC, and GTC_PO. Default is GTC.client_id(str, optional): The client identifier for the order.Constructor:__init__The class constructor initializes theOrderSendParametersobject with the following parameters:alias(str): The unique instrument name for the order.is_buy(bool): A boolean value indicating whether the order is a buy order (True) or a sell order (False).size(int): An integer representing the quantity of the order to be placed.Usage:TheOrderSendParametersclass is used to create an instance with the necessary parameters for a trading order.
Depending on the type of order you want to place, you may set attributes such aslimit_price,stop_price,take_profit_offset,stop_loss_offset,stop_loss_trailing_step,take_profit_client_id,stop_loss_client_id,duration, andclient_id.Example:importbookmapasbm# Creating an OrderSendParameters instance for a limit order to buy 10 units of a BTCUSDT@BNF with a limit price of 50.00order_params=bm.OrderSendParameters("BTCUSDT@BNF",True,10)order_params.limit_price=50.0order_params.duration="GTC"order_params.client_id="Client1"Passing the order_params object to the send_order function to place the orderimportbookmapasbm# Create an OrderSendParameters instance for a limit order to buy 10 units of BTCUSDT@BNF with a limit price of 30000.order_params_limit_buy=bm.OrderSendParameters("BTCUSDT@BNF",True,10)order_params_limit_buy.limit_price=30000# Send the limit buy orderbm.send_order(addon,order_params_limit_buy)# Create an OrderSendParameters instance for a stop-limit order to sell 5 units of# BTCUSDT@BNF with a limit price of 31000 and a stop price of 30500.order_params_stop_limit_sell=bm.OrderSendParameters("BTCUSDT@BNF",False,5)order_params_stop_limit_sell.limit_price=31000order_params_stop_limit_sell.stop_price=30500# Send the stop-limit sell orderbm.send_order(addon,order_params_stop_limit_sell)# Create an OrderSendParameters instance for a stop order to buy 3 units of BTCUSDT@BNF with a stop price of 29000.order_params_stop_buy=bm.OrderSendParameters("BTCUSDT@BNF",True,3)order_params_stop_buy.stop_price=29000# Send the stop buy orderbm.send_order(addon,order_params_stop_buy)cancel_orderdefcancel_order(addon:Dict[str,Any],alias:str,order_id:str,is_batch_end:bool=True,batch_id:int=float("nan"))->None:This function is used to cancel one or multiple orders for a specific instrument in Bookmap.
If you want to cancel several orders in batch, you can specify the is_batch_end and batch_id
arguments. If only order_id is specified, only a single order will be cancelled.
If is_batch_end is set to False, a unique batch_id will be automatically generated.Parameters:addon: The addon state object that you received when callingcreate_addon.alias: The instrument alias (name) for which you want to cancel the order.order_id: The unique identifier of the order to be cancelled. For batch cancellation,
you will need to call severalbm.cancel_orderwith proper specification ofis_batch_endandbatch_id.is_batch_end: A boolean value indicating whether this is the last order to cancel in the batch (default is True).batch_id: (Optional) An integer value representing the batch ID for the order cancellation
(default isfloat("nan")). If not provided, a unique batch ID will be generated automatically.Description:The cancel_order function allows you to efficiently cancel orders for a specific instrument.
By using the batch cancellation feature (is_batch_end=True), you can cancel multiple orders
simultaneously by providing the appropriatebatch_id. Alternatively, setis_batch_end=Falseto generate an automatic batch ID. It is recommended to create your ownbatch_idExample:importbookmapasbm# Cancel a single order with order ID '4567' for instrument 'BTCUSDT@BNF'.bm.cancel_order(addon,'BTCUSDT@BNF','4567')# Cancel multiple orders in batch with order IDs '1234', '2345', '3456' for instrument 'ETHUSDT@BNF'.bm.cancel_order(addon,'ETHUSDT@BNF','1234',is_batch_end=False,batch_id=123)bm.cancel_order(addon,'ETHUSDT@BNF','2345',is_batch_end=False,batch_id=123)bm.cancel_order(addon,'ETHUSDT@BNF','3456',is_batch_end=True,batch_id=123)move_orderdefmove_order(addon:Dict[str,Any],alias:str,order_id:str,limit_price:float,stop_price:float=float("nan"))->None:This function is used to move an existing order for a specific instrument in Bookmap.
By specifying thelimit_priceandstop_price, you can update the order with new values.
Set limit_price tofloat("nan")if the order doesn't have a limit price, and setstop_pricetofloat("nan")if the order doesn't have a stop price (stop_priceis nan by default).Parameters:addon: The addon state object that you received when callingcreate_addon.alias: The instrument alias (name) for which you want to move the order.order_id: The unique identifier of the order to be moved.limit_price: The float value representing the new limit price for the order.
Set it tofloat("nan")if the order doesn't have a limit price.stop_price: (Optional) The float value representing the new stop price for the order.
Set it tofloat("nan")if the order doesn't have a stop price (default isfloat("nan")).Description:The move_order function allows you to update the limit price and stop price of an existing order
for a specific instrument. If you want to modify the limit price only, provide the newlimit_priceand setstop_pricetofloat("nan"). If you want to modify both the limit and stop prices,
provide the new values for bothlimit_priceandstop_price.Example:importbookmapasbm# Move an order with order ID '7890' for instrument 'BTCUSDT@BNF' with a new limit price of 35000.bm.move_order(addon,'BTCUSDT@BNF','7890',35000)# Move an order with order ID '1234' for instrument 'ETHUSDT@BNF' with a new limit price of 1.300 and a new stop price of 1.250.bm.move_order(addon,'ETHUSDT@BNF','1234',1.300,1.250)# Move an order with order ID '4567' for instrument 'XRPUSDT@BNF' with a new stop price of 0.900. Order will no longer be limitbm.move_order(addon,'XRPUSDT@BNF','4567',float("nan"),0.900)resize_orderdefresize_order(addon:Dict[str,Any],alias:str,order_id:str,size:int)->None:This function is used to resize an existing order for a specific instrument in Bookmap.
By specifying thesize, you can update the quantity of the order.Parameters:addon: The addon state object that you received when callingcreate_addon.alias: The instrument alias (name) for which you want to resize the order.order_id: The unique identifier of the order to be resized.size: The integer value representing the new size (quantity) for the order (size_multiplier applied here)Description:The resize_order function allows you to modify the size (quantity) of an existing order for a specific instrument.
By providing the new size, you can increase or decrease the quantity of the order as needed.Example:importbookmapasbm# Resize an order with order ID '7890' for instrument 'BTCUSDT@BNF' to a new size of 15 units.bm.resize_order(addon,'BTCUSDT@BNF','7890',15)# Resize an order with order ID '1234' for instrument 'ETHUSDT@BNF' to a new size of 8 units.bm.resize_order(addon,'ETHUSDT@BNF','1234',8)# Resize an order with order ID '4567' for instrument 'XRPUSDT@BNF' to a new size of 20 units.bm.resize_order(addon,'XRPUSDT@BNF','4567',20)IndicatorsIndicators allow you to draw curves on the Bookmap heatmap or on the bottom chart.register_indicator# Call this method to register a new indicator.## alias:                  str   - The instrument alias you receive in `handle_subscribe_instrument`.# req_id:                 int   - Request id, useful to identify request response.# indicator_name:         str   - Name of the indicator you pick, which will be displayed on Bookmap side.# graph_type:             str   - Where should chart will be drawn, either heatmap of the bottom chart. Valid values: "PRIMARY", "BOTTOM".#                                 PRIMARY - define heatmap indicators, "BOTTOM" - defines subchart indicators.# color:                  tuple - The color of indicator in RGB format (red, green, blue). By default (0,255,0).# line_style:             str   - The style of an indicator line, valid values: "SOLID", "SHORT_DASH","LONG_DASH", "DOT", "DASH_DOT" (by default SOLID).# initial value:          float - The initial indicator value (by default 0.0).bm.register_indicator(addon,alias,req_id,indicator_name,graph_type,color=(0,255,0),line_style="SOLID",initial_value=0.0)The method allows to register an indicator in Bookmap. After calling it, you will receive a
callback inadd_indicator_response_handlerwhich you must handle.
That response containsindicator_idinteger value, which is used to identify the indicator.
Every indicator in scope of a single addon run will have a unique ID, across all instruments.A certain instrument is allowed to have multiple indicators.add_point# Call this method to add a new point (value) to the indicator. The `alias` is the instrument alias# you receive in `handle_subscribe_instrument`. The `indicator_id` is the indicator ID you receive# in `handle_register_indicator`. The `point` should be the latest value of the indicator you want# to set.bm.add_point(addon,alias,indicator_id,point)This function draws a new indicator point. Note that the point should be the price you want to draw
at the current time but you have to multiply it divide itpipsin order to convert it to the price
level.In other words, if you want to draw your indicator on the primary chart (heatmap) at price $1,100,
and the instrument'spipsvalue is 0.01, you have to setpointto 11,000.See alsoPrices and Sizes in Bookmap.Addon SettingsSee below how to create your custom addon settings that get displayed on the addon config panel.
Each user can set different values for each setting.For example, you can add a setting which controls the minimum trade size acceptable by your addon.All settings are per alias, so it is recommended to specify them in instrument callback. Seestart_addonfor details.Supported setting types:NumberStringBooleanColorNote that settings will be saved to the Bookmap's workspace, so no need to specify exact value every
time you restart Bookmap.Each UI change of a certain setting value is handled via a special handler added usingadd_on_settings_change_handler.add_number_settings_parameter# Call this method to add a new number settings parameter.## alias:            str   - The instrument alias you receive in `handle_subscribe_instrument`.# parameter_name:   str   - The name of the parameter (will be displayed in the config panel).# default_value:    float - The default value of the parameter.# minimum:          float - The minimum allowed parameter value.# maximum:          float - The maximum allowed parameter value.# step:             float - The minimum allowed step between values.bm.add_number_settings_parameter(addon,alias,parameter_name,default_value,minimum,maximum,step)Adds a number settings parameter to the addon. Allows you to have and configure through UI a number parameter.add_boolean_settings_parameter# Call this method to add a new boolean settings parameter.## alias:            str   - The instrument alias you receive in `handle_subscribe_instrument`.# parameter_name:   str   - The name of the parameter (will be displayed in the config panel).# default_value:    bool  - The default value of the parameter.bm.add_boolean_settings_parameter(addon,alias,parameter_name,default_value)Adds a checkbox with a label (parameter name) to the configuration panel.add_string_settings_parameter# Call this method to add a new string settings parameter.## alias:            str   - The instrument alias you receive in `handle_subscribe_instrument`.# parameter_name:   str   - The name of the parameter (will be displayed in the config panel).# default_value:    str   - The default value of the parameter.bm.add_string_settings_parameter(addon,alias,parameter_name,default_value)Adds named string configuration field.add_color_settings_parameter# Call this method to add a new color settings parameter.## alias:            str   - The instrument alias you receive in `handle_subscribe_instrument`.# parameter_name:   str   - The name of the parameter (will be displayed in the config panel).# default_value:    tuple - The default value of the parameter in RGB format (red, green, blue).bm.add_color_settings_parameter(addon,alias,parameter_name,default_value)Adds a color selection field to the configuration panel.Utilscreate_order_book# Call this method to create an order book entity.order_book=bm.create_order_book()This function creates a data structure object that represents an order book (non-MBO). It is a
helper for dealing with tracking the order book.bm.create_order_book()returns a dictionary
representing bids and asks price levels. The dictionary contains two keys: "bids" and "asks".Value for each pair is aSortedDict.
Each sorted dict is a dictionary of keys representing price levels (which are integers) and values
representing size (TODO: size levels?). It is sorted by keys, i.e. by price (TODO: are bids reverse
sorted?). You never should write to this dictionary directly, and normally you do not read from it
directly as well.on_depth# Call this method to update your order book object with a new depth event.bm.on_depth(order_book,is_bid,price_level,size_level)This function updates the order book object according to received depth event.get_bbo# Call this method to get the current best bid and ask levels.# Returns ((best_bid, bid_size), (best_ask, ask_size)), or None instead of side tuple.(best_bid_price_level,best_bid_size_level),(best_ask_price_level,best_ask_size_level)=bm.get_bbos(order_book)This function is used to get best bid and ask levels at the current moment.get_sum# Call this method to get the sum of size levels up to `levels_num` levels, per side.# Returns (bids sum, asks sum).bids_size_levels_sum,asks_size_levels_sum=bm.get_sum(order_book,levels_num)Returns the sum of size levels per side, up tolevels_numlevels, where each level is onepips.For example, iflevels_numis 5, then the function will return the sum of size levels of 5 first
price levels, separately for bids and asks.Iflevels_numis 1, you will receive size levels at the best bid and ask (same size levels asget_bboreturns).Note that a certain price level will be taken into account even if it has a zero size level. For
example, iflevels_numis 2, and best bid is at price level 100 of size level 1, 99 is empty,
the method will compute1 + 0and return1.create_mbo_book()# Call this method to create an MBO order book entity.mbo_order_book=bm.create_mbo_book()This function creates a data structure object that represents a MBO order book. It is a
helper for dealing with tracking the MBO order book.bm.create_mbo_book()returns a dictionary
representing orders in the order book.The first key is"orders", it containsSortedDictwhere keys are order
ids and values are tuple with info about order,(side: bool, price: int, size: int).The second key is"mbp_book". It is possible to this MBP order book (it's same to the one created
viacreate_order_book).on_new_order# Call this method to update your MBO order book object with a new order event.bm.on_new_order(mbo_order_book,order_id,is_bid,price_level,size_level)Use this function when receiving a new MBO event with theASK_NEWorBID_NEWevent type.
Seeadd_mbo_handlerfor more details.The order ID must not yet exist inmbo_order_book.ValueError` will be raised otherwise.on_replace_order# Call this method to update your MBO order book object with a replace order event.bm.on_replace_order(mbo_order_book,order_id,new_price,new_size)Use this function when receiving a new MBO event with theREPLACEevent type. Seeadd_mbo_handlerfor more details.The order ID must exist inmbo_order_book.ValueErrorwill be raised otherwise.on_remove_order# Call this method to update your MBO order book object with a remove order event.bm.on_remove_order(mbo_order_book,order_id)Use this function when receiving a new MBO event with theCANCELevent type. Seeadd_mbo_handlerfor more details.The order ID must exist inmbo_order_book.ValueErrorwill be raised otherwise.get_all_order_ids# Call this method to get all order IDs in the order book.all_order_ids=bm.get_all_order_ids(mbo_order_book)This function returns all order ids registered in the order book.has_order# Call this method to check if the order with specified order id exists in the order book.bm.has_order(mbo_order_book,order_id)This function returns true if the order with specified order ID exists.get_order# Call this method to get order info by order id.order_info_or_none=bm.get_order(mbo_order_book,order_id)iforder_info_or_noneisnotNone:side,price_level,size_level=order_info_or_noneThis function returns side, price level and size level in tuple if order with the specified order ID
exists, otherwise it returns None.get_order_price# Call this method to get price level of a certain order ID.price_level=bm.get_order_price(mbo_order_book,order_id)This function returns the order's price level, or raisesValueErrorif there is no such order.get_order_size# Call this method to get size level of a certain order ID.size_level=bm.get_order_size(mbo_order_book,order_id)This function returns the order's size level, or raisesValueErrorif there is no such order.get_order_side# Call this method to get side of a certain order ID.side=bm.get_order_side(mbo_order_book,order_id)This function returns order side, True if bid, otherwise False. ThrowValueErrorif there is no such order.