Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Buy/Sell log question

Guys,

How to log the buy/sell quantity, and the price at which it was executed for each buy/sell operation ?

13 responses

I've tried logging the first transaction:
(amount * cost_basis) + cash

(amount * last_sale_price) + cash

(amount * Price) + cash

(amount * Open price) + cash

(amount * Close price) + cash

However... the math doesn't work - I'm either getting more or less than the starting cash value.
Tried disabling the commission, but that didn't do the trick either.

So, how can I log the exact share price for the transaction ?

There really isn't a good way to log the price at which an order executes. However, this information is automatically captured in the backtest object. The simplest way to view the transactions is to open the backtest, then click on the 'Activity' tab, then click on 'Transactions', and finally click the blue 'Load Transactions' button. This will bring up a list of all the order fills with the time and price. Note the prices include commission.

I must admit there is a sort of annoying 'bug' with the transactions list making the sort order not exactly chronological. Moreover, there isn't a way to sort and filter the transactions. The original version of the backtest display had those features. A bit of a hack is to add /old to the end of the backtest URL right in the browser and then refresh. This will bring up the original display. Click on 'transactions' in the left menu area. That brings up a nicer (in my humble opinion) view.

Additionally, one can get a dataframe with the transactions in a notebook. Go to a backtest and select the 'Notebook' tab. Replace the default bt.create_full_tear_sheet() line with bt.transactions and run the cell. This dataframe is nice because it also breaks out the commissions.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Dobri,

there are position and transaction records in the backtester.
Go to the backtest page: All backtests -> select backtest -> Activity -> Positions -> Load positions ...

And just for the sake of testing - is there a way to "force" the algorithm to use the exact open or close price ?
For example - to run the reballance function on market close or something like that..?

Is the commission price added to the transaction amount, OR, deducted from the cash leftover from the transaction ?

@Dobri Dobrev One can set both the slippage and commission models. These functions determine at what price, and how much of an order fills, and the commissions paid. The standard models cover most typical needs, but custom functions can also be written without much difficulty to handle any special requirements. To 'force' the algorithm to use the exact open or close price there is a model called NoSlippagebut the same results can be had by using the other slippage models such as FixedSlippage. Something like this can be added in the initialize function to get orders to completely fill at the days close price:

