-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Add IB Tiered Fee Model #8446
base: master
Are you sure you want to change the base?
Add IB Tiered Fee Model #8446
Conversation
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.
Nice! Leaving a few comments.
_monthlyTradeVolume = _monthlyTradeVolume.ToDictionary(kvp => kvp.Key, _ => 0m); | ||
} | ||
// Reprocess the rate schedule based on the current traded volume in various assets. | ||
ReprocessRateSchedule(_monthlyTradeVolume[SecurityType.Equity], _monthlyTradeVolume[SecurityType.Future], _monthlyTradeVolume[SecurityType.Forex], |
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.
Should this be done on month rollover only as well?
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.
Nah, the fee will change by sufficient volume/dollar volume traded within that month. It should be sensitive to per order level.
MarketOnOpenOrder(_spy, 30000); | ||
MarketOnOpenOrder(_aig, 30000); | ||
MarketOnOpenOrder(_bac, 30000); |
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.
Are these orders filled on the next day or right away? If the latest, might as well use MarketOrder? Same for the MarketOnClose ones
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.
They should be filled right away at 9:30am, same for market on close at 4pm
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.
Looking good! Just a couple more comments
// Add exchange fees + IBKR regulatory fee (0.02) | ||
return new CashAmount(ibFeePerContract + exchangeFeePerContract + 0.02m, Currencies.EUR); | ||
return new CashAmount(ibFeePerContract + exchangeFeePerContract + 0.02m, Currencies.USD); |
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.
Nice catch
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.
Would it be possible to run at least a few of these tests for the Python model as well? Just to make sure they are always kept the same when changed
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.
CC: @LouisSzeto 👁️
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.
Cool! Leaving some requests and concerns
feeResult += regulatory + transaction + clearing; | ||
|
||
// Update the monthly value traded | ||
_monthlyTradeVolume[SecurityType.Option] += quantity * orderPrice; |
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.
Whops don't think this state is correct, the lean engine can and will call GetOrderFee
multiple times for the same order, when submitting later when processing in the backtesting brokerage, can even be more times in cases of setHoldings where it can call it N times to get the best position size. Maybe something that could be done is look at the order status, if submitted use it to account for the monthly volume, should also keep a guard not to process the same order id multiple times I think, but needs more testing and asserting to be sure it's okay
Seems should make the monthly traded volume public so it can be asserted in the regression algorithm and accessible for the user
Should adjust the algo to also use SetHoldings and will make the bug of the multiple accounting more clearer,
__
btw CalculateOptionFee
already returns quantity * orderPrice
, what about the contract multiplier?
__
the adjustments being made here for equity and options fees, should they also be for the main IB fee model?
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.
btw CalculateOptionFee already returns quantity * orderPrice, what about the contract multiplier?
The fee is per contract, so we don't need to account for the contract multiplier
} | ||
|
||
// Add exchange fees + IBKR regulatory fee (0.02) | ||
return new CashAmount(ibFeePerContract[_futureCommissionTier] + exchangeFeePerContract + 0.02m, Currencies.USD); |
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.
This implementation seems like a slightly more generic version of the one at InteractiveBrokersFeeModel
seems they can be mostly shared, where InteractiveBrokersFeeModel
just uses tier 0?
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.
Hmm.. I would say it is the fee = tier 0 is "very coincident". Some cases the cost is completely different for fixed and tiered fee model, so we leave with this implementation in case that happens in the future.
The other 2 futures markets do not have a tiered structure, so we can share it. Yet if it happens in the future, we still need to make separate future fee models.
{ | ||
var value = Math.Abs(order.GetValue(security)); | ||
fee = 0.00002m * value; // 0.002% | ||
currency = security.QuoteCurrency.Symbol; |
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.
Whops careful! GetValue
returns in account currency, which might not be related to quote currency. Same comment for the other calls to GetValue
for forex & crypto
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.
CFD is direct copying from the original implementation, since it has no tier... I'll change it to order.AbsoluteQuantity * order.Price
then.
Both Forex and Crypto fees are in USD👌
12f0404
to
ae864e1
Compare
Description
Related Issue
Motivation and Context
Missing feature
Requires Documentation Change
Add to Writing Algorithms / Reality Modeling / Transaction Fee / Supported Models
How Has This Been Tested?
Types of changes
Checklist:
bug-<issue#>-<description>
orfeature-<issue#>-<description>