Difference between order.executed.price and order.executed.value
In the quickstart documentation, I see in the notify_order function the values order.executed.price and order.executed.value, what is the difference between the two?
In the output, it seems that they always have the same values.
The default stake size is
1and it's a stock. Price and value are bound to be the same.
Thank you for your answer. I have one additional question.
In the documentation, it seems that Price and Cost are the same whether it is an executed buy or sell.
However, when I ran the code from my laptop, it seems that when the order is an Executed Sell, the cost is equal to the price of the associated buy. Is it normal?
Even if you believe in the power of magic ... nobody can know what you have executed.
lu-victor last edited by lu-victor
Sorry for the lack of clarity. Here's my code (it is simply the code from the documentation with Facebook data):
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv) import backtrader as bt class TestStrategy(bt.Strategy): def log(self, txt, dt=None): ''' Logging function for this strategy''' dt = dt or self.datas.datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data dataseries self.dataclose = self.datas.close self.order = None def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') # Write down: no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose) if self.order: return if not self.position: if self.dataclose < self.dataclose[-1]: if self.dataclose[-1] < self.dataclose[-2]: self.log('BUY CREATE, %.2f' % self.dataclose) self.order = self.buy() else: if len(self) >= (self.bar_executed + 5): self.log('SELL CREATE, %.2f' % self.dataclose) self.order = self.sell() if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere # modpath = os.path.dirname(os.path.abspath(sys.argv)) # datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt') datapath = 'FB.csv' # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2018, 1, 1), # Do not pass values before this date todate=datetime.datetime(2018, 1, 30), # Do not pass values after this date reverse=False) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(100000.0) cerebro.broker.setcommission(commission=0.001) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Lesson number 1 for algotrading (taught in chess and good for life in general)
Look at what you have right in front of your nose. (You can also formulate it like: "Pay attention to details")
Which means that if you open this forum, each and every time, you will see the following at the top
For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Changing the stake to 10, I obtain the values in the screenshot above.
It seems that the cost of the executed sell is always equal to the the cost of the previous executed buy. It is normal behavior of the system? It seems to be in contradiction from the values I see in the documentation.
I would have to find the discussion and commit, but I recall the semantics of value were changed early in the development phase. The sell order would return the value which would have been acquired plus the pnl.
I am facing the exact same error as described above. I don't see any ticket raised on github either.
@carameldragon I don't think this is an error, it's just a little confusing. The cost of an order doesn't change when you sell it. If you buy something for $100 and then sell it for $120, the cost is still $100 and the P&L is +$20. BT captures the P&L in the trade object (with and without commissions).
There is no proceeds tracked in an Order which is what I think you are after. You can get that with
order.executed.price * order.executed.sizefor gross proceeds, and then factor in commission to get net proceeds.
valuefield in Order is a bit ambiguous and I think leads to confusion. It would have been better named