# Placing either of the following into the initialize function will cause orders to fill completely at the close price of the current bar  
set_slippage(slippage.NoSlippage())  
set_slippage(slippage.FixedSlippage(spread=0)

# Place orders at market close to have orders fill at the days close price  
schedule_function(  
        func=place_orders,  
        date_rule=date_rules.every_day(),  
        time_rule=time_rules.market_close()  
    )

Commissions can be set in a similar way with the set_commission method. The commission amount always reduces the transaction amount (added to the cost of a buy and subtracted from the proceeds of a sell). The transaction amount is what's applied to the account cash value (subtracted for a buy and added for a sell). This is similar to what one sees in an actual broker account.

Hope that answers the questions.

@Dan Whitnable

Just a question.. since as you know I'm trying to determine why there is such a huge difference between 2 backtests - one here and one done in backtrader...

  • I'm using SPY "daily" datasets from several locations (Yahoo Finance, Alpha Vantage, STOOQ France, NASDAQ).

  • In backtrader I'm generating the signals on the first day of the backtest, and the signals are executed on the "open" price of the next day (that can quickly be "tempfixed" by starting the backtest one day early), and it executes with the daily open since I'm not using intraday data.

  • I notice Quantopian acts directly on the 1st day - not with the daily "Open" price, but with the price of: 1-minute after market open + order creation = ~3? bars after the daily "open" price (if I'm not mistaken). I tried the method above hoping it'd "act" on the open price of the next day (so I could compare my results and hopefully see no difference (or at least less of a)), but it again didn't match with what I have from the free datasets.

At the end I get ~400-500 less buy/sell orders in backtrader comparing to quantopian, and there (I presume) is the reason of the huge difference I see.

If I buy daily (or 1-minute) data from, for example - quandl, will it match (more or less) with the buy/sell prices I get in "Transactions" on a full backtest? I get that maybe the free datasets aren't that accurate (I also get differences when testing between them - the signals trigger differently (and incorrectly) due to various differences between OHLC prices of the datasets, and in comparison with Qt and TradingView (I also noticed some differences between Qt and TV, so again I presume its related to the datasets)).

I'm banging my head with this for 2 weeks now... :)
Hopefully you'll point me in the right direction, as always.

Regards,
D

What is the 'huge difference' between the two backtest that you are seeing? Is it just the transactions? It was mentioned "there were ~400-500 less buy/sell orders in backtrader compared to Quantopian". Is that trading only SPY daily? Over what timeframe?

I don't think the 'accuracy' of the data is typically an issue. Most sources are pretty good and any little error now and again shouldn't impact the overall backtest. Using data from Quandl or data from Yahoo shouldn't be a game changer. The biggest issue (when it comes to data) is that Backtrader relies on 'adjusted' prices. Backtrader is pretty basic and doesn't incorporate a 'corporate actions' data feed. It relies on corporate action information to be incorporated into any adjustments. There was an explanation of how that can impact backtests in this post.

I would focus on your trading logic. Ensure the logic, and any signals or factors it relies on, are truly the same across platforms. This is actually a huge problem for institutions who test scenarios using one platform but them implement real trades in another. If you attach the Q algo you are using and then a copy of the versions you are using on the other platforms it may help.

Maybe also focus on the 'signals'. It was stated "the signals trigger differently (and incorrectly) due to various differences between OHLC prices of the datasets". Some signals are just plain erratic and hyper-sensitive to small variations in data (RSI with a short window length is one) and sensitive to the amount of data and look-back (any signal that relies on exponential averages). Another issue with signals is often the definition (and underlying calculations) vary from source to source. If you are writing your own that may not be an issue. If you are relying on the platform's version of a particular signal that could be another source of any differences. What 'signals' are being used in the algo?

I'll attach an algo with a custom slippage model that will trade at the open price each day. That may help debug some of the differences.

Attached is an algo which uses a custom slippage model to fully fill every order at the days open price. Maybe use this for debugging?

Does order_target_percent execute "Market" order, or some other (perhaps Limit) type? Because from what I see @ logs, reballance function executes at 09:31, but order creation timestamp shows as created 3-4 hours later...

I believe you are looking at the transaction list when you state "order creation timestamp shows as created 3-4 hours later"? Quantopian logs and transactions use the user's computer timezone. More precisely, the logs and transactions use the timezone reported by the browser which they are running. The intention is to have a backtest 'look and feel' as if it were running real time. The times therefore reflect a user's current timezone. Understandably, this can be confusing especially if one travels and changes timezones or often simple debugging as in this case. That is probably why you feel the orders were created 3-4 hours later?

There isn't a way to change this behavior within Quantopian. However, there are some browser extensions which can help. I personally use a Chrome extension called 'Change Timezone'. It's a simple extension which allows one to set the timezone the browser 'sees' separate from that which is set by the computer. I like setting the timezone to 'US Eastern' so all the logs align with the US market hours. There are other extensions which do the same thing and I'm not promoting this one. Just offering it as an example. Other browsers may have similar extensions.

I any case, if one's browser time is set to US Eastern or market time, one should see the transactions in the above algo all executing at 9:31.

Well... if I was able to "ingest" my iqfeed minute dataset into zipline, I'd be able to test everything more precisely, problem is ... it throws up some stack traces and won't ingest. Hopefully someone @ github can take a look at why.

@Dan

Is the data used to calculate indicators (for example - using data.history()) - adjusted, or unadjusted ?
The return data is adjusted (as per the documentation), bur is the data actually been used for calculations adjusted or not?