⚙️Trading Mechanics

Creating Requests

There are 4 main types of orders that can be created on the platform:

  1. Market Orders

  2. Market Orders with Conditionals (Stop Loss / Take Profit)

  3. Limit Orders

  4. Conditional Orders (Standalone Stop Loss / Take Profit)

All orders are created by calling the createPositionRequest function on the Router smart contract.

solidity

function createPositionRequest(
        MarketId _id,
        Position.Input memory _trade,
        Position.Conditionals calldata _conditionals
    ) external payable returns (bytes32 orderKey)

Parameters:

  • MarketId _id:

  • Position.Input memory _trade: This struct contains the details about the trade itself. See a detailed breakdown of the inner parameters below.

  • Position.Conditionals calldata _conditionals: This struct contains the details about the conditional orders for when orders are of type 2. The inner parameter breakdown can also be found below.

_trade parameters:

solidity

struct Input {
        string ticker; // Asset ticker, e.g ETH:1
        address collateralToken;
        uint256 collateralDelta;
        uint256 sizeDelta; // USD
        uint256 limitPrice;
        uint128 maxSlippage; // 30 D.P Ratio
        uint64 executionFee;
        bool isLong;
        bool isLimit;
        bool isIncrease;
        bool reverseWrap;
        bool triggerAbove; // For Limits -> Execute above the limit price, or below it
    }
  • ticker: The custom id of the asset being traded. Custom ids are structed as TICKER:MARKET_CAP_RANK. So the largest "ETH" ticker by market cap would have the custom id: "ETH:1" and so on.

  • collateralToken: The address of the token being used as collateral. This will be either the WETH or USDC contract address.

  • collateralDelta: The amount of collateral being provided in the respective token's base units. E.g 1 Ether = 1000000000000000000.

  • sizeDelta: The size in usd of the position to 30 decimal places. Where 1 USD = 1e30. The collateralDelta and sizeDelta must be structured so that the leverage of the market during execution is within the accepted range. For example, if the max leverage is 1000, the value of sizeDelta / collateralDeltaInUsd cannot exceed 1000.

  • limitPrice: For limit orders, this represents the price at which the limit order should execute to 30 decimal places. So if the order should execute at a price of $2500, the correct input would be 2.5e33. For non-limit orders, this can remain as 0.

  • maxSlippage: This is a ratio to 30 decimal places for the maximal percentage of price impact that can be applied to the order, and it still go through. 1e30 represents 100%, and so on. If the slippage of the position exceeds the maxSlippage, the order won't be executable.

  • executionFee: The amount, in wei to be paid to the keeper who executes the order. Similarly to liquidity provision, this value can be obtained from the Gas library, by calling getExecutionFees

  • isLong: A boolean indicating whether the position should be a long position or short position.

  • isLimit: A boolean indicating whether the position should be a limit order or not.

  • isIncrease: A boolean indicating whether the position should be an increase (covers new position creation and increasing of existing positions), or it should decrease / close an existing position.

  • reverseWrap: A boolean indicating whether ETH / WETH should be wrapped or unwrapped. If the position is an increase and ETH is passed in, it will be wrapped for WETH. If the position is a decrease, the WETH will be unwrapped for ETH, and ETH will be sent to the user.

  • triggerAbove: For conditional / limit orders, this boolean will determine whether the limit order will trigger above, or below the limit price.

_conditionals parameters:

solidity

struct Conditionals {
        bool stopLossSet;
        bool takeProfitSet;
        uint64 stopLossPercentage;
        uint64 takeProfitPercentage;
        uint256 stopLossPrice;
        uint256 takeProfitPrice;
    }
  • stopLossSet: A boolean indicating whether to attempt to attach a stop loss order to the position request or not. This will only work if the position is a market order, and it's creating a new position as opposed to increasing / decreasing an existing position.

  • takeProfitSet: Similarly to stopLossSet, this will indicate whether to attach a take profit order or not.

  • stopLossPercentage: This represents the percentage the position should be decreased by for the stop loss order. The percentage has 18 decimal places, with 100% being equal to 1e18, 50% being equal to 0.5e18 and so on.

  • takeProfitPercentage: Similarly to stopLossPercentage, this determines the percentage of the position that will be taken as profit in the take profit scenario.

  • stopLossPrice: The price at which the stop loss should execute at, to 30 decimal places. So a price of $2500 would be represented as 2.5e33.

  • takeProfitPrice: The price at which the take profit should execute at, to 30 decimal places. So a price of $2500 would be represented as 2.5e33.

Note: The value provided must equal the executionFee + the collateral delta, or the function will revert.

Executing Requests

There are different execution paths. The market order execution path, and the limit / conditional order execution path. The former requires 1 simple step, and the latter requires a total of 2 steps.

Market Order Execution

Market orders can be executed immediately after creation, provided that a price has been signed. To execute a market order, simply call the executePosition function on the PositionManager smart contract:

solidity

function executePosition(  
    MarketId _id,  
    bytes32 _orderKey,  
    bytes32 _requestKey,  
    address _feeReceiver  
) external payable;

Parameters:

  • MarketId _id: The ID of the market where the position is being executed.

  • bytes32 _orderKey: For market orders, you can pass bytes32(0) as this is only required for limit orders.

  • bytes32 _requestKey: For market orders, you can pass bytes32(0) as this is only required for limit orders.

  • address _feeReceiver: The address that will receive any fees associated with the execution.

Note: It's crucial that a price has been signed before calling this function for market orders.

Limit Order Execution

Executing a limit order is a two-step process:

  1. Request execution pricing

  2. Execute the position

Step 1: Request Execution Pricing:

Before executing a limit order, you must first call the requestExecutionPricing function on the Router smart contract:

function requestExecutionPricing(  
    MarketId _id,  
    bytes32 _key,  
    bool _isPositionKey  
) external payable returns (bytes32 priceRequestKey);

Parameters:

  • MarketId _id: The ID of the market where the limit order is placed.

  • bytes32 _key: The order key of the limit order.

  • bool _isPositionKey: Should be set to false for limit orders.

Returns:

  • bytes32 priceRequestKey: A unique key for the price update request.

Note: This function is payable and requires a fee to cover the cost of the price update. Ensure you send enough ETH to cover the priceUpdateFee.

Step 2: Execute the Position

After requesting the execution pricing, wait for a price to be signed. Once the price is signed, you can proceed to execute the limit order by calling the executePosition function:

solidity

function executePosition(  
    MarketId _id,  
    bytes32 _orderKey,  
    bytes32 _requestKey,  
    address _feeReceiver  
) external payable;

Parameters:

  • MarketId _id: The ID of the market where the limit order is being executed.

  • bytes32 _orderKey: The order key of the limit order.

  • bytes32 _requestKey: The price request key returned from the requestExecutionPricing function.

  • address _feeReceiver: The address that will receive any fees associated with the execution.

By following these steps, you can successfully execute both market orders and limit orders on the platform.

Last updated