-
-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix closing fee #475
fix closing fee #475
Changes from all commits
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 |
---|---|---|
|
@@ -102,10 +102,12 @@ func (k Keeper) OpenPerpetualFuturesPosition(ctx sdk.Context, positionId string, | |
func (k Keeper) ClosePerpetualFuturesPosition(ctx sdk.Context, position types.PerpetualFuturesPosition) error { | ||
params := k.GetParams(ctx) | ||
commissionRate := params.PerpetualFutures.CommissionRate | ||
// FIXME: Size_ cannot be used like this. | ||
// It causes the inconsistency between the position and the token amount. | ||
feeAmountDec := position.PositionInstance.Size_.Mul(commissionRate) | ||
tradeAmount := position.PositionInstance.Size_.Sub(feeAmountDec) | ||
|
||
// At closing the position, the trading fee is deducted. | ||
// fee = positionSize * commissionRate | ||
positionSizeInMicroDec := sdk.NewDecFromInt(*position.PositionInstance.SizeInMicro) | ||
feeAmountDec := positionSizeInMicroDec.Mul(commissionRate) | ||
tradeAmount := positionSizeInMicroDec.Sub(feeAmountDec) | ||
feeAmount := feeAmountDec.RoundInt() | ||
|
||
baseUsdPrice, err := k.GetCurrentPrice(ctx, position.Market.BaseDenom) | ||
|
@@ -117,19 +119,10 @@ func (k Keeper) ClosePerpetualFuturesPosition(ctx sdk.Context, position types.Pe | |
return err | ||
} | ||
|
||
// TODO: this is wrong. refer to Issue#407 | ||
// maybe this todo is related to the above fixme content. | ||
if !feeAmount.IsZero() { | ||
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, position.Address.AccAddress(), types.ModuleName, sdk.Coins{sdk.NewCoin(position.Market.BaseDenom, feeAmount)}) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
quoteTicker := k.GetPoolQuoteTicker(ctx) | ||
baseMetricsRate := types.NewMetricsRateType(quoteTicker, position.Market.BaseDenom, baseUsdPrice) | ||
quoteMetricsRate := types.NewMetricsRateType(quoteTicker, position.Market.QuoteDenom, quoteUsdPrice) | ||
returningAmount, lossToLP := position.CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate) | ||
returningAmount, lossToLP := position.CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate, feeAmount) | ||
|
||
// Tell the loss to the LP happened by a trade | ||
// This has to be restricted by the protocol behavior in the future | ||
|
@@ -141,6 +134,7 @@ func (k Keeper) ClosePerpetualFuturesPosition(ctx sdk.Context, position types.Pe | |
} | ||
|
||
returningCoin := sdk.NewCoin(position.RemainingMargin.Denom, returningAmount) | ||
|
||
if returningCoin.IsPositive() { | ||
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, position.Address.AccAddress(), sdk.Coins{returningCoin}); err != nil { | ||
return err | ||
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 code patch adds a trading fee deduction and modifies the returning amount calculation in Improvements:
Bug Risk:
Overall, the changes seem to improve the code's functionality. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -241,7 +241,7 @@ func (m PerpetualFuturesPosition) RequiredMarginInMetrics(baseMetricsRate, quote | |
} | ||
|
||
// CalcReturningAmountAtClose calculates the amount of the principal and the profit/loss at the close of the position. | ||
func (m PerpetualFuturesPosition) CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate MetricsRateType) (returningAmount math.Int, lossToLP math.Int) { | ||
func (m PerpetualFuturesPosition) CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate MetricsRateType, tradingFee sdk.Int) (returningAmount math.Int, lossToLP math.Int) { | ||
principal := m.RemainingMargin.Amount | ||
// pnlAmountInMetrics represents the profit/loss amount in the metrics asset of the market. | ||
// In the most cases, it means it's in "usd". | ||
|
@@ -260,6 +260,14 @@ func (m PerpetualFuturesPosition) CalcReturningAmountAtClose(baseMetricsRate, qu | |
lossToLP = sdk.ZeroInt() | ||
} | ||
|
||
// Subtract the trading fee. | ||
if returningAmount.LT(tradingFee) { | ||
// Return 0 returning amount and the trading fee subtracted by the returning amount as LossToLP | ||
return sdk.ZeroInt(), tradingFee.Sub(returningAmount) | ||
} | ||
|
||
returningAmount = returningAmount.Sub(tradingFee) | ||
|
||
return returningAmount, lossToLP | ||
} | ||
|
||
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 review:
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 code changes seem to add functionality related to trading fees calculation. The One suggestion for improvement would be to validate the Overall, the code changes appear to be low risk, as they do not significantly alter the existing functionality. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -691,6 +691,7 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
position types.PerpetualFuturesPosition | ||
closedBaseRate sdk.Dec | ||
closeQuoteRate sdk.Dec | ||
tradingFee sdk.Int | ||
expReturn math.Int | ||
expLoss math.Int | ||
}{ | ||
|
@@ -712,7 +713,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.00002"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(11000000), | ||
tradingFee: sdk.NewInt(1000000), | ||
expReturn: sdk.NewInt(10000000), | ||
}, | ||
{ | ||
name: "Profit Short position in quote denom margin", | ||
|
@@ -732,7 +734,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.00001"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(11000000), | ||
tradingFee: sdk.NewInt(1000000), | ||
expReturn: sdk.NewInt(10000000), | ||
}, | ||
{ | ||
name: "Loss Long position in quote denom margin", | ||
|
@@ -752,6 +755,7 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.000009"), | ||
closeQuoteRate: uusdcRate, | ||
tradingFee: sdk.ZeroInt(), | ||
expReturn: sdk.NewInt(0), | ||
}, | ||
{ | ||
|
@@ -772,7 +776,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.0000105"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(1000000), | ||
tradingFee: sdk.NewInt(500000), | ||
expReturn: sdk.NewInt(500000), | ||
}, | ||
{ | ||
name: "Profit Long position in base denom margin", | ||
|
@@ -792,7 +797,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.00002"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(1500000), | ||
tradingFee: sdk.NewInt(500000), | ||
expReturn: sdk.NewInt(1000000), | ||
}, | ||
{ | ||
name: "Profit Short position in base denom margin", | ||
|
@@ -812,7 +818,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.00001"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(2000000), | ||
tradingFee: sdk.NewInt(1000), | ||
expReturn: sdk.NewInt(1999000), | ||
}, | ||
{ | ||
name: "Loss Long position in base denom margin", | ||
|
@@ -832,7 +839,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.000009"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(888889), | ||
tradingFee: sdk.NewInt(100), | ||
expReturn: sdk.NewInt(888789), | ||
}, | ||
{ | ||
name: "Loss Short position in base denom margin", | ||
|
@@ -852,7 +860,8 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.000011"), | ||
closeQuoteRate: uusdcRate, | ||
expReturn: sdk.NewInt(909091), | ||
tradingFee: sdk.NewInt(1000), | ||
expReturn: sdk.NewInt(908091), | ||
}, | ||
{ | ||
name: "Loss Exceeds Margin: Long position in base denom margin", | ||
|
@@ -872,6 +881,7 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
}, | ||
closedBaseRate: sdk.MustNewDecFromStr("0.000009"), | ||
closeQuoteRate: uusdcRate, | ||
tradingFee: sdk.ZeroInt(), | ||
expReturn: sdk.NewInt(0), | ||
expLoss: sdk.NewInt(-111111), | ||
}, | ||
|
@@ -885,7 +895,7 @@ func TestCalcReturningAmountAtClose(t *testing.T) { | |
sizeInMicro := types.NormalToMicroInt(tc.position.PositionInstance.Size_) | ||
tc.position.PositionInstance.SizeInMicro = &sizeInMicro | ||
|
||
returningAmount, lossToLP := tc.position.CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate) | ||
returningAmount, lossToLP := tc.position.CalcReturningAmountAtClose(baseMetricsRate, quoteMetricsRate, tc.tradingFee) | ||
fmt.Println(returningAmount, lossToLP) | ||
if !tc.expReturn.Equal(returningAmount) { | ||
t.Error(tc, "expected %v, got %v", tc.expReturn, returningAmount) | ||
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. with the code patch. It's adding a new variable (tradingFee) to the TestCalcReturningAmountAtClose function, and it is also being used in the CalcReturningAmountAtClose function. This new variable should be properly initialized before calling CalcReturningAmountAtClose, otherwise it might lead to unexpected behaviours. Also, it should be checked that the tradingFee value is valid (non-negative). Apart from that, I would recommend adding some documentation to the TestCalcReturningAmountAtClose function, so it is easier for other developers to understand what the code is doing. 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 code patch appears to be a test case for the There are no obvious bug risks in this code review. However, some potential improvements could include providing more descriptive comments, renaming variables to make them clearer, or adding additional test cases to cover more edge cases. |
||
|
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.
the code review: