Skip to content

Commit 3c53773

Browse files
authored
[Orderbook] Make the trigger condition more generic (#17197)
1 parent 4ab94f0 commit 3c53773

6 files changed

Lines changed: 49 additions & 126 deletions

File tree

aptos-move/framework/aptos-experimental/doc/order_book.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,12 +535,12 @@ If order doesn't exist, it aborts with EORDER_NOT_FOUND.
535535
_bid_price,
536536
_orig_size,
537537
_size,
538-
is_bid,
538+
_is_bid,
539539
trigger_condition,
540540
_
541541
) = order.destroy_order();
542542
self.pending_orders.cancel_pending_order(
543-
trigger_condition.destroy_some(), unique_priority_idx, is_bid
543+
trigger_condition.destroy_some(), unique_priority_idx
544544
);
545545
<b>if</b> (client_order_id.is_some()) {
546546
self.client_order_ids.remove(
@@ -912,7 +912,6 @@ it is added to the order book, if it exists, it's size is updated.
912912
order_id,
913913
order_req.trigger_condition.destroy_some(),
914914
ascending_idx,
915-
order_req.is_bid
916915
);
917916
}
918917
</code></pre>

aptos-move/framework/aptos-experimental/doc/order_book_types.md

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
- [Function `get_active_matched_size`](#0x7_order_book_types_get_active_matched_size)
3333
- [Function `get_matched_size`](#0x7_order_book_types_get_matched_size)
3434
- [Function `new_order_with_state`](#0x7_order_book_types_new_order_with_state)
35-
- [Function `tp_trigger_condition`](#0x7_order_book_types_tp_trigger_condition)
36-
- [Function `sl_trigger_condition`](#0x7_order_book_types_sl_trigger_condition)
35+
- [Function `price_move_up_condition`](#0x7_order_book_types_price_move_up_condition)
36+
- [Function `price_move_down_condition`](#0x7_order_book_types_price_move_down_condition)
3737
- [Function `index`](#0x7_order_book_types_index)
3838
- [Function `get_order_from_state`](#0x7_order_book_types_get_order_from_state)
3939
- [Function `get_metadata_from_state`](#0x7_order_book_types_get_metadata_from_state)
@@ -386,7 +386,7 @@
386386

387387

388388
<details>
389-
<summary>TakeProfit</summary>
389+
<summary>PriceMoveAbove</summary>
390390

391391

392392
<details>
@@ -408,7 +408,7 @@
408408
</details>
409409

410410
<details>
411-
<summary>StopLoss</summary>
411+
<summary>PriceMoveBelow</summary>
412412

413413

414414
<details>
@@ -998,13 +998,13 @@
998998

999999
</details>
10001000

1001-
<a id="0x7_order_book_types_tp_trigger_condition"></a>
1001+
<a id="0x7_order_book_types_price_move_up_condition"></a>
10021002

1003-
## Function `tp_trigger_condition`
1003+
## Function `price_move_up_condition`
10041004

10051005

10061006

1007-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_tp_trigger_condition">tp_trigger_condition</a>(take_profit: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>
1007+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_price_move_up_condition">price_move_up_condition</a>(price: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>
10081008
</code></pre>
10091009

10101010

@@ -1013,22 +1013,22 @@
10131013
<summary>Implementation</summary>
10141014

10151015

1016-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_tp_trigger_condition">tp_trigger_condition</a>(take_profit: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a> {
1017-
TriggerCondition::TakeProfit(take_profit)
1016+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_price_move_up_condition">price_move_up_condition</a>(price: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a> {
1017+
TriggerCondition::PriceMoveAbove(price)
10181018
}
10191019
</code></pre>
10201020

10211021

10221022

10231023
</details>
10241024

1025-
<a id="0x7_order_book_types_sl_trigger_condition"></a>
1025+
<a id="0x7_order_book_types_price_move_down_condition"></a>
10261026

1027-
## Function `sl_trigger_condition`
1027+
## Function `price_move_down_condition`
10281028

10291029

10301030

1031-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_sl_trigger_condition">sl_trigger_condition</a>(stop_loss: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>
1031+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_price_move_down_condition">price_move_down_condition</a>(price: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>
10321032
</code></pre>
10331033

10341034

@@ -1037,8 +1037,8 @@
10371037
<summary>Implementation</summary>
10381038

10391039

1040-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_sl_trigger_condition">sl_trigger_condition</a>(stop_loss: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a> {
1041-
TriggerCondition::StopLoss(stop_loss)
1040+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_price_move_down_condition">price_move_down_condition</a>(price: u64): <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a> {
1041+
TriggerCondition::PriceMoveBelow(price)
10421042
}
10431043
</code></pre>
10441044

@@ -1052,7 +1052,7 @@
10521052

10531053

10541054

1055-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_index">index</a>(self: &<a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>, is_bid: bool): (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;)
1055+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_index">index</a>(self: &<a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>): (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;)
10561056
</code></pre>
10571057

10581058

@@ -1061,22 +1061,14 @@
10611061
<summary>Implementation</summary>
10621062

10631063

1064-
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_index">index</a>(self: &<a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a>, is_bid: bool):
1064+
<pre><code><b>public</b> <b>fun</b> <a href="order_book_types.md#0x7_order_book_types_index">index</a>(self: &<a href="order_book_types.md#0x7_order_book_types_TriggerCondition">TriggerCondition</a>):
10651065
(Option&lt;u64&gt;, Option&lt;u64&gt;, Option&lt;u64&gt;) {
10661066
match(self) {
1067-
TriggerCondition::TakeProfit(tp) =&gt; {
1068-
<b>if</b> (is_bid) {
1069-
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*tp), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
1070-
} <b>else</b> {
1071-
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*tp), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
1072-
}
1067+
TriggerCondition::PriceMoveAbove(price) =&gt; {
1068+
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*price), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
10731069
}
1074-
TriggerCondition::StopLoss(sl) =&gt; {
1075-
<b>if</b> (is_bid) {
1076-
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*sl), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
1077-
} <b>else</b> {
1078-
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*sl), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
1079-
}
1070+
TriggerCondition::PriceMoveBelow(price) =&gt; {
1071+
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*price), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
10801072
}
10811073
TriggerCondition::TimeBased(time) =&gt; {
10821074
(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*time))

aptos-move/framework/aptos-experimental/doc/pending_order_book_index.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141

142142

143143

144-
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_cancel_pending_order">cancel_pending_order</a>(self: &<b>mut</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderBookIndex">pending_order_book_index::PendingOrderBookIndex</a>, trigger_condition: <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>, unique_priority_idx: <a href="order_book_types.md#0x7_order_book_types_UniqueIdxType">order_book_types::UniqueIdxType</a>, is_bid: bool)
144+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_cancel_pending_order">cancel_pending_order</a>(self: &<b>mut</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderBookIndex">pending_order_book_index::PendingOrderBookIndex</a>, trigger_condition: <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>, unique_priority_idx: <a href="order_book_types.md#0x7_order_book_types_UniqueIdxType">order_book_types::UniqueIdxType</a>)
145145
</code></pre>
146146

147147

@@ -154,10 +154,9 @@
154154
self: &<b>mut</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderBookIndex">PendingOrderBookIndex</a>,
155155
trigger_condition: TriggerCondition,
156156
unique_priority_idx: UniqueIdxType,
157-
is_bid: bool
158157
) {
159158
<b>let</b> (price_move_up_index, price_move_down_index, time_based_index) =
160-
trigger_condition.index(is_bid);
159+
trigger_condition.index();
161160
<b>if</b> (price_move_up_index.is_some()) {
162161
self.price_move_up_index.remove(
163162
&<a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderKey">PendingOrderKey</a> {
@@ -190,7 +189,7 @@
190189

191190

192191

193-
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_place_pending_maker_order">place_pending_maker_order</a>(self: &<b>mut</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderBookIndex">pending_order_book_index::PendingOrderBookIndex</a>, order_id: <a href="order_book_types.md#0x7_order_book_types_OrderIdType">order_book_types::OrderIdType</a>, trigger_condition: <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>, unique_priority_idx: <a href="order_book_types.md#0x7_order_book_types_UniqueIdxType">order_book_types::UniqueIdxType</a>, is_bid: bool)
192+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_place_pending_maker_order">place_pending_maker_order</a>(self: &<b>mut</b> <a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderBookIndex">pending_order_book_index::PendingOrderBookIndex</a>, order_id: <a href="order_book_types.md#0x7_order_book_types_OrderIdType">order_book_types::OrderIdType</a>, trigger_condition: <a href="order_book_types.md#0x7_order_book_types_TriggerCondition">order_book_types::TriggerCondition</a>, unique_priority_idx: <a href="order_book_types.md#0x7_order_book_types_UniqueIdxType">order_book_types::UniqueIdxType</a>)
194193
</code></pre>
195194

196195

@@ -204,12 +203,10 @@
204203
order_id: OrderIdType,
205204
trigger_condition: TriggerCondition,
206205
unique_priority_idx: UniqueIdxType,
207-
is_bid: bool
208206
) {
209207
// Add this order <b>to</b> the pending order book index
210208
<b>let</b> (price_move_down_index, price_move_up_index, time_based_index) =
211-
trigger_condition.index(is_bid);
212-
209+
trigger_condition.index();
213210
<b>if</b> (price_move_up_index.is_some()) {
214211
self.price_move_up_index.add(
215212
<a href="pending_order_book_index.md#0x7_pending_order_book_index_PendingOrderKey">PendingOrderKey</a> {

aptos-move/framework/aptos-experimental/sources/trading/order_book/order_book.move

Lines changed: 10 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ module aptos_experimental::order_book {
4040
#[test_only]
4141
use aptos_experimental::order_book_types::{
4242
new_order_id_type,
43-
tp_trigger_condition,
44-
UniqueIdxType
43+
price_move_up_condition,
44+
UniqueIdxType, price_move_down_condition
4545
};
4646

4747
const EORDER_ALREADY_EXISTS: u64 = 1;
@@ -157,12 +157,12 @@ module aptos_experimental::order_book {
157157
_bid_price,
158158
_orig_size,
159159
_size,
160-
is_bid,
160+
_is_bid,
161161
trigger_condition,
162162
_
163163
) = order.destroy_order();
164164
self.pending_orders.cancel_pending_order(
165-
trigger_condition.destroy_some(), unique_priority_idx, is_bid
165+
trigger_condition.destroy_some(), unique_priority_idx
166166
);
167167
if (client_order_id.is_some()) {
168168
self.client_order_ids.remove(
@@ -356,7 +356,6 @@ module aptos_experimental::order_book {
356356
order_id,
357357
order_req.trigger_condition.destroy_some(),
358358
ascending_idx,
359-
order_req.is_bid
360359
);
361360
}
362361

@@ -1116,7 +1115,7 @@ module aptos_experimental::order_book {
11161115
}
11171116

11181117
#[test]
1119-
fun test_TP_order() {
1118+
fun test_price_move_down_condition() {
11201119
let order_book = new_order_book<TestMetadata>();
11211120

11221121
// Place a GTC sell order for 1000 units at price 100
@@ -1149,7 +1148,7 @@ module aptos_experimental::order_book {
11491148
orig_size: 400,
11501149
remaining_size: 400,
11511150
is_bid: true,
1152-
trigger_condition: option::some(tp_trigger_condition(90)),
1151+
trigger_condition: option::some(price_move_down_condition(90)),
11531152
metadata: TestMetadata {}
11541153
}
11551154
);
@@ -1175,64 +1174,11 @@ module aptos_experimental::order_book {
11751174
assert!(matched_size == 400);
11761175
assert!(order.get_orig_size() == 1000);
11771176
assert!(order.get_remaining_size() == 600); // Partial fill
1178-
1179-
// Place another buy order for 300 units
1180-
let match_result =
1181-
order_book.place_order_and_get_matches(
1182-
OrderRequest::V1 {
1183-
account: @0xBB,
1184-
order_id: new_order_id_type(3),
1185-
client_order_id: option::none(),
1186-
price: 100,
1187-
orig_size: 300,
1188-
remaining_size: 300,
1189-
is_bid: true,
1190-
trigger_condition: option::some(tp_trigger_condition(80)),
1191-
metadata: TestMetadata {}
1192-
}
1193-
);
1194-
1195-
assert!(match_result.is_empty());
1196-
assert!(
1197-
order_book.pending_orders.get_price_move_down_index().keys().length() == 1
1198-
);
1199-
1200-
// Oracle price moves up to 95, this should not trigger any order
1201-
let match_results = order_book.trigger_pending_orders(95);
1202-
assert!(match_results.length() == 0);
1203-
1204-
// Move the oracle price down to 80, this should trigger the order
1205-
let match_results = order_book.trigger_pending_orders(80);
1206-
// Verify second taker was fully filled
1207-
assert!(total_matched_size(&match_results) == 300);
1208-
1209-
// Verify original maker was partially filled again
1210-
assert!(match_results.length() == 1);
1211-
let maker_match = match_results[0];
1212-
let (order, matched_size) = maker_match.destroy_single_order_match();
1213-
assert!(order.get_account() == @0xAA);
1214-
assert!(order.get_order_id() == new_order_id_type(1));
1215-
assert!(matched_size == 300);
1216-
assert!(order.get_orig_size() == 1000);
1217-
assert!(order.get_remaining_size() == 300); // Still partial as 300 units remain
1218-
1219-
// Original sell order should still exist with 300 units remaining
1220-
let order_id = new_order_id_type(1);
1221-
let order_state = *order_book.orders.borrow(&order_id);
1222-
let (order, is_active) = order_state.destroy_order_from_state();
1223-
let (_account, _order_id, _, price, orig_size, size, is_bid, _, _) =
1224-
order.destroy_order();
1225-
assert!(is_active == true);
1226-
assert!(price == 100);
1227-
assert!(orig_size == 1000);
1228-
assert!(size == 300); // 1000 - 400 - 300 = 300 remaining
1229-
assert!(is_bid == false);
1230-
12311177
order_book.destroy_order_book();
12321178
}
12331179

12341180
#[test]
1235-
fun test_SL_order() {
1181+
fun test_price_move_up_condition() {
12361182
let order_book = new_order_book<TestMetadata>();
12371183

12381184
// Place a GTC sell order for 1000 units at price 100
@@ -1265,7 +1211,7 @@ module aptos_experimental::order_book {
12651211
orig_size: 400,
12661212
remaining_size: 400,
12671213
is_bid: false,
1268-
trigger_condition: option::some(tp_trigger_condition(110)),
1214+
trigger_condition: option::some(price_move_up_condition(110)),
12691215
metadata: TestMetadata {}
12701216
}
12711217
);
@@ -1304,7 +1250,7 @@ module aptos_experimental::order_book {
13041250
orig_size: 300,
13051251
remaining_size: 300,
13061252
is_bid: false,
1307-
trigger_condition: option::some(tp_trigger_condition(120)),
1253+
trigger_condition: option::some(price_move_up_condition(120)),
13081254
metadata: TestMetadata {}
13091255
}
13101256
);
@@ -1519,7 +1465,7 @@ module aptos_experimental::order_book {
15191465
orig_size: 1000,
15201466
remaining_size: 1000,
15211467
is_bid: false,
1522-
trigger_condition: option::some(tp_trigger_condition(90)),
1468+
trigger_condition: option::some(price_move_up_condition(90)),
15231469
metadata: TestMetadata {}
15241470
};
15251471
order_book.place_maker_order(order_req);

0 commit comments

Comments
 (0)