Working order
This commit is contained in:
@@ -51,7 +51,7 @@ pub struct Signal {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct EngineOrder {
|
pub struct EngineOrder {
|
||||||
pub risk_equity: Decimal,
|
pub risk: Decimal,
|
||||||
pub size: Decimal,
|
pub size: Decimal,
|
||||||
pub stop_loss: Decimal,
|
pub stop_loss: Decimal,
|
||||||
|
|
||||||
|
|||||||
+18
-1
@@ -3,6 +3,8 @@ pub mod strategy;
|
|||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
pub use hypersdk;
|
pub use hypersdk;
|
||||||
|
|
||||||
|
use hypersdk::Decimal;
|
||||||
|
use rust_decimal::RoundingStrategy;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
use crate::{general::LogKind, strategy::StrategyEngineMessage};
|
use crate::{general::LogKind, strategy::StrategyEngineMessage};
|
||||||
@@ -10,9 +12,9 @@ use crate::{general::LogKind, strategy::StrategyEngineMessage};
|
|||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::Strategy;
|
pub use crate::Strategy;
|
||||||
pub use crate::general::*;
|
pub use crate::general::*;
|
||||||
pub use crate::server_path;
|
|
||||||
pub use crate::strategy::*;
|
pub use crate::strategy::*;
|
||||||
pub use crate::terminal::*;
|
pub use crate::terminal::*;
|
||||||
|
pub use crate::{round_price, server_path};
|
||||||
|
|
||||||
pub use hypersdk;
|
pub use hypersdk;
|
||||||
pub use postcard;
|
pub use postcard;
|
||||||
@@ -26,6 +28,21 @@ pub fn map_postcard_err<T>(res: postcard::Result<T>) -> tokio::io::Result<T> {
|
|||||||
res.map_err(|e| tokio::io::Error::new(std::io::ErrorKind::Other, e))
|
res.map_err(|e| tokio::io::Error::new(std::io::ErrorKind::Other, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn round_price(price: Decimal) -> Decimal {
|
||||||
|
let digits = price.trunc().to_string().len() as u32;
|
||||||
|
let decimal_places = 5_i32 - digits as i32;
|
||||||
|
|
||||||
|
if decimal_places < 0 {
|
||||||
|
let factor = Decimal::from(10_u64.pow((-decimal_places) as u32));
|
||||||
|
(price / factor).round() * factor
|
||||||
|
} else {
|
||||||
|
price.round_dp_with_strategy(
|
||||||
|
decimal_places as u32,
|
||||||
|
RoundingStrategy::MidpointAwayFromZero,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn send_raw(data: &[u8]) -> tokio::io::Result<()> {
|
pub async fn send_raw(data: &[u8]) -> tokio::io::Result<()> {
|
||||||
let mut stdout = tokio::io::stdout();
|
let mut stdout = tokio::io::stdout();
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,16 @@ impl Engine {
|
|||||||
|
|
||||||
*size = Some(engine_order);
|
*size = Some(engine_order);
|
||||||
|
|
||||||
|
let limit_px = round_price(signal.entry_price);
|
||||||
|
let sz = round_price(engine_order.size / signal.entry_price);
|
||||||
|
|
||||||
let order = BatchOrder {
|
let order = BatchOrder {
|
||||||
orders: vec![
|
orders: vec![
|
||||||
OrderRequest {
|
OrderRequest {
|
||||||
asset: asset_id,
|
asset: asset_id,
|
||||||
is_buy: matches!(signal.side, Side::Bid),
|
is_buy: matches!(signal.side, Side::Bid),
|
||||||
limit_px: signal.entry_price,
|
limit_px,
|
||||||
sz: engine_order.size,
|
sz,
|
||||||
reduce_only: false,
|
reduce_only: false,
|
||||||
order_type: OrderTypePlacement::Limit {
|
order_type: OrderTypePlacement::Limit {
|
||||||
tif: TimeInForce::Gtc,
|
tif: TimeInForce::Gtc,
|
||||||
@@ -53,12 +56,12 @@ impl Engine {
|
|||||||
OrderRequest {
|
OrderRequest {
|
||||||
asset: asset_id,
|
asset: asset_id,
|
||||||
is_buy: !matches!(signal.side, Side::Bid),
|
is_buy: !matches!(signal.side, Side::Bid),
|
||||||
limit_px: signal.entry_price,
|
limit_px,
|
||||||
sz: engine_order.size,
|
sz,
|
||||||
reduce_only: true,
|
reduce_only: true,
|
||||||
order_type: OrderTypePlacement::Trigger {
|
order_type: OrderTypePlacement::Trigger {
|
||||||
is_market: true,
|
is_market: true,
|
||||||
trigger_px: signal.take_profit,
|
trigger_px: round_price(signal.take_profit),
|
||||||
tpsl: hypercore::TpSl::Tp,
|
tpsl: hypercore::TpSl::Tp,
|
||||||
},
|
},
|
||||||
cloid: engine_order.take_profit,
|
cloid: engine_order.take_profit,
|
||||||
@@ -66,12 +69,12 @@ impl Engine {
|
|||||||
OrderRequest {
|
OrderRequest {
|
||||||
asset: asset_id,
|
asset: asset_id,
|
||||||
is_buy: !matches!(signal.side, Side::Bid),
|
is_buy: !matches!(signal.side, Side::Bid),
|
||||||
limit_px: signal.entry_price,
|
limit_px,
|
||||||
sz: engine_order.size,
|
sz,
|
||||||
reduce_only: true,
|
reduce_only: true,
|
||||||
order_type: OrderTypePlacement::Trigger {
|
order_type: OrderTypePlacement::Trigger {
|
||||||
is_market: true,
|
is_market: true,
|
||||||
trigger_px: engine_order.stop_loss,
|
trigger_px: round_price(engine_order.stop_loss),
|
||||||
tpsl: hypercore::TpSl::Sl,
|
tpsl: hypercore::TpSl::Sl,
|
||||||
},
|
},
|
||||||
cloid: engine_order.stop_loss_id,
|
cloid: engine_order.stop_loss_id,
|
||||||
@@ -81,6 +84,8 @@ impl Engine {
|
|||||||
builder: None,
|
builder: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("{order:?}");
|
||||||
|
|
||||||
let nonce = NonceHandler::default();
|
let nonce = NonceHandler::default();
|
||||||
|
|
||||||
match client
|
match client
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl RiskEngine {
|
|||||||
for r in rm {
|
for r in rm {
|
||||||
let order = self.orders.lock().await.remove(r);
|
let order = self.orders.lock().await.remove(r);
|
||||||
|
|
||||||
self.state.lock().await.pnl -= order.risk_equity;
|
self.state.lock().await.pnl -= order.risk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,15 +157,14 @@ impl RiskEngine {
|
|||||||
take_profit: Cloid::random(),
|
take_profit: Cloid::random(),
|
||||||
stop_loss_id: Cloid::random(),
|
stop_loss_id: Cloid::random(),
|
||||||
|
|
||||||
size: size.round_dp(3),
|
size,
|
||||||
risk_equity: risk,
|
risk,
|
||||||
|
|
||||||
stop_loss: if matches!(signal.side, Side::Ask) {
|
stop_loss: if matches!(signal.side, Side::Ask) {
|
||||||
signal.entry_price + sl_distance
|
signal.entry_price + sl_distance
|
||||||
} else {
|
} else {
|
||||||
signal.entry_price - sl_distance
|
signal.entry_price - sl_distance
|
||||||
}
|
},
|
||||||
.round_dp(3),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user