Back to Community
ETF market rotation strategy

ETF market rotation strategy provides steady positive results and small drawdown

Clone Algorithm
1498
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: 54ab04f91478200917c4a26a
We have migrated this algorithm to work with a new version of the Quantopian API. The code is different than the original version, but the investment rationale of the algorithm has not changed. We've put everything you need to know here on one page.
There was a runtime error.
37 responses

Very interesting, particularly because you pick a best one and not a group of etf's. One question as I look for curve fitting when I look at an algo and I see

 rank = p * 0.7 + v * 0.3  

Why this ratio and did you test other ratio's?

Best, Peter

Good job! Also excellent to have largely avoided some of the remarkable downturns during that period.

sir,
Why not using history function?

@batch_transform(window_length=83)  
def accumulateData(data):  
    # return price_history = history(bar_count=20, frequency='1d', field='price')  
    return data  

I may have munged it a bit... Here's a compact, version. Doesn't get the same results, so your entry/exit technique must impart spin of some sort...

[Edit: Updated the whole ranking mechanism. getting consistent results now.]

import math  
import numpy

lookbackPeriods = 63  
historicPeriods = 83  
volatilityPeriods = 20

def initialize(context):  
    set_symbol_lookup_date('2007-12-31')  
    #context.stocks = symbols("EDV","VGT","VCR","VB","VAW","VHT","IBB")  
    context.stocks = symbols("VAW","VHT","IBB","EDV","VGT","VCR","VB")  
    context.stockMetrics = {}  
    for stock in context.stocks:  
        context.stockMetrics[stock] = Metric(0,0,0)  
    context.currentMonth = 0  
def handle_data(context, data):  
    date = get_datetime()  
    month = date.month  
    if context.currentMonth == month:  
        return  
    context.currentMonth = month

    historic = history(historicPeriods, "1d", "close_price")  
    historic = historic.dropna(axis=1)  
    for stock in context.stocks:  
        if (stock in historic):  
            context.stockMetrics[stock] = GetStockMetrics(historic[stock], lookbackPeriods)  
        else:  
            context.stockMetrics[stock] = Metric(0,0,0)  
    best = GetBestRanked(context.stockMetrics)  
    if (best == None):  
        print("All securities ranked 0.0")  
    for stock in context.stocks:  
        if (stock == best):  
            order_target_percent(stock, 1)  
            print(stock.symbol, context.stockMetrics[stock].ToString())  
        else:  
            order_target_percent(stock, 0)  
def GetBestRanked(stockMetrics):  
    list = [metric.Performance for metric in stockMetrics.values()]  
    minP, maxP = GetMinMax(list)  
    list = [metric.Volatility for metric in stockMetrics.values()]  
    minV, maxV = GetMinMax(list)  
    isValid = False  
    for stock in stockMetrics:  
        p = stockMetrics[stock].Performance  
        v = stockMetrics[stock].Volatility  
        if (p != 0.0 and v != 0.0):  
            p = .7 * (p - minP) / (maxP - minP)  
            v = .3 * (v - minV) / (maxV - minV)  
            rank = p - v  
            stockMetrics[stock].Performance = p  
            stockMetrics[stock].Volatility = v  
            stockMetrics[stock].Rank = rank  
            isValid = True  
    if (isValid):  
        keyValuesList = sorted(stockMetrics.items(), key=lambda x: x[1].Rank)  
        if (keyValuesList[-1][1].Rank != 0.0):  
            return keyValuesList[-1][0]  
        else:  
            return None  
    else:  
        return None  
def GetStockMetrics(prices, period):  
    volatilities = []  
    x = 0  
    volatilityWindow = volatilityPeriods + 1  
    for i in xrange(-period, 0):  
        volatilities.append(GetHistoricalVolatility(prices[i - volatilityWindow : volatilityWindow + x], volatilityPeriods))  
        x += 1  
    meanVolatility = sum(volatilities) / period  
    performance = (prices[-1] - prices[-period]) / prices[-period]  
    return Metric(0, performance, meanVolatility)

def GetHistoricalVolatility(prices, period):  
    normalizedPrices = numpy.asarray(prices) / prices[0]  
    volatility = numpy.std(normalizedPrices)  
    return volatility

