log taker trade summary (#579)
* add new event for taker trade so arb bots can verify their execution cost without waiting for consume events Co-authored-by: Nicholas <nicholasgclarke@gmail.com>
This commit is contained in:
parent
08dfb0ddba
commit
9166b761e9
|
@ -4,6 +4,8 @@ Update this for each program release and mainnet deployment.
|
|||
|
||||
## not on mainnet
|
||||
|
||||
- New event: PerpTakerTradeLog immdediatly logs your last trade execution (#579)
|
||||
|
||||
## mainnet
|
||||
|
||||
### v0.15.0, 2023-5-11
|
||||
|
|
|
@ -9172,6 +9172,51 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpTakerTradeLog",
|
||||
"fields": [
|
||||
{
|
||||
"name": "mangoGroup",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "mangoAccount",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "perpMarketIndex",
|
||||
"type": "u16",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerSide",
|
||||
"type": "u8",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalBaseLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalQuoteLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerFeesPaid",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "feePenalty",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpForceClosePositionLog",
|
||||
"fields": [
|
||||
|
|
|
@ -397,6 +397,18 @@ pub struct FilledPerpOrderLog {
|
|||
pub seq_num: u64,
|
||||
}
|
||||
|
||||
#[event]
|
||||
pub struct PerpTakerTradeLog {
|
||||
pub mango_group: Pubkey,
|
||||
pub mango_account: Pubkey,
|
||||
pub perp_market_index: u16,
|
||||
pub taker_side: u8,
|
||||
pub total_base_lots_taken: i64,
|
||||
pub total_quote_lots_taken: i64, // exclusive fees paid
|
||||
pub taker_fees_paid: i128, // in native quote units
|
||||
pub fee_penalty: i128, // in native quote units
|
||||
}
|
||||
|
||||
#[event]
|
||||
pub struct PerpForceClosePositionLog {
|
||||
pub mango_group: Pubkey,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::logs::FilledPerpOrderLog;
|
||||
use crate::logs::{FilledPerpOrderLog, PerpTakerTradeLog};
|
||||
use crate::state::MangoAccountRefMut;
|
||||
use crate::{
|
||||
error::*,
|
||||
|
@ -64,9 +64,11 @@ impl<'a> Orderbook<'a> {
|
|||
let order_id = market.gen_order_id(side, price_data);
|
||||
|
||||
// IOC orders have a fee penalty applied regardless of match
|
||||
if order.needs_penalty_fee() {
|
||||
apply_penalty(market, mango_account)?;
|
||||
}
|
||||
let fee_penalty = if order.needs_penalty_fee() {
|
||||
apply_penalty(market, mango_account)?
|
||||
} else {
|
||||
I80F48::ZERO
|
||||
};
|
||||
|
||||
let perp_position = mango_account.perp_position_mut(market.perp_market_index)?;
|
||||
|
||||
|
@ -165,7 +167,7 @@ impl<'a> Orderbook<'a> {
|
|||
emit!(FilledPerpOrderLog {
|
||||
mango_group: market.group.key(),
|
||||
perp_market_index: market.perp_market_index,
|
||||
seq_num: seq_num,
|
||||
seq_num,
|
||||
});
|
||||
}
|
||||
let total_quote_lots_taken = order.max_quote_lots - remaining_quote_lots;
|
||||
|
@ -177,7 +179,17 @@ impl<'a> Orderbook<'a> {
|
|||
// realized when the fill event gets executed
|
||||
if total_quote_lots_taken > 0 || total_base_lots_taken > 0 {
|
||||
perp_position.add_taker_trade(side, total_base_lots_taken, total_quote_lots_taken);
|
||||
apply_fees(market, mango_account, total_quote_lots_taken)?;
|
||||
let taker_fees_paid = apply_fees(market, mango_account, total_quote_lots_taken)?;
|
||||
emit!(PerpTakerTradeLog {
|
||||
mango_group: market.group.key(),
|
||||
mango_account: *mango_account_pk,
|
||||
perp_market_index: market.perp_market_index,
|
||||
taker_side: side as u8,
|
||||
total_base_lots_taken,
|
||||
total_quote_lots_taken,
|
||||
taker_fees_paid: taker_fees_paid.to_bits(),
|
||||
fee_penalty: fee_penalty.to_bits(),
|
||||
});
|
||||
}
|
||||
|
||||
// Apply changes to matched asks (handles invalidate on delete!)
|
||||
|
@ -365,7 +377,7 @@ fn apply_fees(
|
|||
market: &mut PerpMarket,
|
||||
account: &mut MangoAccountRefMut,
|
||||
quote_lots: i64,
|
||||
) -> Result<()> {
|
||||
) -> Result<I80F48> {
|
||||
let quote_native = I80F48::from_num(market.quote_lot_size * quote_lots);
|
||||
|
||||
// The maker fees apply to the maker's account only when the fill event is consumed.
|
||||
|
@ -391,11 +403,11 @@ fn apply_fees(
|
|||
// breaks assumptions.
|
||||
market.fees_accrued += taker_fees + maker_fees;
|
||||
|
||||
Ok(())
|
||||
Ok(taker_fees)
|
||||
}
|
||||
|
||||
/// Applies a fixed penalty fee to the account, and update the market's fees_accrued
|
||||
fn apply_penalty(market: &mut PerpMarket, account: &mut MangoAccountRefMut) -> Result<()> {
|
||||
fn apply_penalty(market: &mut PerpMarket, account: &mut MangoAccountRefMut) -> Result<I80F48> {
|
||||
let fee_penalty = I80F48::from_num(market.fee_penalty);
|
||||
account
|
||||
.fixed
|
||||
|
@ -404,5 +416,5 @@ fn apply_penalty(market: &mut PerpMarket, account: &mut MangoAccountRefMut) -> R
|
|||
let perp_position = account.perp_position_mut(market.perp_market_index)?;
|
||||
perp_position.record_trading_fee(fee_penalty);
|
||||
market.fees_accrued += fee_penalty;
|
||||
Ok(())
|
||||
Ok(fee_penalty)
|
||||
}
|
||||
|
|
|
@ -9172,6 +9172,51 @@ export type MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpTakerTradeLog",
|
||||
"fields": [
|
||||
{
|
||||
"name": "mangoGroup",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "mangoAccount",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "perpMarketIndex",
|
||||
"type": "u16",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerSide",
|
||||
"type": "u8",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalBaseLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalQuoteLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerFeesPaid",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "feePenalty",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpForceClosePositionLog",
|
||||
"fields": [
|
||||
|
@ -18686,6 +18731,51 @@ export const IDL: MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpTakerTradeLog",
|
||||
"fields": [
|
||||
{
|
||||
"name": "mangoGroup",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "mangoAccount",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "perpMarketIndex",
|
||||
"type": "u16",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerSide",
|
||||
"type": "u8",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalBaseLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "totalQuoteLotsTaken",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "takerFeesPaid",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "feePenalty",
|
||||
"type": "i128",
|
||||
"index": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PerpForceClosePositionLog",
|
||||
"fields": [
|
||||
|
|
Loading…
Reference in New Issue