Placing an Order

To interact with a given market, a wallet will first need a UserMarket account to be created on-chain so that the wallet's orders and positions can be stored and updated.

Generate or Load a UserMarket Account

A User-Market Account (UMA) stores a given wallet's matched and unmatched orders on-chain.

A UMA must be initialized before a wallet can interact with a market, so that the orders placed by that wallet can be stored.

There are some optional parameters to consider when initializing a UMA - for example, allocating a particular number of slots for how many unmatched orders can remain open in this market at the same time.

i.e. - a typical user may only need a few, while a market maker may wish to have capacity to place several orders per outcome and side.

The method used here will first check whether a UMA already exists for this wallet and market, and if so, load that. Otherwise, if not, it will handle the process to create one.

from pyaver.user_market import UserMarket

uma = await UserMarket.get_or_create_user_market_account(
    aver_client = client,
    owner = owner_keypair,
    market = market,
    number_of_orders = (3 * market.market_state.number_of_outcomes) # Optional argument
)

print(f'UMA created with pubkey {uma.pubkey}')

It's possible to read information related to your wallets interaction with this market directly from the UMA.

This includes:

  • Positions/exposures to each of the outcomes in the market

  • Broken down by positions which are 'free' (i.e. held outright, available to trade or hold) and 'locked' (those which are held to back an open order)

  • List of open/unmatched orders which are currently posted on the book

  • Idle funds (if applicable) - where the user has residual money in a market which is no longer required to back a matched/unmatched bet.

You can read more about the properties and methods within the UserMarket object here.

Place an Order

Placing an order is called from a UserMarket object, as it is this object which will store the order (if posted) and/or record the resulting positions/exposures from the order being matched.

The uma.place_order() has a number of required arguments, and some optional arguments. Each of these is elaborated upon in more detail here:

  • Owner - This is the keypair of the UserMarket's owning wallet. The keypair is required to be passed, as the place_order() method sends a transaction requiring signing.

  • Outcome_id - This is the integer index corresponding to the outcome within the market which the order relates to.

  • Side - Specifies whether the order is to buy/back or to sell/lay.

  • Limit_price - This is the maximum (in the case of a buy/back) or minimum (in the case of sell) price at which the order should be matched. This argument is required in probability price format (ranging from 0 to 1).

  • Size_format - Specifies whether the order is being specified in terms of stake (amount to pay for a buy/back, or receive for a sell/lay) or in terms of the number of payout units to be exchanged.

  • Size - Specifies the maximum size of the order to match (in the format specified in size_format above)

Limit_price must be provided in probability price format (i.e. a value in the range 0 to 1). If you are used to trading in Decimal odds (or another format), a simple conversion will be required prior to calling this method.

  • Probability Price = 1 / Decimal Odds

from pyaver.enums import Side, SizeFormat

txn_signature = await uma.place_order(
  owner = owner_keypair, 
  outcome_id = 0,                        
  side = Side.BUY,                        
  limit_price = 0.5,                     
  size_format = SizeFormat.PAYOUT,    
  size = 10                     
)

# Optionally wait to ensure transaction has been confirmed before moving on
await client.provider.connection.confirm_transaction(txn_signature['result'], Confirmed)

There are a number of other optional arguments which can be used to exercise more control over the order specification or execution:

  • Order_type - You can read more about this parameter here.

  • Self_trade_behavior - You can read about this parameter here.

  • Active_pre_flight_checks - This toggles on and off validations performed client side, which are intended to identify issues which may lead to the order being forbidden by the program.

Market Orders - Market orders can be achieved by setting the limit_price to:

  • 1.0 in the case of a buy/back order

  • 0.0 in the case of a sell/lay order

and setting the (optional) parameter order_type = KILL_OR_FILL or IOC

Currently, market orders can only be supported when size_format = PAYOUT.

Orders with limit_price = 1 or 0 which do not have order_type = KILL_OR_FILL or IOC and size_format = PAYOUT will be aborted by the program.

Refreshing Information

After you've taken an action (such as placing and order) you may wish to view your updated positions and open orders.

Please see the Refreshing Information section which discusses the most efficient/optimized way to refresh information and synchronize your client-side state with on-chain state.

Last updated