0x0::order
Order module defines the order struct and its methods. All order matching happens in this module.
Order
OrderCanceled
OrderModified
balance_manager_id
order_id
client_order_id
quantity
filled_quantity
fee_is_deep
order_deep_price
epoch
status
expire_timestamp
price
new
generate_fill
modify
calculate_cancel_refund
locked_balance
emit_order_canceled
emit_order_modified
emit_cancel_maker
copy_order
set_canceled
is_bid
use 0x0::balances;
use 0x0::constants;
use 0x0::deep_price;
use 0x0::fill;
use 0x0::math;
use 0x0::utils;
use 0x1::option;
use 0x1::u64;
use 0x2::event;
use 0x2::object;
Order
Order struct represents the order in the order book. It is optimized for space.
struct Order has drop, store
balance_manager_id: object::ID
order_id: u128
client_order_id: u64
quantity: u64
filled_quantity: u64
fee_is_deep: bool
order_deep_price: deep_price::OrderDeepPrice
epoch: u64
status: u8
expire_timestamp: u64
OrderCanceled
Emitted when a maker order is canceled.
struct OrderCanceled has copy, drop, store
balance_manager_id: object::ID
pool_id: object::ID
order_id: u128
client_order_id: u64
trader: address
price: u64
is_bid: bool
original_quantity: u64
base_asset_quantity_canceled: u64
timestamp: u64
OrderModified
Emitted when a maker order is modified.
struct OrderModified has copy, drop, store
balance_manager_id: object::ID
pool_id: object::ID
order_id: u128
client_order_id: u64
trader: address
price: u64
is_bid: bool
previous_quantity: u64
filled_quantity: u64
new_quantity: u64
timestamp: u64
const EInvalidNewQuantity: u64 = 0;
const EOrderExpired: u64 = 1;
balance_manager_id
public fun balance_manager_id(self: &order::Order): object::ID
public fun balance_manager_id(self: &Order): ID {
self.balance_manager_id
}
order_id
public fun order_id(self: &order::Order): u128
client_order_id
public fun client_order_id(self: &order::Order): u64
public fun client_order_id(self: &Order): u64 {
self.client_order_id
}
quantity
public fun quantity(self: &order::Order): u64
filled_quantity
public fun filled_quantity(self: &order::Order): u64
public fun filled_quantity(self: &Order): u64 {
self.filled_quantity
}
fee_is_deep
public fun fee_is_deep(self: &order::Order): bool
public fun fee_is_deep(self: &Order): bool {
self.fee_is_deep
}
order_deep_price
public fun order_deep_price(self: &order::Order): &deep_price::OrderDeepPrice
public fun order_deep_price(self: &Order): &OrderDeepPrice {
&self.order_deep_price
}
epoch
public fun epoch(self: &order::Order): u64
status
public fun status(self: &order::Order): u8
expire_timestamp
public fun expire_timestamp(self: &order::Order): u64
public fun expire_timestamp(self: &Order): u64 {
self.expire_timestamp
}
price
public fun price(self: &order::Order): u64
public fun price(self: &Order): u64 {
let (_, price, _) = utils::decode_order_id(self.order_id);
price
}
new
initialize the order struct.
public(friend) fun new(order_id: u128, balance_manager_id: object::ID, client_order_id: u64, quantity: u64, filled_quantity: u64, fee_is_deep: bool, order_deep_price: deep_price::OrderDeepPrice, epoch: u64, status: u8, expire_timestamp: u64): order::Order
public(package) fun new(
order_id: u128,
balance_manager_id: ID,
client_order_id: u64,
quantity: u64,
filled_quantity: u64,
fee_is_deep: bool,
order_deep_price: OrderDeepPrice,
epoch: u64,
status: u8,
expire_timestamp: u64,
): Order {
Order {
order_id,
balance_manager_id,
client_order_id,
quantity,
filled_quantity,
fee_is_deep,
order_deep_price,
epoch,
status,
expire_timestamp,
}
}
generate_fill
Generate a fill for the resting order given the timestamp, quantity and whether the order is a bid.
public(friend) fun generate_fill(self: &mut order::Order, timestamp: u64, quantity: u64, is_bid: bool, expire_maker: bool, taker_fee_is_deep: bool): fill::Fill
public(package) fun generate_fill(
self: &mut Order,
timestamp: u64,
quantity: u64,
is_bid: bool,
expire_maker: bool,
taker_fee_is_deep: bool,
): Fill {
let remaining_quantity = self.quantity - self.filled_quantity;
let mut base_quantity = remaining_quantity.min(quantity);
let mut quote_quantity = math::mul(base_quantity, self.price());
let order_id = self.order_id;
let balance_manager_id = self.balance_manager_id;
let expired = timestamp > self.expire_timestamp || expire_maker;
if (expired) {
self.status = constants::expired();
base_quantity = remaining_quantity;
quote_quantity = math::mul(base_quantity, self.price());
} else {
self.filled_quantity = self.filled_quantity + base_quantity;
self.status =
if (self.quantity == self.filled_quantity) constants::filled()
else constants::partially_filled();
};
fill::new(
order_id,
self.client_order_id,
self.price(),
balance_manager_id,
expired,
self.quantity == self.filled_quantity,
self.quantity,
base_quantity,
quote_quantity,
is_bid,
self.epoch,
self.order_deep_price,
taker_fee_is_deep,
self.fee_is_deep,
)
}
modify
Modify the order with a new quantity. The new quantity must be greater than the filled quantity and less than the original quantity. The timestamp must be less than the expire timestamp.
public(friend) fun modify(self: &mut order::Order, new_quantity: u64, timestamp: u64)
public(package) fun modify(
self: &mut Order,
new_quantity: u64,
timestamp: u64,
) {
assert!(
new_quantity > self.filled_quantity &&
new_quantity < self.quantity,
EInvalidNewQuantity,
);
assert!(timestamp <= self.expire_timestamp, EOrderExpired);
self.quantity = new_quantity;
}
calculate_cancel_refund
Calculate the refund for a canceled order. The refund is any unfilled quantity and the maker fee. If the cancel quantity is not provided, the remaining quantity is used. Cancel quantity is provided when modifying an order, so that the refund can be calculated based on the quantity that’s reduced.
public(friend) fun calculate_cancel_refund(self: &order::Order, maker_fee: u64, cancel_quantity: option::Option<u64>): balances::Balances
public(package) fun calculate_cancel_refund(
self: &Order,
maker_fee: u64,
cancel_quantity: Option<u64>,
): Balances {
let cancel_quantity = cancel_quantity.get_with_default(
self.quantity - self.filled_quantity,
);
let deep_out = math::mul(
maker_fee,
self
.order_deep_price()
.deep_quantity(
cancel_quantity,
math::mul(cancel_quantity, self.price()),
),
);
let mut base_out = 0;
let mut quote_out = 0;
if (self.is_bid()) {
quote_out = math::mul(cancel_quantity, self.price());
} else {
base_out = cancel_quantity;
};
balances::new(base_out, quote_out, deep_out)
}
locked_balance
public(friend) fun locked_balance(self: &order::Order, maker_fee: u64): (u64, u64, u64)
public(package) fun locked_balance(
self: &Order,
maker_fee: u64,
): (u64, u64, u64) {
let (is_bid, order_price, _) = utils::decode_order_id(self.order_id());
let mut base_quantity = 0;
let mut quote_quantity = 0;
let remaining_base_quantity = self.quantity() - self.filled_quantity();
let remaining_quote_quantity = math::mul(remaining_base_quantity, order_price);
if (is_bid) {
quote_quantity = quote_quantity + remaining_quote_quantity;
} else {
base_quantity = base_quantity + remaining_base_quantity;
};
let deep_quantity = math::mul(
maker_fee,
self
.order_deep_price()
.deep_quantity(
remaining_base_quantity,
remaining_quote_quantity,
),
);
(base_quantity, quote_quantity, deep_quantity)
}
emit_order_canceled
public(friend) fun emit_order_canceled(self: &order::Order, pool_id: object::ID, trader: address, timestamp: u64)
public(package) fun emit_order_canceled(
self: &Order,
pool_id: ID,
trader: address,
timestamp: u64,
) {
let is_bid = self.is_bid();
let price = self.price();
let remaining_quantity = self.quantity - self.filled_quantity;
event::emit(OrderCanceled {
pool_id,
order_id: self.order_id,
balance_manager_id: self.balance_manager_id,
client_order_id: self.client_order_id,
is_bid,
trader,
original_quantity: self.quantity,
base_asset_quantity_canceled: remaining_quantity,
timestamp,
price,
});
}
emit_order_modified
public(friend) fun emit_order_modified(self: &order::Order, pool_id: object::ID, previous_quantity: u64, trader: address, timestamp: u64)
public(package) fun emit_order_modified(
self: &Order,
pool_id: ID,
previous_quantity: u64,
trader: address,
timestamp: u64,
) {
let is_bid = self.is_bid();
let price = self.price();
event::emit(OrderModified {
order_id: self.order_id,
pool_id,
client_order_id: self.client_order_id,
balance_manager_id: self.balance_manager_id,
trader,
price,
is_bid,
previous_quantity,
filled_quantity: self.filled_quantity,
new_quantity: self.quantity,
timestamp,
});
}
emit_cancel_maker
public(friend) fun emit_cancel_maker(balance_manager_id: object::ID, pool_id: object::ID, order_id: u128, client_order_id: u64, trader: address, price: u64, is_bid: bool, original_quantity: u64, base_asset_quantity_canceled: u64, timestamp: u64)
public(package) fun emit_cancel_maker(
balance_manager_id: ID,
pool_id: ID,
order_id: u128,
client_order_id: u64,
trader: address,
price: u64,
is_bid: bool,
original_quantity: u64,
base_asset_quantity_canceled: u64,
timestamp: u64,
) {
event::emit(OrderCanceled {
balance_manager_id,
pool_id,
order_id,
client_order_id,
trader,
price,
is_bid,
original_quantity,
base_asset_quantity_canceled,
timestamp,
});
}
copy_order
Copy the order struct.
public(friend) fun copy_order(order: &order::Order): order::Order
public(package) fun copy_order(order: &Order): Order {
Order {
order_id: order.order_id,
balance_manager_id: order.balance_manager_id,
client_order_id: order.client_order_id,
quantity: order.quantity,
filled_quantity: order.filled_quantity,
fee_is_deep: order.fee_is_deep,
order_deep_price: order.order_deep_price,
epoch: order.epoch,
status: order.status,
expire_timestamp: order.expire_timestamp,
}
}
set_canceled
Update the order status to canceled.
public(friend) fun set_canceled(self: &mut order::Order)
public(package) fun set_canceled(self: &mut Order) {
self.status = constants::canceled();
}
is_bid
public(friend) fun is_bid(self: &order::Order): bool
public(package) fun is_bid(self: &Order): bool {
let (is_bid, _, _) = utils::decode_order_id(self.order_id);
is_bid
}