def GetMinMax(arr):  
   return min(arr), max(arr) 

class Metric(object):  
    def __init__(this, r, p, v):  
        this.Rank = r  
        this.Performance = p  
        this.Volatility = v  
    def ToString(this):  
        toString = "Rank:{0:<7.5f} performance:{1:<7.5f} volatility:{2:<7.5f}".format(this.Rank, this.Performance, this.Volatility)  
        return toString     

Print log:

2014-07-01 PRINT('EDV', 'Rank:0.45876 performance:0.51824 volatility:0.05949')  
2014-08-01 PRINT('VGT', 'Rank:0.46813 performance:0.62635 volatility:0.15823')  
2014-09-02 PRINT('IBB', 'Rank:0.40000 performance:0.70000 volatility:0.30000')  
2014-10-01 PRINT('VHT', 'Rank:0.51983 performance:0.69815 volatility:0.17832')  
2014-11-03 PRINT('IBB', 'Rank:0.40000 performance:0.70000 volatility:0.30000')  
2014-12-01 PRINT('VHT', 'Rank:0.58249 performance:0.66101 volatility:0.07853')  
2015-01-02 PRINT('EDV', 'Rank:0.64355 performance:0.70000 volatility:0.05645')  

the differnce might be explained by p * 0.5 + v * 0.5 vs p * 0.7 + v * 0.3 ?

@Dave M.'s use of volatility + return performance is good to know about and study. I thank ye kindly for your efforts and sharing.

I did swap out the flip-flopped min/max @Dave M. had going and simply subtracted the volatility instead. Plus, when used with .7 and .3, the numbers still don't come out like his. I used all of his securities too, but even when duplicated exactly, the entry/exit change alters things. I'd have to guess the extra delay in the exit first then enter one period later (which ends up being 2 periods) of @Dave's code may have made the difference.

Reworking other quant's code is good practice for learning this sometimes tricksy language. That's the only reason I even attempted it (and others). Python'ers will no doubt be able to eliminate many of the loops with embedded matrix algebra -- a thing I continue to struggle with.

Do any portfolios model tax consequences? The question is not specific to this strategy, but this one looks interesting enough to continue refining the model.

not automatically, its always possible to do via extending the Run Summary or a custom logging function. IB has a tax report buyt thats very US oriented. As this is country dependent and personal circumstances dependent it's hard to model this in a more general fashion, however Quantopian could create a configurable module that allows a user to state the tax on transactions (UK), tax on profits (AUS,US, UK), compensation of losses (AUS,US), tax on total average holding (NL), tax on holding at 31st Dec... etc etc

Return for the last 2 years (period 1/1/2013 to end of 2014) is all along below SPY.

How did you pick the ETFs? Some sector ETFs are commented out.

Just for reference, this is Dave's backtest with the financial ETF plugged back in. The return is a little lower but the drawdown is the same. (I had wondered if the drawdown would be increased)

Clone Algorithm
77
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: 54aed632db51056d77188e3a
There was a runtime error.

Looking at Market Tech's re-factoring of this algorithm, if you replace this context.stocks line

context.stocks = symbols('VHT','VGT','VCR','IBB','EDV','VB','VAW')

with this:

context.stocks = { sid(25906), sid(25905), sid(25902), sid(22445), sid(22887), sid(25899), sid(25898)}

Then the performance is in line with Dave's original one. But I'm not sure why this makes such a big change. Originally, I thought maybe the symbols weren't resolving to the correct ETFs, but that doesn't seem it. Anyone know why this makes such a difference? A set vs. a list? Oddly (because the first two should be identical) all of the below give wildly different results:

context.stocks = symbols('VHT','VGT','VCR','IBB','EDV','VB','VAW')
context.stocks = [ sid(25906), sid(25905), sid(25902), sid(22445), sid(22887), sid(25899), sid(25898) ]
context.stocks = { sid(25906), sid(25905), sid(25902), sid(22445), sid(22887), sid(25899), sid(25898) }

@Alan B. I tell ya what, I'm gonna use dictionaries from now on 'cuz they give much better results!

