Skip to content

Commit

Permalink
add test for calculate_limit_price_with_buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
crispheaney committed Oct 19, 2023
1 parent 971632b commit 4dd470a
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 20 deletions.
1 change: 1 addition & 0 deletions programs/drift/src/controller/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3910,6 +3910,7 @@ pub mod fulfill_order {
slot,
0,
true,
FillMode::Fill,
)
.unwrap();

Expand Down
50 changes: 30 additions & 20 deletions programs/drift/src/math/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,44 +71,54 @@ pub fn calculate_base_asset_amount_for_amm_to_fulfill(
return Ok((0, limit_price));
}

let limit_price_with_buffer = if !order.post_only {
limit_price
let limit_price_with_buffer =
calculate_limit_price_with_buffer(order, limit_price, fee_tier, market.fee_adjustment)?;

let base_asset_amount = calculate_base_asset_amount_to_fill_up_to_limit_price(
order,
market,
limit_price_with_buffer,
Some(existing_base_asset_amount),
)?;
let max_base_asset_amount = calculate_amm_available_liquidity(&market.amm, &order.direction)?;

Ok((min(base_asset_amount, max_base_asset_amount), limit_price))
}

fn calculate_limit_price_with_buffer(
order: &Order,
limit_price: Option<u64>,
fee_tier: &FeeTier,
fee_adjustment: i16,
) -> DriftResult<Option<u64>> {
if !order.post_only {
Ok(limit_price)
} else if let Some(limit_price) = limit_price {
let mut buffer = limit_price
.safe_mul(fee_tier.maker_rebate_numerator.cast()?)?
.safe_div(fee_tier.maker_rebate_denominator.cast()?)?;

if market.fee_adjustment < 0 {
if fee_adjustment < 0 {
buffer = buffer.saturating_sub(
buffer
.safe_mul(market.fee_adjustment.abs().cast()?)?
.safe_mul(fee_adjustment.abs().cast()?)?
.safe_div(FEE_ADJUSTMENT_MAX)?,
);
} else if market.fee_adjustment > 0 {
} else if fee_adjustment > 0 {
buffer = buffer.saturating_add(
buffer
.safe_mul(market.fee_adjustment.cast()?)?
.safe_mul(fee_adjustment.cast()?)?
.safe_div(FEE_ADJUSTMENT_MAX)?,
);
}

match order.direction {
PositionDirection::Long => Some(limit_price.safe_sub(buffer)?),
PositionDirection::Short => Some(limit_price.safe_add(buffer)?),
PositionDirection::Long => limit_price.safe_sub(buffer).map(Some),
PositionDirection::Short => limit_price.safe_add(buffer).map(Some),
}
} else {
None
};

let base_asset_amount = calculate_base_asset_amount_to_fill_up_to_limit_price(
order,
market,
limit_price_with_buffer,
Some(existing_base_asset_amount),
)?;
let max_base_asset_amount = calculate_amm_available_liquidity(&market.amm, &order.direction)?;

Ok((min(base_asset_amount, max_base_asset_amount), limit_price))
Ok(None)
}
}

pub fn calculate_base_asset_amount_to_fill_up_to_limit_price(
Expand Down
129 changes: 129 additions & 0 deletions programs/drift/src/math/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2782,3 +2782,132 @@ pub mod find_bids_and_asks_from_users {
assert_eq!(asks, expected_asks);
}
}

pub mod calculate_limit_price_with_buffer {
use crate::math::orders::calculate_limit_price_with_buffer;
use crate::state::user::Order;
use crate::{FeeTier, PositionDirection, PRICE_PRECISION_U64};

#[test]
fn test() {
// No limit price
let order = Order::default();
let fee_tier = FeeTier::default();
let fee_adjustment = 0_i16;
let limit_price = None;

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(limit_price_with_buffer, None);

// No post only
let order = Order {
post_only: false,
..Order::default()
};
let limit_price = Some(100 * PRICE_PRECISION_U64);
let fee_tier = FeeTier {
maker_rebate_numerator: 2,
maker_rebate_denominator: 1000,
..FeeTier::default()
};

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(limit_price_with_buffer, limit_price);

// Post only bid
let order = Order {
post_only: true,
direction: PositionDirection::Long,
..Order::default()
};
let limit_price = Some(100 * PRICE_PRECISION_U64);
let fee_tier = FeeTier {
maker_rebate_numerator: 2,
maker_rebate_denominator: 10000, // 2bps
..FeeTier::default()
};

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(
limit_price_with_buffer,
Some(100 * PRICE_PRECISION_U64 - PRICE_PRECISION_U64 / 50) // 99.98
);

// Post only bid
let order = Order {
post_only: true,
direction: PositionDirection::Short,
..Order::default()
};
let limit_price = Some(100 * PRICE_PRECISION_U64);
let fee_tier = FeeTier {
maker_rebate_numerator: 2,
maker_rebate_denominator: 10000, // 2bps
..FeeTier::default()
};

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(
limit_price_with_buffer,
Some(100 * PRICE_PRECISION_U64 + PRICE_PRECISION_U64 / 50) // 99.98
);

// Post only bid w fee adjustment
let order = Order {
post_only: true,
direction: PositionDirection::Long,
..Order::default()
};
let limit_price = Some(100 * PRICE_PRECISION_U64);
let fee_tier = FeeTier {
maker_rebate_numerator: 2,
maker_rebate_denominator: 10000, // 2bps
..FeeTier::default()
};
let fee_adjustment = -75;

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(
limit_price_with_buffer,
Some(100 * PRICE_PRECISION_U64 - PRICE_PRECISION_U64 / 50 / 4) // 99.995
);

// Post only ask w fee adjustment
let order = Order {
post_only: true,
direction: PositionDirection::Short,
..Order::default()
};
let limit_price = Some(100 * PRICE_PRECISION_U64);
let fee_tier = FeeTier {
maker_rebate_numerator: 2,
maker_rebate_denominator: 10000, // 2bps
..FeeTier::default()
};
let fee_adjustment = -75;

let limit_price_with_buffer =
calculate_limit_price_with_buffer(&order, limit_price, &fee_tier, fee_adjustment)
.unwrap();

assert_eq!(
limit_price_with_buffer,
Some(100 * PRICE_PRECISION_U64 + PRICE_PRECISION_U64 / 50 / 4) // 100.005
);
}
}

0 comments on commit 4dd470a

Please sign in to comment.