-
Notifications
You must be signed in to change notification settings - Fork 17
Feature: market close order #3244
Changes from 2 commits
cd16fe3
12043b9
3da5159
f82e1df
425d5cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,15 +7,13 @@ use anyhow::Context; | |
use anyhow::Result; | ||
use async_trait::async_trait; | ||
use model::libp2p::PeerId; | ||
use model::market_closing_price; | ||
use model::Cfd; | ||
use model::Contracts; | ||
use model::Identity; | ||
use model::Leverage; | ||
use model::OfferId; | ||
use model::OrderId; | ||
use model::Price; | ||
use model::Role; | ||
use model::{ContractSymbol, Position}; | ||
use sqlite_db; | ||
use std::collections::HashMap; | ||
use time::OffsetDateTime; | ||
|
@@ -29,12 +27,9 @@ pub struct PlaceOrder { | |
pub leverage: Leverage, | ||
} | ||
|
||
#[derive(Clone)] | ||
#[derive(Clone, Copy)] | ||
pub struct ProposeSettlement { | ||
pub order_id: OrderId, | ||
pub bid: Price, | ||
pub ask: Price, | ||
pub quote_timestamp: String, | ||
} | ||
|
||
pub struct Actor { | ||
|
@@ -43,6 +38,7 @@ pub struct Actor { | |
collab_settlement_actor: xtra::Address<collab_settlement::taker::Actor>, | ||
order_actor: xtra::Address<order::taker::Actor>, | ||
offers: Offers, | ||
latest_offers: HashMap<(ContractSymbol, Position), model::Offer>, | ||
maker_identity: Identity, | ||
maker_peer_id: PeerId, | ||
} | ||
|
@@ -64,6 +60,7 @@ impl Actor { | |
offers: Offers::default(), | ||
maker_identity, | ||
maker_peer_id, | ||
latest_offers: HashMap::new(), | ||
} | ||
} | ||
} | ||
|
@@ -73,24 +70,44 @@ impl Actor { | |
async fn handle_latest_offers(&mut self, msg: offer::taker::LatestOffers) { | ||
self.offers.insert(msg.0.clone()); | ||
|
||
for i in msg.0.iter() { | ||
tracing::info!( | ||
"Received new offer: {:?} with price {}", | ||
i.position_maker.counter_position(), | ||
i.price | ||
); | ||
self.latest_offers.insert( | ||
(i.contract_symbol, i.position_maker.counter_position()), | ||
i.clone(), | ||
); | ||
} | ||
|
||
if let Err(e) = self.projection_actor.send(projection::Update(msg.0)).await { | ||
tracing::warn!("Failed to send current offers to projection actor: {e:#}"); | ||
}; | ||
} | ||
|
||
async fn handle_propose_settlement(&mut self, msg: ProposeSettlement) -> Result<()> { | ||
let ProposeSettlement { | ||
order_id, | ||
bid, | ||
ask, | ||
quote_timestamp, | ||
} = msg; | ||
let ProposeSettlement { order_id } = msg; | ||
|
||
let cfd = self.db.load_open_cfd::<Cfd>(order_id, ()).await?; | ||
|
||
let proposal_closing_price = market_closing_price(bid, ask, Role::Taker, cfd.position()); | ||
let offer = self | ||
.latest_offers | ||
.get(&(cfd.contract_symbol(), cfd.position().counter_position())) | ||
.context("Cannot propose settlement without price")?; | ||
|
||
if !offer.is_safe_to_take(OffsetDateTime::now_utc()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given the frequent protocol failures the user might see some annoyance of "outdated offer" here when triggering collab settlement. This is unrelated to this fix, nothing to change here, but I wanted to point it out :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The timeout is currently set to 10 minutes . That's plenty of time to hopefully get an offer :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But that would mean that the only thing that protects us from using an outdated price is the automation's logic of "what is acceptable" as price. Is this fixing the problem of using an outdated price? Is the problem not that the price in the automation is potentially not up to date? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That should be fine. The taker simply proposes the latest price what he got from the maker in here. The logic whether to accept or decline this price is outside of this scope. |
||
bail!("The maker's offer appears to be outdated, cannot close position"); | ||
} | ||
|
||
let proposal_closing_price = offer.price; | ||
let offer_timestamp = offer | ||
.creation_timestamp_maker | ||
.format() | ||
.context("Failed to format timestamp")?; | ||
|
||
tracing::debug!(%order_id, %proposal_closing_price, %bid, %ask, %quote_timestamp, "Proposing settlement of contract"); | ||
tracing::debug!(%order_id, %proposal_closing_price, %offer_timestamp, "Proposing settlement of contract"); | ||
|
||
// Wait for the response to check for invariants (ie. whether it is possible to settle) | ||
self.collab_settlement_actor | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ We should remove the function
market_closing_price
and also use the maker's price in the projection - otherwise what we show in the UI does not match what is actually used!