It looks like the first two in your list are equivalent; the both are "list"s.
That last one though, the dictionary object {} yeah, I like that one much better. It's a "set".
Set, Game, Match!

Apparently the treatment for the "set" and the sids/symbols therein must be selecting something differently than the "symbols()" method returns. That would seem to require some explanation from those in the Q'Know.

[EDIT: Try this list:

context.stocks = symbols('EDV','VB','VAW', 'VHT','VGT','VCR','IBB')  

And you'll find that it matches the "set" version above.
Which means that ORDER now has something to do with the logic in this strategy. It's not all rose smelling in Denmark me thinks.
]

Hello Dave & all,

Skimming over the original algo posted above, I gather that in a nutshell, it is a matter of applying this, and finding the top-ranked ETF:

 Normalize the performance and volatility values to a range  
    # between [0..1] then rank them based on a 70/30 weighting.  
    for s in stocks:  
        p = (performances[s.sid] - minP) / (maxP - minP)  
        v = (volatilities[s.sid] - minV) / (maxV - minV)  
        rank = p * 0.7 + v * 0.3  

If I understand correctly, the performance is simply the overall relative gain/loss over the trailing window:

performance = (end - start) / start  

Correct?

The volatility calculation is more involved, though:

    # Calculate 20-day volatility for the given period  
    v = []  
    x = 0  
    for i in xrange(-period, 0):  
        v.append(historicalVolatility(20, prices[i-21:21+x]))  
        x += 1  
    volatility = sum(v) / period

with historicalVolatility using the log of the day-to-day returns, etc. Is there a justification for this approach? A quick google search provides http://quantivity.wordpress.com/2011/02/21/why-log-returns/, which concludes with some references discussing the use of logarithmic versus linear returns. Also, I've wondered if a proper volatility calculation should somehow incorporate all of the OHLCV values contained within a bar (be it daily or minutely), rather than just the closing price value.

Grant

Dear Quants,

For even better performance, perhaps the use of leveraged ETFs could be considered.
When a 3X small cap fund is substituted for all non-Treasury EFTs, the performance increased to over 600% over the same period.

The obvious drawback is a larger draw down (51%). and high volatility.

Is this progress in the desired direction?

Dave

Clone Algorithm
1498
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: 54afe8a06e663d2ad34dcd77
We have migrated this algorithm to work with a new version of the Quantopian API. The code is different than the original version, but the investment rationale of the algorithm has not changed. We've put everything you need to know here on one page.
There was a runtime error.

@dave macpherson: definitely better one, but it outperforms SPY significantly in the last two years only in the last year.
The problem is when market is steadily going up, a lot of strategies perform well as well.

Also there are many strategies that could have avoided the 2008-2009 downturn and once you stop including 2008-2009 the strategies fall apart. It's not necessarily a bad thing that it performs better in a massive downturn, but it always feels a little bit like data mining.

There's still some unanswered questions about this algo. See Alan Baer's post above.

Take @Dave M. original strat, Swap out only his stocks collection mechanism and retest. Yeah you have to make some minor changes to the iterations within the body of code but this does not change logic in anyway.

You can try a "set" {} or a "list" [] but either should work no? The code just iterates the collection right? Then change the order of the list version... Different results???

This,
context.stocks = [sid(22887),sid(25905),sid(25902),sid(25899),sid(25898),sid(25906),sid(22445)]

gives different results than this: (just rearranged in order)
context.stocks = [sid(25898),sid(25906),sid(22445),sid(22887),sid(25905),sid(25902),sid(25899)]

Which may give different results than (using a set not a list)
context.stocks = {sid(25898),sid(25906),sid(22445),sid(22887),sid(25905),sid(25902),sid(25899)}
(note the use of [] vs {})

Thanks for your question:

Q. You can try a "set" {} or a "list" [] but either should work no?
A. algorithm works with "set" {} only. What is the advantage of switching to the list data structure?

Q. The code just iterates the collection right?
A. Yes. Picks best ETF based on simple performance criteria.

Q.Then change the order of the list version... Different results???
A. Not when using the original code with set notation. Still investigating the "rearranged order" differences. I DON'T THINK the order of the ETFs within the set should matter.

