Back to Community
Distributions of returns by asset in research

Does anyone know simple way to get returns of each asset from Backtest Result in research environment? I want plot histogram of returns by asset. I think it's basic thing and I'm sure somebody do it before me. I will be grateful if somebody share it or gives some advice.

5 responses

Hi Maksim,

You may know that detailed analysis of full backtests is possible in Research through Pyfolio. Here is a post introducing the feature. Note that the result of get_backtest is assigned to a variable bt; this object has some attributes that you may find useful (check them out by running dir(bt)).

Specifically, bt.positions is a DataFrame containing data on all the positions the algorithm held during the backtest. The cost_basis column tells you the average price paid for the position, and the last_sale_price column tells you the price at which the last share of that position is sold/covered. By taking the difference of these two columns you can get the returns of every position. Let me know if this works for you!

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.

Hi Nathan,

thanks for the replay. I tried it for the simplest algorithm and I'm confused.
bt.positions - is empty for my backtest but bt.transactions is valid.
I tried to use bt. transactions to compute return. But I got a return that different from the result of standard qbacktest.

Clone Algorithm
1
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 57a41f126e95ea12709575a3
There was a runtime error.

My notebook.

Loading notebook preview...
Notebook previews are currently unavailable.

Hi Maksim,

bt.positions is empty because your algorithm is only day trading; the positions are only recorded at the end of each day.

Your returns computation using bt.transactions has a couple problems with how the commissions are applied. Here's a corrected version:

def set_commistion(x):  
    return max(abs(x), 1.)  
#because int bt.transactions commision is None, I have to compute it by myself  
tr['_commis']  = tr['amount']*0.0075  
tr['_commis'] = tr['_commis'].apply(set_commistion)  

Basically, we need to put abs(x) instead of x because commissions are positive whether you're buying or selling. And .apply() doesn't work inplace; you have to reassign the result.

So once you make that change the returns calculation should be correct.

Thank you Nathan! It's bug in my computation, I will fix it and try it again. I'll share the results in this thread.