How to calculate open position cost basis?



  • Can anybody suggest how to do it? As only current price and size attributes present in Position object I'm assuming I need to calculate cost basis when orders are filled. Is there any code examples how to do it?


  • administrators

    Cost basis is managed by the CommissionInfo objects which live in the broker.

    If you add/set nothing, then you will have a stocklike default CommissionInfo.

    You can get to the object with (from a Strategy instance for example)

    comminfo = self.broker.getcommissioninfo(data)
    

    The broker reference is here: Docs - Broker

    The CommissionInfo family is documented here:

    The actual method to get the cost of an operation is getoperationcost(size, price), which always returns an absolute (i.e.: positive) value.



  • @backtrader said in How to calculate open position cost basis?:

    The actual method to get the cost of an operation is getoperationcost(size, price), which always returns an absolute (i.e.: positive) value.

    I think I'm missing something fundamental here. For getoperationcost to return cost basis I need to pass entry price to it, right? Position object has only current price as far as I understood.

    Where can I get average entry price for the position then? Should I calculate it when order is filled?



  • @Ed-Bartosh

    I think you can get it from the trades using strategy.notify_trade() or from the orders using strategy.notify_order(). Get prices, store them separately and do the math.

    For trades you may check .justopened event and get trade.price (https://www.backtrader.com/docu/trade.html)

    For orders you might check order.complete and get order.executed.price
    (https://www.backtrader.com/docu/order.html)

    Also if you check position.price just after the order is executed, then this price may help.



  • @ab_trader thanks. That's what I was afraid of :) See my first message. I was hoping to get cost basis automagically, something similar to this: Position object



  • @Ed-Bartosh it can be a good point for further improvement. If you can offer the approach on how to implement it in the existing framework, then it'll help to community.


  • administrators

    @Ed-Bartosh quoting from the link:

    cost_basis
    Float: The volume-weighted average price paid (price and commission) per share in this position.

    The question here is if the volume-weighted average price is actually the cost of entering the position.

    Putting aside that philosophical detail, there is real problem with the definition:

    • A position per se doesn't have any associated commission costs

    Of course you may argue that if you open a position it has taken money from you in the form of value to enter and the commission for the broker. But you may exit the on-line application of your broker, you log in again and the position is just a position and has no associated commission

    As pointed out by @ab_trader, the actual cost is given you by the Trades.



  • @backtrader said in How to calculate open position cost basis?:

    Of course you may argue that if you open a position it has taken money from you in the form of value to enter and the commission for the broker. But you may exit the on-line application of your broker, you log in again and the position is just a position and has no associated commission

    I'm not sure I'm getting your point here. Even if I re-login to the broker application I'm able to see position cost basis or average cost if you prefer. It's also available through the API, e.g. by updatePortfolio() call of IB API.


  • administrators

    But not all brokers are created equal and the goal of backtrader was to be as generic as possible, whilst at the same time providing as much as possible.

    Even if someone has created an API/data structure that mimics a specific data strcuture/method of a broker's API, that doesn't make it an standard.

    One other reason why in the design of Position, the inclusion of commissions wasn't considered:

    • Multi-Strategy approach

    You can have 2 or more strategies which for whatever the reason operate on the same asset. The position is general for all strategies, to let them know what the overall status is, but the commissions are notified individually to the strategies by means of Order notifications and Trade notifications. If the commissions were all inserted in the position, all strategies would understand that the entire amount belongs to the operations they have executed, this not being the case.

    Most of what Interactive Brokers gives you in a Position is in the Trade. Namely:

    • status (int): Trade status
    • dt (float): float coded datetime
    • barlen (int): number of bars the trade has been active
    • size (int): current size of the Trade
    • price (float): current price of the Trade
    • value (float): current monetary value of the Trade
    • pnl (float): current profit and loss of the Trade
    • pnlcomm (float): current profit and loss minus commission


  • @backtrader said in How to calculate open position cost basis?:

    If the commissions were all inserted in the position, all strategies would understand that the entire amount belongs to the operations they have executed, this not being the case.

    Why would all strategies understand that if position is by design shared between strategies? This is actually good thing as position doesn't belong to the strategy, but to the portfolio from my point of view.

    Correct me if I'm wrong but as far as I understood you're saying that position cost basis or average position cost is something that's not generic?

    IB(and other brokers too, I believe) shows average position cost and doesn't care of how many strategies I used to build this position. Why for it's so different for backtester?

    Please, don't get me wrong. I'm not criticising backtester design. The work you've done is exceptional and I'm very impressed by the design and current implementation. I'm just trying to understand it better.



  • Most of what Interactive Brokers gives you in a Position is in the Trade

    This is just not true. It shows me average position cost including commissions. It's recalculated after each fill.



  • Looking more carefully thru position.py I found out that position.price is a size-weighted average price for current position, calculated considering position changes. Which is a cost-basis, am I correct?

    Based on docs I thought that it is a price of position based on last asset price.



  • @ab_trader thank you very much! I was also confused by the docs and then by this thread. position.price is what i was looking for.



  • I think I was too quick on this. position.price is not exactly cost basis as it's calculated without using commission. I set commission to 0, that's why the value was the same.

    With this code in notify_order:

        def notify_order(self, order):
            if order.status == order.Completed:
                print self.getposition(order.data).price, (abs(order.executed.value) + order.executed.comm) / abs(order.executed.size)
    

    I've got this output:

    106.68 107.7468
    

    I'm not entirely sure, but shouldn't the cost basis and position.price be negative for the short position?



  • @Ed-Bartosh Size is negative. Price is positive.



  • @ab_trader true. anyway it's not what I'm looking for as commission is not included into calculation.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.