I always express the ETFs using the sid number as follows:

def initialize(context):
context.stocks = {
22887: sid(22887), # EDV VANGUARD treasury
25906: sid(25906), # VHT (Vanguard Health Care ETF)
25905: sid(25905), # VGT (Vanguard Information Technology ETF)
25902: sid(25902), # VCR (Vanguard Consumer Discretionary ETF)
22445: sid(22445), # IBB (iShares Nasdaq Biotechnology Index Fund)
37515: sid(37515), # TNA (Direxion Small Cap Bull 3X Shares (ETF))
25899: sid(25899), # VB = Vanguard small cap
25898: sid(25898) # VAW (Vanguard Materials ETF)
}

================================== experimental results changing ETF order within the set =============== these experiments (using the set {} notation) all produced the same performance results with ETFs listed in different order as expected.
start date: 11/05/2008, end date: 01/06/2015, returns 400.7% running daily using EFTs in this order: VHT, VGT, VCR, IBB, TNA, EDV, VB, VAW
start date: 11/05/2008, end date: 01/06/2015, returns 400.7% running daily using EFTs in this order: VB, VHT, VGT, VCR, IBB, TNA, EDV, VAW
start date: 11/05/2008, end date: 01/06/2015, returns 400.7% running daily using EFTs in this order: EDV, VHT, VGT, VCR, IBB, TNA, VB, VAW
start date: 11/05/2008, end date: 01/06/2015, returns 400.7% running daily using EFTs in this order: VHT, VGT, IBB, TNA, EDV, VB, VAW, VCR

....

Dave M

The reason to use a list "[]" is to use the easier to understand implementation of context.stocks = symbols()

Here's two differently ordered lists of your ETFs that produce different results. Still trying to figure out why.

    context.stocks = symbols("EDV","VGT","VCR","VB","VAW","VHT","IBB") # returns: 287.6%  
    context.stocks = symbols("VAW","VHT","IBB","EDV","VGT","VCR","VB") # returns: 87.1%  

Greetings, first post to Quantopian forums...

This algo caught my eye and I got sucked into figuring out what is going on with the rest of you.

Seems this variable result is somewhat due to the EDV instrument and perhaps the fact that there is no data for EDV until sometime in 2013. If you remove EDV from the list, the performance is consistent regardless of order.

I'm not yet up to speed enough with the platform to figure out how to ignore an instrument in the list that does not have valid data. Found this after putting the following check in around line 53 since GetStockMetrics was returning NaN values:

if math.isnan(p) or math.isnan(v):  
            continue  

Without EDV, the algo is returning 80% for me with 42.9%DD.

Randy,

Thanks -- Very interesting discovery. Nice method provided for detecting NaNs. A more rigorous approach [for trading real money] could test all ETF data for NaN.

