Trade State
Learn about the structures representing requests for trade changes and trades themselves (called Positions and PositionRequests) on Imperial.
Position Request
Every Position starts life as a PositionRequest. This object is submitted by a user-originated transaction that is constructed by the front-end. If it is valid along every dimension, it will either result in the creation a new Position for the user's wallet or change an existing Position, potentially even closing one, partially or completely.
Ultimately, you use this structure to open/increase/close/partially close a Position over a time window. This window is future-facing for Implied Volatility, past-facing for Realized Volatility, and past-facing for RV-IV where IV is the IV at the beginning of the moving window.
Some of the fields in PositionRequest were inherited from the Jupiter design in an attempt to maintain some backwards compatibility with bots that may work with Jupiter. Some fields are also unused, and may be used as we add more functionality in the future (like trigger orders).
#[account]
pub struct PositionRequest {
pub owner: Pubkey,
pub request_payer: Pubkey,
pub pool: Pubkey,
pub collateral_custody: Pubkey,
pub mint: Pubkey,
pub open_time: i64,
pub update_time: i64,
pub size_usd_delta: u64,
pub collateral_delta: u64,
pub request_change: u8, // unused
pub request_type: RequestPositionType, // Somewhat misused as similar to request_change
pub side: Side,
pub entry_value: i32, // Entry value seen by trader to compare against oracle
pub vol_slippage: u32, // how much slippage against oracle is acceptable (bps)
pub time_window: String, // 1d 1w 2w 30d 60d 90d
pub jupiter_minimum_out: u64, // unused legacy field from Jupiter
pub pre_swap_amount: u64, // unused
pub trigger_price: u64, // unused
pub trigger_above_threshold: bool, // unused
pub decrease_type: DecreasePositionType,
pub executed: bool, // unused
pub counter: u64, // unused
pub total_fees: u64,
pub lamports: u64,
pub product: Product,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Debug)]
pub enum RequestPositionType {
Increase = 0,
Decrease = 1,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Debug)]
pub enum DecreasePositionType {
None = 0,
EntirePosition = 1,
CollateralOnly = 2,
PartialProportional = 3,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Debug)]
pub enum Side {
Long,
Short,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Debug)]
pub enum Product {
Iv,
Rv,
RvDiffIv,
}
Position
Once a PositionRequest has been converted by an off-chain crank via transaction, a Position is updated or created or closed. Here is it's structure:
#[account]
pub struct Position {
pub owner: Pubkey,
pub position_payer: Pubkey,
pub pool: Pubkey,
pub collateral_custody: Pubkey,
pub open_time: i64,
pub update_time: i64,
pub side: Side,
pub entry_value: i32,
pub time_window: String,
pub size_usd: u64,
pub collateral_usd: u64,
pub realised_pnl_usd: i64,
pub cumulative_interest_snapshot: u64,
pub locked_amount: u64,
pub max_size: u64,
pub short_long_mismatch_borrow_modifier_bps: u64,
pub leverage_modifier_bps: u64,
pub product: Product,
}
Notably, a different person can pay for the Position lamports (and will be paid back for it) than the actual owner of the Position. The size_usd contains the entire loan + collateral of the Position, and realized_pnl_usd will be updated whenever a withdrawal occurs. cumulative_interest_snapshot will be updated whenever an update_position call is made (ie a PositionRequest is executed) and is used to calculate the updated interest to apply to the Position.
Also note that max_size contains the total allowable value the Position can take in it's lifetime, collateral + loan + profit, and it will decrease as fees or withdrawals occur. locked_amount is some fraction of this amount and is the tokens set aside from the collateral_custody that are guaranteed to be paid out before the insurance of the collateral_custody steps in and before impairment losses occur to the collateral_custody after that per the payout rules.
The short_long_mismatch_borrow_modifier_bps is a fraction used to modify the borrow fee to incentivize contrarians to make larger bets to offset profits made by the more obvious trades and is derived from some simple math by the long/short ratio in the Pool, see here.
Finally, the leverage_modifier_bps is a similar modifier to short_long_mismatch_borrow_modifier_bps that modifies the base max_leverage to grant contrarians to take out more leverage than those taking more obvious trades.
Last updated