Skip to content

Commit

Permalink
program: flag to set max leverage for spot orders (#346)
Browse files Browse the repository at this point in the history
* program: flag to set max leverage for spot orders

* allow max leverage flag for perps

* add ts test

* fix lint issue

* fix tick/step size mix up
  • Loading branch information
crispheaney authored Feb 6, 2023
1 parent 6dbbc1a commit b1ff36f
Show file tree
Hide file tree
Showing 10 changed files with 1,434 additions and 41 deletions.
54 changes: 38 additions & 16 deletions programs/drift/src/controller/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ pub fn place_perp_order(

// Increment open orders for existing position
let (existing_position_direction, order_base_asset_amount) = {
let market_position = &mut user.perp_positions[position_index];
market_position.open_orders += 1;

validate!(
params.base_asset_amount >= market.amm.order_step_size,
ErrorCode::OrderAmountTooSmall,
Expand All @@ -186,8 +183,22 @@ pub fn place_perp_order(
market.amm.order_step_size
)?;

let base_asset_amount =
standardize_base_asset_amount(params.base_asset_amount, market.amm.order_step_size)?;
let base_asset_amount = if params.base_asset_amount == u64::MAX {
calculate_max_perp_order_size(
user,
position_index,
params.market_index,
params.direction,
perp_market_map,
spot_market_map,
oracle_map,
)?
} else {
standardize_base_asset_amount(params.base_asset_amount, market.amm.order_step_size)?
};

let market_position = &mut user.perp_positions[position_index];
market_position.open_orders += 1;

if !matches!(
&params.order_type,
Expand Down Expand Up @@ -2626,6 +2637,7 @@ pub fn place_spot_order(
let market_index = params.market_index;
let spot_market = &spot_market_map.get_ref(&market_index)?;
let force_reduce_only = spot_market.is_reduce_only()?;
let step_size = spot_market.order_step_size;

validate!(
!matches!(spot_market.status, MarketStatus::Initialized),
Expand All @@ -2639,36 +2651,46 @@ pub fn place_spot_order(

let oracle_price_data = *oracle_map.get_price_data(&spot_market.oracle)?;
let (worst_case_token_amount_before, _) = user.spot_positions[spot_position_index]
.get_worst_case_token_amounts(spot_market, &oracle_price_data, None)?;
.get_worst_case_token_amounts(spot_market, &oracle_price_data, None, None)?;

let balance_type = user.spot_positions[spot_position_index].balance_type;
let token_amount = user.spot_positions[spot_position_index].get_token_amount(spot_market)?;
let signed_token_amount = get_signed_token_amount(token_amount, &balance_type)?;

// Increment open orders for existing position
let (existing_position_direction, order_base_asset_amount) = {
let spot_position = &mut user.spot_positions[spot_position_index];
spot_position.open_orders += 1;

validate!(
params.base_asset_amount >= spot_market.order_step_size,
params.base_asset_amount >= step_size,
ErrorCode::InvalidOrderSizeTooSmall,
"params.base_asset_amount={} cannot be below spot_market.order_step_size={}",
params.base_asset_amount,
spot_market.order_step_size
step_size
)?;

let base_asset_amount =
standardize_base_asset_amount(params.base_asset_amount, spot_market.order_step_size)?;
let base_asset_amount = if params.base_asset_amount == u64::MAX {
calculate_max_spot_order_size(
user,
params.market_index,
params.direction,
perp_market_map,
spot_market_map,
oracle_map,
)?
} else {
standardize_base_asset_amount(params.base_asset_amount, step_size)?
};

validate!(
is_multiple_of_step_size(base_asset_amount, spot_market.order_step_size)?,
is_multiple_of_step_size(base_asset_amount, step_size)?,
ErrorCode::InvalidOrderNotStepSizeMultiple,
"Order base asset amount ({}), is not a multiple of step size ({})",
base_asset_amount,
spot_market.order_step_size
step_size
)?;

let spot_position = &mut user.spot_positions[spot_position_index];
spot_position.open_orders += 1;

if !matches!(
&params.order_type,
OrderType::TriggerMarket | OrderType::TriggerLimit
Expand Down Expand Up @@ -2754,7 +2776,7 @@ pub fn place_spot_order(
user.orders[new_order_index] = new_order;

let (worst_case_token_amount_after, _) = user.spot_positions[spot_position_index]
.get_worst_case_token_amounts(spot_market, &oracle_price_data, None)?;
.get_worst_case_token_amounts(spot_market, &oracle_price_data, None, None)?;

let order_risk_decreasing =
is_spot_order_risk_decreasing(&user.orders[new_order_index], &balance_type, token_amount)?;
Expand Down
23 changes: 19 additions & 4 deletions programs/drift/src/math/margin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::state::user::{PerpPosition, SpotPosition, User};
use num_integer::Roots;
use solana_program::msg;
use std::cmp::{max, min, Ordering};
use std::ops::Neg;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -332,11 +333,21 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
}
}
} else {
let signed_token_amount = spot_position.get_signed_token_amount(&spot_market)?;
let (worst_case_token_amount, worst_cast_quote_token_amount): (i128, i128) =
spot_position.get_worst_case_token_amounts(
&spot_market,
oracle_price_data,
None,
if strict {
Some(
spot_market
.historical_oracle_data
.last_oracle_price_twap_5min,
)
} else {
None
},
Some(signed_token_amount),
)?;

if worst_case_token_amount == 0 {
Expand All @@ -349,9 +360,9 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
)?;
}

let worst_case_token_value = if strict {
let signed_token_value = if strict {
get_strict_token_value(
worst_case_token_amount,
signed_token_amount,
spot_market.decimals,
oracle_price_data,
spot_market
Expand All @@ -360,12 +371,16 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
)?
} else {
get_token_value(
worst_case_token_amount,
signed_token_amount,
spot_market.decimals,
oracle_price_data.price,
)?
};

// the worst case token value is the deposit/borrow amount * oracle + worst case order size * oracle
let worst_case_token_value =
signed_token_value.safe_add(worst_cast_quote_token_amount.neg())?;

margin_requirement =
margin_requirement.safe_add(spot_position.margin_requirement_for_open_orders()?)?;

Expand Down
Loading

0 comments on commit b1ff36f

Please sign in to comment.