Module 0x7::pending_order_book_index
(work in progress)
- Struct
PendingUpOrderKey - Struct
PendingDownOrderKey - Struct
PendingTimeKey - Enum
PendingOrderBookIndex - Function
new_pending_order_book_index - Function
cancel_pending_order - Function
place_pending_order - Function
take_ready_price_move_up_orders - Function
take_ready_price_move_down_orders - Function
take_ready_price_based_orders - Function
take_ready_time_based_orders
use 0x1::big_ordered_map;
use 0x1::error;
use 0x1::option;
use 0x1::timestamp;
use 0x5::order_book_types;
use 0x7::order_book_utils;
Struct PendingUpOrderKey
struct PendingUpOrderKey has copy, drop, store
Fields
-
price: u64 -
tie_breaker: order_book_types::IncreasingIdx
Struct PendingDownOrderKey
struct PendingDownOrderKey has copy, drop, store
Fields
-
price: u64 -
tie_breaker: order_book_types::DecreasingIdx
Struct PendingTimeKey
struct PendingTimeKey has copy, drop, store
Fields
-
time: u64 -
tie_breaker: order_book_types::IncreasingIdx
Enum PendingOrderBookIndex
enum PendingOrderBookIndex has store
Variants
V1
Fields
-
price_move_down_index: big_ordered_map::BigOrderedMap<pending_order_book_index::PendingDownOrderKey, order_book_types::OrderId> -
price_move_up_index: big_ordered_map::BigOrderedMap<pending_order_book_index::PendingUpOrderKey, order_book_types::OrderId> -
time_based_index: big_ordered_map::BigOrderedMap<pending_order_book_index::PendingTimeKey, order_book_types::OrderId>
Function new_pending_order_book_index
public(friend) fun new_pending_order_book_index(): pending_order_book_index::PendingOrderBookIndex
Implementation
public(friend) fun new_pending_order_book_index(): PendingOrderBookIndex {
PendingOrderBookIndex::V1 {
price_move_up_index: order_book_utils::new_default_big_ordered_map(),
price_move_down_index: order_book_utils::new_default_big_ordered_map(),
time_based_index: order_book_utils::new_default_big_ordered_map()
}
}
Function cancel_pending_order
public(friend) fun cancel_pending_order(self: &mut pending_order_book_index::PendingOrderBookIndex, trigger_condition: order_book_types::TriggerCondition, unique_priority_idx: order_book_types::IncreasingIdx)
Implementation
public(friend) fun cancel_pending_order(
self: &mut PendingOrderBookIndex,
trigger_condition: TriggerCondition,
unique_priority_idx: IncreasingIdx
) {
let (price_move_down_index, price_move_up_index, time_based_index) =
trigger_condition.get_trigger_condition_indices();
if (price_move_up_index.is_some()) {
self.price_move_up_index.remove(
&PendingUpOrderKey {
price: price_move_up_index.destroy_some(),
tie_breaker: unique_priority_idx
}
);
};
if (price_move_down_index.is_some()) {
self.price_move_down_index.remove(
&PendingDownOrderKey {
price: price_move_down_index.destroy_some(),
tie_breaker: unique_priority_idx.into_decreasing_idx_type()
}
);
};
if (time_based_index.is_some()) {
self.time_based_index.remove(
&PendingTimeKey {
time: time_based_index.destroy_some(),
tie_breaker: unique_priority_idx
}
);
};
}
Function place_pending_order
public(friend) fun place_pending_order(self: &mut pending_order_book_index::PendingOrderBookIndex, order_id: order_book_types::OrderId, trigger_condition: order_book_types::TriggerCondition, unique_priority_idx: order_book_types::IncreasingIdx)
Implementation
public(friend) fun place_pending_order(
self: &mut PendingOrderBookIndex,
order_id: OrderId,
trigger_condition: TriggerCondition,
unique_priority_idx: IncreasingIdx
) {
// Add this order to the pending order book index
let (price_move_down_index, price_move_up_index, time_based_index) =
trigger_condition.get_trigger_condition_indices();
if (price_move_up_index.is_some()) {
self.price_move_up_index.add(
PendingUpOrderKey {
price: price_move_up_index.destroy_some(),
tie_breaker: unique_priority_idx
},
order_id
);
} else if (price_move_down_index.is_some()) {
self.price_move_down_index.add(
PendingDownOrderKey {
price: price_move_down_index.destroy_some(),
// Use a descending tie breaker to ensure that for price move down orders,
// orders with the same price are processed in FIFO order
tie_breaker: unique_priority_idx.into_decreasing_idx_type()
},
order_id
);
} else if (time_based_index.is_some()) {
self.time_based_index.add(
PendingTimeKey {
time: time_based_index.destroy_some(),
tie_breaker: unique_priority_idx
},
order_id
);
};
}
Function take_ready_price_move_up_orders
fun take_ready_price_move_up_orders(self: &mut pending_order_book_index::PendingOrderBookIndex, current_price: u64, orders: &mut vector<order_book_types::OrderId>, limit: u64)
Implementation
inline fun take_ready_price_move_up_orders(
self: &mut PendingOrderBookIndex,
current_price: u64,
orders: &mut vector<OrderId>,
limit: u64
) {
while (!self.price_move_up_index.is_empty() && orders.length() < limit) {
let (key, order_id) = self.price_move_up_index.borrow_front();
if (current_price >= key.price) {
orders.push_back(*order_id);
self.price_move_up_index.remove(&key);
} else {
break;
}
};
}
Function take_ready_price_move_down_orders
fun take_ready_price_move_down_orders(self: &mut pending_order_book_index::PendingOrderBookIndex, current_price: u64, orders: &mut vector<order_book_types::OrderId>, limit: u64)
Implementation
inline fun take_ready_price_move_down_orders(
self: &mut PendingOrderBookIndex,
current_price: u64,
orders: &mut vector<OrderId>,
limit: u64
) {
while (!self.price_move_down_index.is_empty() && orders.length() < limit) {
let (key, order_id) = self.price_move_down_index.borrow_back();
if (current_price <= key.price) {
orders.push_back(*order_id);
self.price_move_down_index.remove(&key);
} else {
break;
}
};
}
Function take_ready_price_based_orders
public(friend) fun take_ready_price_based_orders(self: &mut pending_order_book_index::PendingOrderBookIndex, current_price: u64, order_limit: u64): vector<order_book_types::OrderId>
Implementation
public(friend) fun take_ready_price_based_orders(
self: &mut PendingOrderBookIndex, current_price: u64, order_limit: u64
): vector<OrderId> {
let orders = vector::empty();
self.take_ready_price_move_up_orders(
current_price,
&mut orders,
math64::ceil_div(order_limit, 2)
);
self.take_ready_price_move_down_orders(current_price, &mut orders, order_limit);
// Try to fill the rest of the space if available.
self.take_ready_price_move_up_orders(current_price, &mut orders, order_limit);
orders
}
Function take_ready_time_based_orders
public(friend) fun take_ready_time_based_orders(self: &mut pending_order_book_index::PendingOrderBookIndex, order_limit: u64): vector<order_book_types::OrderId>
Implementation
public(friend) fun take_ready_time_based_orders(
self: &mut PendingOrderBookIndex, order_limit: u64
): vector<OrderId> {
let orders = vector::empty();
while (!self.time_based_index.is_empty() && orders.length() < order_limit) {
let current_time = timestamp::now_seconds();
let (time, order_id) = self.time_based_index.borrow_front();
if (current_time >= time.time) {
orders.push_back(*order_id);
self.time_based_index.remove(&time);
} else {
break;
}
};
orders
}