Please help to understand cash changes
-
Hi everyone,
I'm testing a simple futures strategy that long/short at 10-day high/low and when two SMA cross. The commission scheme is defined as:
class CommInfoFutures(bt.CommInfoBase): params = ( ('stocklike', False), ('commtype', bt.CommInfoBase.COMM_PERC), ('percabs', True) ) def _getcommission(self, size, price, pseudoexec): return abs(size) * price * self.p.mult * self.p.commission def get_margin(self, price): return price * self.p.mult * self.p.margin comm_rb = CommInfoFutures(commission=1e-4, margin=0.09, mult=10.0) cerebro = bt.Cerebro() cerebro.broker.addcommissioninfo(comm_rb, name='RB')
The backtesting runs on daily bars from 2018 to 2019. The first entry is triggered on 2018-03-16 and trade happens on 03-19, logged as:
2018-03-08 - cash = 20000000.0 value = 20000000.0 2018-03-09 - cash = 20000000.0 value = 20000000.0 2018-03-12 - cash = 20000000.0 value = 20000000.0 2018-03-13 - cash = 20000000.0 value = 20000000.0 2018-03-14 - cash = 20000000.0 value = 20000000.0 2018-03-15 - cash = 20000000.0 value = 20000000.0 2018-03-16 - cash = 20000000.0 value = 20000000.0 2018-03-16 - Entry Short: Order status=1 ref=1 price=2615.0 trig_price=2615.0 2018-03-19 - Order status: ref = 1, action = SELL, Price = 2615.0 Size = -1 Cost = 2353.5 Comm = 2.615 2018-03-19 - Trade ref = 1 PnL = 0.0 PnL+Comm = -2.615 2018-03-19 - cash = 19997703.885 value = 20000051.985000003 2018-03-20 - cash = 19997723.885 value = 20000070.185000002 2018-03-21 - cash = 19998043.885 value = 20000361.385 2018-03-22 - cash = 19998023.885 value = 20000343.185000002 2018-03-23 - cash = 20000523.885 value = 20002618.185000002 2018-03-26 - cash = 20000583.885 value = 20002672.785 2018-03-27 - cash = 19999883.885 value = 20002035.785
It looks the cash changes everyday with price after opening a short position. Is it because of the margin changes? If yes, on March 19, the margin cost+commission should be
margin + commission = value - cash = 20000051.985 - 19997703.885 = 2348.1
. Sincecommission=2.615
is determined when submitting the order and does not change, margin is2348.1-2.615=2345.485
and the price for computing the margin should be2345.485 / (10 * 0.09) = 2606.095
. But the OHLC prices on 03-19 are2689, 2693, 2596, 2609
and trade price is2615
. I can't understand where the margin price2606.095
is from.Can someone show me how the daily cash is calculated? Thanks a lot!
-
@jesseliu0 said in Please help to understand cash changes:
It looks the cash changes everyday with price after opening a short position.
And not only for short positions. Long positions do also have the bad habit of generating cash changes. It is daily because you are using daily data.
@jesseliu0 said in Please help to understand cash changes:> Is it because of the margin changes?
No. It is because the price changes. I don't know if you trade futures and if you with whom, but most brokers will instantly change the available cash in your account following each price tick.
@jesseliu0 said in Please help to understand cash changes:
Can someone show me how the daily cash is calculated? Thanks a lot!
Yes. For each tick in your favour, you get the multiplier per point in your favor in cash (x times your position obviously). The opposite happens when it goes against you.
Your log shows how the cash changes in multiples of
10
which is your multiplier. -
@backtrader
Thanks for explanation. I can understand the multiplier, but the value changes returned from notify_cashvalue() are still confusing. On 3/19 the first order opened the short position with the filling price2615
, and the close price is2609
on that day, so I should make profit(2615-2609) * 10 = 60
, minus commission2.615
, which is60-2.615 = 57.385
. The value at the end of day 3/19 should be20000057.385
, but the returned value is20000051.985
. Can you please help me to understand why there is a5.4
difference? Thank you! -
See:
-
Custom Commission Scheme
-
Incomplete Code
Are you really expecting me to follow the logic of something you can only follow?
-
-
Of course not if you are not interested.
I've explored the doc you listed but no clue. The custom commission scheme is in the top post. Appreciate any insight but that's ok if not. Thanks anyway. -
@jesseliu0 said in Please help to understand cash changes:
Of course not if you are not interested.
I believe you fail to understand the problem. It has nothing to do with interest. It has to do with the provided information
- No data
- Incomplete code
@jesseliu0 said in Please help to understand cash changes:
2018-03-16 - Entry Short: Order status=1 ref=1 price=2615.0 trig_price=2615.0 2018-03-19 - Order status: ref = 1, action = SELL, Price = 2615.0 Size = -1 Cost = 2353.5 Comm = 2.615 2018-03-19 - Trade ref = 1 PnL = 0.0 PnL+Comm = -2.615
You already know on
2018-03-16
at which price you will get matched on2018-03-19
, which is2615
. Is it with aLimit
order, is it not?But with missing data, missing type of order execution, missing ... any diagnostic is impossible.
-
Thank you for looking into this.
The order type is stop with trigger price at2615
and trade fill price is also2615
without slippage. The OHLC prices are below:
I think I know what's going on. Below is the output with commission set to 0. The margin cost based on fill price is
2615*0.9=2353.5
, and the margin cost based on close price is2609*0.9=2348.1
, so the difference is5.4
. The method notify_cashvalue() calculates cash and value based on the margin cost2353.5
at the trade fill price2615
, but calculates the daily profit based on the end of day close price2609
, which is(2615-2609) * 10 = 60
, so the value at the end of 3/19 is(20e6 - 2615 * 0.9) + 60 + 2609 * .9 = 20000054.6
, and the cash is(20e6 - 2615 * 0.9) + 60 = 19997706.5
. Both match the output.I'm not familiar the calculation detail at a real broker. Intuitively, the account value calculation should not involve margin cost, and the end-of-day cash should be based on the close price instead of fill price. Maybe the method notify_cashvalue() is supposed to return the cash and value at the moment of trade?
2018-03-16 - cash = 20000000.0 value = 20000000.0 value-cash = 0.0 close_price = 2689.0 margin_val = 2420.1 2018-03-16 - Close = 2689.0 Position size = 0 order = None 2018-03-16 - Entry Short: Order status=1 ref=1 price=2615.0 trig_price=2615.0 2018-03-19 - Order status: ref = 1, action = SELL, Price = 2615.0 Size = -1 Cost = 2353.5 Comm = 0.0 2018-03-19 - Trade: ref = 1 price = 2615.0 value = 2353.5 2018-03-19 - cash = 19997706.5 value = 20000054.6 value-cash = 2348.10000000149 close_price = 2609.0 margin_val = 2348.1 2018-03-19 - Close = 2609.0 Position size = -1 order = None 2018-03-20 - cash = 19997726.5 value = 20000072.8 value-cash = 2346.300000000745 close_price = 2607.0 margin_val = 2346.2999999999997 2018-03-20 - Close = 2607.0 Position size = -1 order = None
-
One of the major problems is talking about what you are not executing. Your code
@jesseliu0 said in Please help to understand cash changes:
def get_margin(self, price): return price * self.p.mult * self.p.margin
But you then say ...
@jesseliu0 said in Please help to understand cash changes:
The margin cost based on fill price is 2615*0.9=2353.5,
Which obviously has no
times 10
(i.e.: the multiplier in the above calculation).At least you mention the commission has changed ... but again ... INCOMPLETE CODE
Let's assume you have removed the multiplier and the commission from the equation. I cannot see the problem. Forgive me if I cannot write
20e6
but I really fail to see how that can help, because it only obscures things.- Cash:
20000000.0
- Entry at:
2615
. - Your desired margin:
0.9
- Cash remaining in your account after you enter the market:
20000000.00 - 2615 * 0.9 = 19997646.50
- Closing price:
2609
- Cash to be added to your account at the end of the day:
(2615 - 2609) * 10 = 60.00
- Cash at the end of the day:
19997646.50 + 60.00 = 19997706.50
.
Which as you indicates, it happens to be the REPORTED cash.
Is it really so difficult to put things in different lines to clarify the calculations? You may follow entire paragraphs with numbers interleaved with text. Sorry, I cannot.
@jesseliu0 said in Please help to understand cash changes:
I'm not familiar the calculation detail at a real broker. Intuitively, the account value calculation should not involve margin cost, and the end-of-day cash should be based on the close price instead of fill price.
You are not familiar at all. Rather than trying to clarify things with a simulation platform, I would go into the market and buy
1-future
of whatever and see how things work. Real life experience does really mean something. - Cash:
-
@backtrader said in Please help to understand cash changes:
Which obviously has no times 10 (i.e.: the multiplier in the above calculation).
In the first post, I put the code
comm_rb = CommInfoFutures(commission=1e-4, margin=0.09, mult=10.0)
I use 0.9 because 0.9 = 0.09 * 10.
@backtrader said in Please help to understand cash changes:
Cash remaining in your account after you enter the market: 20000000.00 - 2615 * 0.9 = 19997646.50
Closing price: 2609
Cash to be added to your account at the end of the day: (2615 - 2609) * 10 = 60.00
Cash at the end of the day: 19997646.50 + 60.00 = 19997706.50.The margin cost at the end of day should be based on close price 2609 instead of the price when entering the market 2615, so cash at the end of day should be 20000000.00 - 2609 * 0.9 + 60, instead of 20000000.00 - 2615 * 0.9 + 60.
About the value. My understanding is some money could move between margin cost and cash in the account, but the total account value should not be affected by margin cost. I think the account value at the end of day should be 20000000.00 + 60, instead of 20000000.00 + (2609 - 2615) * 0.9 + 60.
Sorry if the calculations confused you. I don't think more code helps since the problem and reasoning are very simple. More code just bring more confuse.
@backtrader said in Please help to understand cash changes:
I would go into the market and buy 1-future of whatever and see how things work. Real life experience does really mean something.
Yes I did.