Skip to content

Commit

Permalink
Fix orders response camelCasing
Browse files Browse the repository at this point in the history
Add support for oracleOffsetPrice
  • Loading branch information
jordy25519 committed Dec 18, 2023
1 parent 995b0b9 commit 70eb766
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 27 deletions.
48 changes: 25 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,30 +139,31 @@ $ curl -X GET \
{
"orders": [
{
"order_type": "limit",
"market_id": 1,
"market_type": "spot",
"orderType": "limit",
"marketIndex": 1,
"marketType": "spot",
"amount": "-1.100000000",
"filled": "0.000000000",
"price": "80.500000",
"post_only": true,
"reduce_only": false,
"user_order_id": 101,
"order_id": 35,
"immediate_or_cancel": false
"postOnly": true,
"reduceOnly": false,
"userOrderId": 101,
"orderId": 35,
"immediateOrCancel": false
},
{
"order_type": "limit",
"market_id": 0,
"market_type": "perp",
"amount": "-1.230000000",
"orderType": "limit",
"marketIndex": 1,
"marketType": "perp",
"amount": "0.005000000",
"filled": "0.000000000",
"price": "80.000000",
"post_only": true,
"reduce_only": false,
"user_order_id": 0,
"order_id": 37,
"immediate_or_cancel": false
"price": "0.000000",
"postOnly": true,
"reduceOnly": false,
"userOrderId": 103,
"orderId": 50,
"immediateOrCancel": false,
"oraclePriceOffset": "20.000000"
}
]
}
Expand Down Expand Up @@ -205,7 +206,8 @@ localhost:8080/v2/positions
- use sub-zero `amount` to indicate sell/offer order
- `userOrderId` is a uint in the range 1 <= x <= 255 which can be assigned by the client to help distinguish orders
- `orderType` only "limit" and "market" options are fully supported by the gateway
- `oraclePriceOffset` supported on `"limit"` order types.
It creates a limit order with a floating price relative to the market oracle price. when supplied the `price` field is ignored.
```bash
$ curl localhost:8080/v2/orders -X POST \
-H 'content-type: application/json' \
Expand All @@ -218,17 +220,17 @@ $ curl localhost:8080/v2/orders -X POST \
"price": 80.0,
"postOnly": true,
"orderType": "limit",
"userOrderId": 101
"userOrderId": 101,
"immediateOrCancel": false,
"reduce_only": false,
"reduceOnly": false
},
{
"marketIndex": 0,
"marketType": "perp",
"amount": 1.23,
"price": 60.0,
"postOnly": true,
"orderType": "limit",
"oraclePriceOffset": 2,
"userOrderId": 102
}]
}'
Expand Down Expand Up @@ -293,7 +295,7 @@ $ curl localhost:8080/v2/orders/cancelAndPlace -X POST -H 'content-type: applica
"postOnly": true,
"orderType": "limit",
"immediateOrCancel": false,
"reduce_only": false
"reduceOnly": false
}]
}
}'
Expand Down
35 changes: 31 additions & 4 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ use rust_decimal::Decimal;
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Order {
#[serde(serialize_with = "order_type_ser", deserialize_with = "order_type_de")]
order_type: sdk_types::OrderType,
market_id: u16,
market_index: u16,
#[serde(
serialize_with = "market_type_ser",
deserialize_with = "market_type_de"
Expand All @@ -34,6 +35,8 @@ pub struct Order {
user_order_id: u8,
order_id: u32,
immediate_or_cancel: bool,
#[serde(skip_serializing_if = "Option::is_none")]
oracle_price_offset: Option<Decimal>,
}

impl Order {
Expand All @@ -45,7 +48,7 @@ impl Order {
let to_sign = 1_i64 - 2 * (value.direction as i64);

Order {
market_id: value.market_index,
market_index: value.market_index,
market_type: value.market_type,
price: Decimal::new(value.price as i64, PRICE_PRECISION.ilog10()),
amount: Decimal::new(value.base_asset_amount as i64 * to_sign, decimals),
Expand All @@ -56,6 +59,14 @@ impl Order {
order_id: value.order_id,
post_only: value.post_only,
user_order_id: value.user_order_id,
oracle_price_offset: if value.oracle_price_offset == 0 {
None
} else {
Some(Decimal::new(
value.oracle_price_offset as i64,
PRICE_PRECISION.ilog10(),
))
},
}
}
}
Expand Down Expand Up @@ -202,6 +213,7 @@ pub struct PlaceOrder {
#[serde(flatten)]
market: Market,
amount: Decimal,
#[serde(default)]
price: Decimal,
/// 0 indicates it is not set (according to program)
#[serde(default)]
Expand All @@ -218,6 +230,8 @@ pub struct PlaceOrder {
reduce_only: bool,
#[serde(default)]
immediate_or_cancel: bool,
#[serde(default)]
oracle_price_offset: Option<Decimal>,
}

fn market_type_ser<S>(market_type: &sdk_types::MarketType, serializer: S) -> Result<S::Ok, S::Error>
Expand Down Expand Up @@ -249,6 +263,12 @@ fn scale_decimal_to_u64(x: Decimal, target: u32) -> u64 {
((x.mantissa().unsigned_abs() * target as u128) / 10_u128.pow(x.scale())) as u64
}

#[inline]
/// Convert decimal to unsigned fixed-point representation with `target` precision
fn scale_decimal_to_i64(x: Decimal, target: u32) -> i64 {
((x.mantissa().abs() * target as i128) / 10_i128.pow(x.scale())) as i64
}

impl PlaceOrder {
pub fn to_order_params(self, context: Context) -> OrderParams {
let target_scale = if let MarketType::Perp = self.market.market_type {
Expand All @@ -259,7 +279,11 @@ impl PlaceOrder {
config.precision as u32
};
let base_amount = scale_decimal_to_u64(self.amount.abs(), target_scale);
let price = scale_decimal_to_u64(self.price, PRICE_PRECISION as u32);
let price = if self.oracle_price_offset.is_none() {
scale_decimal_to_u64(self.price, PRICE_PRECISION as u32)
} else {
0
};

OrderParams {
market_index: self.market.market_index,
Expand All @@ -275,11 +299,14 @@ impl PlaceOrder {
immediate_or_cancel: self.immediate_or_cancel,
reduce_only: self.reduce_only,
post_only: if self.post_only {
PostOnlyParam::TryPostOnly
PostOnlyParam::MustPostOnly // this will report the failure to the gateway caller
} else {
PostOnlyParam::None
},
user_order_id: self.user_order_id,
oracle_price_offset: self
.oracle_price_offset
.map(|x| scale_decimal_to_i64(x, PRICE_PRECISION as u32) as i32),
..Default::default()
}
}
Expand Down

0 comments on commit 70eb766

Please sign in to comment.