Bootstrap margin fee exchange configuration #351
No reviewers
Labels
No labels
blocked
breaking
bug
dependencies
duplicate
enhancement
good first issue
help wanted
question
tech debt
testing
wontfix
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set.
Reference
scion/arbitrader!351
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bootstap-margin-fee-exch-configuration"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This pull request replaces https://github.com/agonyforge/arbitrader/pull/320
@AllirionX please have a look at my changes in the
PaperTradeService. I had a merge conflict there. Direct link to the diff: https://github.com/agonyforge/arbitrader/pull/351/files#diff-6b843429246f24a5598b1910f6350f8e1cd50476dec55d1f4ddcec2b695cc0a4A few things here:
exchange:{}|exchange:{}instead ofexchange:{}|margin:{}I also try to start the paper trading logs by{} paper exchange:so we can identify logs coming from the paper trading internal logic easilyI don't now if it's how it's supposed to work: if we set the leverage when buying on the short exchange, are we supposed to pay margin fees? I would think so, but then the setLeverage(2) in the TradingService.executeOrderPair method should not be set for the short exchange BUY orders - as we don't need the leverage.
Maybe better way to do this would be to check if a margin trade is required or not depending on the balances and leverage?
Create
Change checkBalance (LimitOrder order) to
And use
isMarginRequiredto see if we should use the margin fees.Thanks for the nice feedback 👍
I think we always pay margin fees even if we have enough balance for the borrowed coins (short), @scionaltera can you please confirm?
As far as I know setting value
2toorder.getLeverage()is only needed for Liquid exchange and has no impact in the remaining exchanges. @scionaltera can you confirm this as well?The exchange should decide whether it's a margin or non-margin trade by looking at
LimitOrder.getLeverage(). If it's not null, then it's a margin trade (regardless of long or short) and margin fees should be charged. If we really wanted to do it right for margin orders we wouldn't take the full amount out of the balance either. On a 2:1 trade (getLeverage() == 2) we'd only take half of the value away from the balance. It's not that important for Arbitrader at this time because we only ever set it to 2 and we never trade above our actual balance.In that case, we can have a method
useMarginto determine if we charge the margin fees or not.The fees could be:
and change the checkBalance method accordingly
One other wrinkle I just thought of - the PaperExchange should probably check whether it's configured with
margin: trueor not and reject margin orders if it is not supposed to be a margin-capable exchange. It would be a bug if we tried to submit a margin order to a non-margin exchange, but stranger things have happened.Lots of comments but only one actual problem. The way this code is written we might set
tradeFee: 0.0026andmarginFee: 0.0002based on the examples in the example configuration and the bot would return 0.0002 as the fee for the entire short trade which is incorrect. It should be 0.0028. I have pointed out all the places I saw where this needs to be fixed.This change to the comment is not accurate. The trade fee is applied to every trade. Long or short, margin or not.
This should be
shortExchangeFee.getTradeFee().add(shortExchangeFee.getMarginFee().get()). The trade fee and margin fees need to get added together.Again if it's a short trade the trade fee and margin fee need to be added together.
If it's a margin trade the trade fee and margin fee need to be added together.
The fee on a margin trade needs to be the trade fee + the margin fee.
It does check it with exchangeService.getExchangeMetadata(exchange).getMargin(). Currently, it rejects orders that would make any balance negative unless margin is enabled, via the check balance method
Aha, I didn't know that. I will fix it.
Thanks @AllirionX for your great feedback!
@scionaltera yeah, I have implemented a check condition for that use case.
This check is not necessary here if the useMargin method throws a MarginNotSupportedException when the leverage is not null but the exchange is not configured for it.
If this checks for funds, for margin enabled, etc. should we rename both checkBalance to verifyOrder ?
@ -260,3 +285,4 @@BigDecimal feePercentage = getFee(order);//Calculate fees in crypto currencyBigDecimal baseFee = exchangeService.getExchangeMetadata(exchange).getFeeComputation() == SERVER ? BigDecimal.ZERO : order.getOriginalAmount().multiply(feePercentage).setScale(BTC_SCALE,RoundingMode.HALF_EVEN);This should probably be removed: it's logic is already included in checkBalance and useMargin.
This should throw a MarginNotSupportedException if the order leverage is not null and the exchange does not have margin enabled, basically moving the check on line 70 to this method
This test throws an exception because we did not set the order leverage.
We should have another test for the happy scenario (with
order.getLeverage() != null) that does not throw an exceptionThanks, you were right. We were missing copying the leverage value and I also created an unit test to assert on that
This comment and the next one will be confusing now. It's "trade fee" and "margin fee".
Need to rename
shortFeetomarginFeehere and 'longFee' to 'tradeFee' below both in variable names and comments. They're both the individual fee rates and not the combined fees.This is incorrectly named. The method returns the margin fee, not the combined fees for a short trade.
Let's be as clear as we can be in these comments and say "Long exchange fee percent" on 183 and "Short exchange fee percent" on 185.
Between long and short exchanges and long and short trades and long and short fees there is a lot of room for ambiguity. That's why I'm trying so hard to make sure we use our terminology consistently.
The variable names confused me:
ExchangeFee has two fees: tradeFee and marginFee
But here:
tradeFee is the long exchange tradeFee
marginFee is the sum of tradeFee and marginFee for the longExchange
To avoid confusion we could use different variable names:
longTradeFee (= tradeFee)
shortTotalFee (= tradeFee + marginFee)
See other comment.
tradeFee is the long exchange trade fee, and marginFee is the sum of the short exchange tradeFee and marginFee.
They should be logged as such:
LOGGER.debug("Long trade fee percent: {}", longTradeFee);
LOGGER.debug("Short trade and margin fee percent: {} + {} = {}", shortTradeFee, shortMarginFee, shortTotalFee);
See other comment, the same naming convention should apply here as well.
Agreed. Once you take the
marginFeeand add thetradeFeeto it, it is specific to the short trade and it is the total of both the fees that apply to that trade.