🌊
Example Trade Flow

Opening a trade in detail

Let us walk through the example of a user buying a call from the market. We use the terminology quote to represent the unit of pricing a base asset that is having options traded against it.
Before any trading can happen, it is necessary to provide liquidity and create the listings.
Note: For the sake of simplicity, we have removed units from these function calls. In reality, these values would be multiplied by the unit of the tokens (1e18).

Seeding liquidity

As an LP we add some initial liquidity to the pool with the following function:
liquidityPool.deposit(500_000);
After there is liquidity in the pool, the contact owner creates an option board, which is a group of listings with the same expiry time.
optionMarket.createOptionBoard(now() + MONTH_SEC, 1, [1500, 2000, 2500], [0.9, 1, 1.1]);
This will lock all current LP funds from exiting the system until the expiry timestamp passes. Also, no new funds can provide liquidity to the system until this timestamp (maxExpiryTimestamp) passes. Liquidity can be deposited, but will only be used when the next round begins.

Purchasing Options

So given three listings to trade, each with a different strike price. A trader wants to buy a call on the $1500 strike listing. There are four parameters for the function openPosition.
openPosition(uint _listingId, bool isLong, bool isCall, uint amount)
  • _listingId refers to the relevant listing.
  • isLong refers to whether the user is buying from the market (long) or selling to the market (short)
  • isCall refers to whether or not the user is trading a call or a put.
  • amount is the number of options the user wants to trade.
In this case, _listingId would be 1, since it is the first listing we created. We want isLong to be true, since we are buying from the market, and isCall to be true, since we want a call option. For the amount variable, we are going to just buy 1 option.
optionMarket.openPosition(1, true, true, 1);
We can now verify that the trade was executed successfully by querying the call balance, passing in the _listingId and the address of the trader.
optionMarket.getListingToUserToCallAmount(1, accountAddress);
This call will return a value of 1.
Similarly, to close the position, we need to call OptionMarket.closePosition.
The parameters will be the same as openPosition. Since we bought 1 option, we would pass 1 in as the amount to close.
optionMarket.closePosition(1, true, true, 1);
We can verify that we have successfully closed this trade by once again querying the call balance, which should now return a value of 0.
optionMarket.getListingToUserToCallAmount(1, accountAddress);

Types of positions

There are four distinct types of options that can be purchased. These are:
  1. 1.
    Long Call: User buys a call from the AMM.
  2. 2.
    Long Put: User buys a put from the AMM.
  3. 3.
    Short Call: User sells a call to the AMM.
  4. 4.
    Short Put: User sells a put to the AMM.
When users go long, they are buying an option from the system. They must pay the system for the option. When users go short, they are selling an option to the system. The system pays them for the option. However they must provide collateral for the option.

Detailed flow

When users call openPosition(), a number of steps occur to allow the AMM to correctly price options.
Firstly, the system works out what the imapct of the trade is on the option's implied volatility (iv) and what the total cost of this option will be after iv has been scaled. This is handled by another contract named OptionPricer. Before going further, it is important to note that pricing does not distinguish whether a position is being opened or closed, but rather which way the option is flowing. I.e.
  • isBuy = true signifies that a long is being opened OR a short is being closed. Option are flowing from the system to user.
  • isBuy = false signifies that a short is being opened OR a long is being closed. Options are flowing from the user to system.
When computing the price using BlackScholes, aggregate values of the netDelta and netStdVega positions of the system are stored in the OptionGreekCache contract.
Locking Collateral
Once the trade impact and cost have been determined, the system then handles the collateralization of the option being traded. When the users open long positions, the system locks collateral in the LiquidityPool. In the event that the option finishes in the money, the profits will be distributed from this collateral.
When users open short positions, the system takes collateral from the user and locks it in the OptionMarket. This gives the system the right to exercise its option, should it expire in the money.
Recap
To summarise, opening a position includes five distinct steps:
  1. 1.
    Record the amount of options being traded by the user.
  2. 2.
    Workout IV impact and get the total cost.
  3. 3.
    Update the OptionGreekCache
  4. 4.
    Lock the collateral needed to collateralise the option.
  5. 5.
    Transfer the cost from the purchaser to the seller.

Cost and payouts for Opening/closing/liquidating different types options

Long Call (user is buying a call from the market)

To open:
  • User must send the cost of the options to the LiquidityPool in quoteAsset
  • LiquidityPool locks amount baseAsset. This is converted from quoteAsset.
To close:
  • User receives the cost of the options in quoteAsset
  • LiquidityPool frees amount in baseAsset. This is converted to quoteAsset.
At liquidation:
  • If spot > strike:
    • amount * (spot - strike) quoteAsset is reserved per option to pay out to the user

Long Put (user is buying a put from the market)

To open:
  • User must send the cost of the options to the LiquidityPool in quoteAsset.
  • LiquidityPool locks amount * strike in quoteAsset.
To close:
  • User receives the cost of the options in quoteAsset
  • LiquidityPool frees amount * strike in quoteAsset.
At liquidation:
  • If strike > spot:
    • amount * (strike - spot) quoteAsset is reserved per option to pay out to the user

Short Call (user is selling a call to the market)

To open:
  • User sends the amount baseAsset to the OptionMarket
  • User receives the cost of the options in quoteAsset from LiquidityPool
To close:
  • User sends the cost of the options in quoteAsset to LiquidityPool
  • User receives amount of baseAsset from the OptionMarket
At liquidation:
  • If spot > strike:
    • amount * (spot - strike) quoteAsset is sent to the LP from the user's collateral (a portion of the baseAsset collateral is sold)
    • The remainder of baseAsset is reserved to pay back to the user
  • Else
    • amount baseAsset is reserved to pay back to the user per option

Short Put (user is selling a call to the market)

To open:
  • User sends amount * strike in quoteAsset to the OptionMarket as collateral
  • User receives the cost of the options in quoteAsset from LiquidityPool
To close:
  • User sends the cost of the options in quoteAsset to LiquidityPool
  • User receives back amount * strike in quoteAsset from the OptionMarket
At liquidation:
  • If strike > spot
    • amount * (strike - spot) quoteAsset per option is taken from the user's collateral
    • amount * spot is reserved for the user in quoteAsset
  • Else
    • amount * strike is reserved for the user in quoteAsset
Last modified 1mo ago