For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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. Since commission=2.615 is determined when submitting the order and does not change, margin is 2348.1-2.615=2345.485 and the price for computing the margin should be 2345.485 / (10 * 0.09) = 2606.095. But the OHLC prices on 03-19 are 2689, 2693, 2596, 2609 and trade price is 2615. I can't understand where the margin price 2606.095 is from.

    Can someone show me how the daily cash is calculated? Thanks a lot!


  • administrators

    @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 price 2615, and the close price is 2609 on that day, so I should make profit (2615-2609) * 10 = 60, minus commission 2.615, which is 60-2.615 = 57.385. The value at the end of day 3/19 should be 20000057.385, but the returned value is 20000051.985. Can you please help me to understand why there is a 5.4 difference? Thank you!


  • administrators

    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.


  • administrators

    @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 on 2018-03-19, which is 2615. Is it with a Limit 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 at 2615 and trade fill price is also 2615 without slippage. The OHLC prices are below:
    4032d4a4-849a-4793-aee8-64d0d95d97f5-image.png

    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 is 2609*0.9=2348.1, so the difference is 5.4. The method notify_cashvalue() calculates cash and value based on the margin cost 2353.5 at the trade fill price 2615, but calculates the daily profit based on the end of day close price 2609, 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
    

  • administrators

    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.



  • @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.


Log in to reply
 

});