The inception date for the EDV ETF is 6 Dec 2007 [ https://institutional.vanguard.com/iippdf/pdfs/FS930R.pdf ] , so perhaps some of the Quantopian data is missing?
We also expected the Quantopian wrapper to adjust / report when EDV's data was not available.

I guess Quantopian is using us to beta test stuff like this???

Dave

Sets and Lists behave differently when it comes to internal order.

Given this code:

def handle_data(context, data):  
    set = {'a','b','c','d'}  
    list = ['a','b','c','d']  
    print('test1')  
    print(set)  
    print(list)

    set = {'c','d','a','b'}  
    list = ['c','d','a','b']  
    print('test2')  
    print(set)  
    print(list)  

You'll get this print result:

2011-01-04 PRINT test1  
2011-01-04 PRINT set(['a', 'c', 'b', 'd'])  
2011-01-04 PRINT ['a', 'b', 'c', 'd']  
2011-01-04 PRINT test2  
2011-01-04 PRINT set(['a', 'c', 'b', 'd'])  
2011-01-04 PRINT ['c', 'd', 'a', 'b']  

The sets do not change their order based on their constructors. The lists do.
This means @Dave M. that your algo for applying performance and volatility during ranking appears to be imperfect. You get the same order of securities no matter what by using a set. But using a list changes the order which should not change the results -- but it does.

The above code block of the refactoring effort has been updated to reflect this issue.

Fails for Minute data; index out of bounds error on 230.

Hey Noah,

There are a couple version of the algorithm posted on this thread, do you mind sharing the one you're working with so we can help debug?

Thanks,
Seong

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.

The main one at the very top.

Hi Noah,

Take a look at the code below, I think a part of the error was coming from the batch_transform use so the algo here has been converted into history()

Clone Algorithm
265
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: 54bbc3ea9f8a69097596c43f
There was a runtime error.

Sorry for digging up an old thread, but I don't understand the concept of this code. It seems to take the best performance per volatility ETF, but what is the theory and math behind it? Can anyone point to a paper or tutorial that could explain this to me?

Thanks

Hi Johnny,
The theory is based on empirical evidence that stocks and ETFs which have performed well in the past, tend to outperform. This is an empirically observed break from the efficient markets hypothesis which assumes stock returns are independently and identically distributed (i.e. today's return can tell you nothing about tomorrow's return). The profitability of this and similar strategies is based on the idea that past returns do contain information about future returns.
There has been much written about this in the literature. Feel fee to browse some of the articles on Google Scholar:
https://scholar.google.com/scholar?as_vis=1&q=finance+momentum&hl=en&as_sdt=1,9

Thanks for your reply, Reed.
There is something other than momentum at play here because momentum is simple to calculate while Dave's code is rather complex. My simple momentum algo fares a lot worse than Dave's code. There is something else at play here other than comparing x month return.

I don't understand the code so it has an almost magical quality to it. I was hoping that the technique (or magic!) was sufficiently robust to apply to other rotation strategies such as asset rotation.

It's quite impressive until about 2009...

Clone Algorithm
24
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: 55873b9381ed011261a2fefe
There was a runtime error.

The order magic likely comes from the rank being equal. Then the first listed ETF is picked.

@ maket tech how were you able... to quantify ... those results context.stocks = symbols("EDV","VGT","VCR","VB","VAW","VHT","IBB") # returns: 287.6% context.stocks = symbols("VAW","VHT","IBB","EDV","VGT","VCR","VB") # returns: 87.1% can you show us the code... we will check on how it is computed...

Hi,
Is there a reason why this algorithm works on equity sectors, but not all 13 of them like for example the standard morningstar sector classification?
I mean, is there some logic behind?
Plus, In the original list of stocks IBB and EDV have not enough data, you can tell buy adding a check like:

backtest_start = '2006-1-1'  
context.no_data = [sec for sec in context.stocks.itervalues() if sec.start_date.replace(tzinfo=None) > context.backtest_start]  
if len(context.no_data) > 0:  
    context.enough_history= False  

By the way, unfortunately adding all sectors cause the equity line to be very poor

Backtest in minute mode of the same algo utilizing the history function to accumulate data is for now 29% in drowdown.

Clone Algorithm
25
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: 56a54101f102f11191c0a7d8
There was a runtime error.

Over 850% at one point. How on earth to address DD. Quite a few changes here ...

Clone Algorithm
76
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: 56a61b4b76139510fa38b665
There was a runtime error.

Only change to previous test here about Backtest for last 2 years. The results below Show the difficulty of picking of a " ETF universe" to trade and how returns changes over a different market behavior(what type of news is driving the market now VS 5 years ago). eg- 2015 Jan down market is now clear retrospective , however difficult to read the market message with a live systematic traded strategy or in hindsight
1,Although we are doing systematic trading.. its constant tuning effort by using a lot common sense read the market.
2, picking a 'universe of instrument' to trade changes for the same strategy over different market will be very different (essentially the news drives the market and our algo/instrument should reflect the view )
3, Never trade live with real money until you perform your due diligence and have some money to loose.
4, Never think you or your algo are the smartest thing created by us (academic or Geek or .. ) ; the random nature of the market will humble you (it at the end , same as going playing in a casino, at the end of day )

play safe , smart and self-aware even if we are the smartest dudes on the planet !
cheers

Clone Algorithm
24
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: 57364ab17cb95311d69b54ca
There was a runtime error.