MOMENTUM Trading Strategy on the NASDAQ with Python using multiple lookbacks [MUST WATCH]

แชร์
ฝัง
  • เผยแพร่เมื่อ 12 มิ.ย. 2024
  • THANK YOU FEDERICO! In this video I am building a strategy suggested by a subscriber. The strategy tested on Nasdaq stocks is a multi look back window Momentum Trading strategy which is forming an equal weighted portfolio based on the 12 month/6 months and 3 months top performer returns. Interesting results in the first place!
    Get the Notebook/Source code by becoming a Tier-3 Channel member:
    / @algovibes
    Interested in exploring this strategy, getting fully rid of survivorship bias or apply that on other assets? Like, share, subscribe. Helps me a lot. Thank you :-)
    This video is recommended to check out beforehand:
    • Momentum Trading Strat...
    Survivorship bias is also covered in that video!
    Return calculation clearly explained here:
    • How To Calculate Stock...
    Python for Finance playlist (Momentum and other Trading strategies recommended ):
    • Python for Finance
    Interested in automated trading? Check out the Cryptobot playlist here:
    • Cryptocurrency Bots / ...
    wiki link:
    en.wikipedia.org/wiki/Nasdaq-100
    Disclaimer: This video is not an investment advice and is for informational and educational purposes only.
    00:00 - 01:42 Background / Strategy
    01:42 - 03:31 Stock tickers & Prices
    03:31 - 05:15 Excluding some stocks (listen to what I mention)
    05:15 - 07:05 Monthly return
    07:05 - 08:24 Recap on returns
    08:24 - 11:40 12/6/3 month returns
    11:40 - 15:47 Top performers
    15:47 - 19:42 Portfolio performance (1m holding)
    19:42 - 23:34 Backtest
    23:34 - 25:34 Benchmark comparison / final remarks
    #python #trading #strategy

ความคิดเห็น • 162

  • @lio_k
    @lio_k ปีที่แล้ว +66

    I've been successfully running a very similar model for the past 7 years .
    To improve the robustness of the list of stocks, a good filter to add would be to include only those stocks that not only have the best momentum, but also have greater momentum compared to the NASDAQ index. This will ensure that the stocks on the list not only have strong overall momentum, but also have momentum that is stronger than the broader market.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Cool! Thanks a lot for sharing man.

    • @keahananthonyturnbull6773
      @keahananthonyturnbull6773 ปีที่แล้ว +10

      What is your return?

    • @pw12
      @pw12 ปีที่แล้ว

      .

    • @victorh.rampazzo6466
      @victorh.rampazzo6466 ปีที่แล้ว +2

      i dint understand. how could a stock have the best momentum and at the same time have a lower momentum than the index?

    • @Elvis00026
      @Elvis00026 ปีที่แล้ว +1

      Check that the momentum is greater than 0 could be a good addition to stop drawdowns.

  • @simondechoisy779
    @simondechoisy779 24 วันที่ผ่านมา +2

    Definitely be interested in seeing this without any survivorship bias

    • @Algovibes
      @Algovibes  22 วันที่ผ่านมา

      Already did it! Be invited to check it out :-)

  • @andycare
    @andycare ปีที่แล้ว +23

    Great video, as always. A few points which I noticed after testing this system:
    - starting the backtest at 2005 hides a huge drawdon between 2000 and 2005 of > 60 %
    - The survivorship bias has huge impact on this system (as often for momentum systems): the CAGR decreases from 28 % to 15 % and the maxDD increases from 46 % to 65 % (tested from 2000 to today)
    - a simple regime filter helps a lot lowering the drawdowns
    - the system performs a little bit better on the S&P 500 universe with 250 stocks -> 100 stocks -> 10 stocks (not optimized)

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Good comment. Thanks a lot Andy!

    • @richardkasden
      @richardkasden ปีที่แล้ว

      What kind of regime filter do you use?
      And a more detailed question: as an example if you're using a 200sma, are you setting the filter based on the (in this case) Nasdaq 100 200sma and not trading when the overall market trend is down or the 200sma for each individual stock and picking the final 10 based on each being above it's indiviual 200sma?

    • @npomfret
      @npomfret ปีที่แล้ว

      I set the start date to 2000-01-01. Performance was pretty flat (just looking at the plot), but I don't see a huge drawdown? Perhaps it's too small to see when compared with more recent returns? I can see a 32% drawdown at 2009-01-31, but not one greater than 60%. Can you provide details?

  • @82fedlom
    @82fedlom ปีที่แล้ว +7

    Great work, thanks for your video AlgoVibes, I'm waiting for the fully SVS-bias free version, and, if possible, with the eur/usd conversion (selectable as a choice). Regarding the drawdown problem, I recommend the book in which Andreas Cleanow presents his approach :"Stocks on the move". Here the momentum strategy presented (on SP500) is a bit more complex. But a simple SMA 200 filter on the benchmark is sufficient to halve the DD, with a very limited reduction in the CAGR.

  • @zAngus
    @zAngus ปีที่แล้ว +21

    Yes would like to see how it changes without survivorship bias.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Thanks a lot for your feedback! Will see what I can do.

  • @rraul
    @rraul ปีที่แล้ว +1

    Hi! My favourite videos style, old factors tested! Glad to see this return to the spots. Thanks

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Hi 🙋🏻 Awesome. Love to make these videos as well. Thanks for watching rraul.

  • @cmrncrick
    @cmrncrick ปีที่แล้ว +2

    Wow man! Good stuff! Thank you!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks buddy :-)

  • @PavelSumik
    @PavelSumik ปีที่แล้ว +1

    I always look forward to your videos, thanks

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks for your support Pavel! Really appreciate it.

  • @ricardomarchao5435
    @ricardomarchao5435 ปีที่แล้ว +1

    well done ! great job! for the benchmarks and performance a lot of the time that is expressed with the sharpe ratio as you can later leverage the strategy as you wish

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks a ton Ricardo. Yep! Check out the newest video. I am talking about Sharpe ratio there. Sharpe ratio is usually the optimizing objective.

  • @jitkadyan
    @jitkadyan ปีที่แล้ว +1

    Another superb video, with lots of information and knowledge shared along with python coding learning. Thanks dear 🙏🙏

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks for watching mate!

  • @lokeshsaluja3305
    @lokeshsaluja3305 ปีที่แล้ว +1

    Hey @AlgoVibes, loved the video. What a beautifully written and well explained code. Just one question. What date would you pass each month in the last Get_Top(Date) function to get names of 10stocks to invest in? Would it be starting range of the data or the current date where you want recommendations per the model? I couldn’t understand that part of the logic. TIA

  • @drwho8576
    @drwho8576 ปีที่แล้ว +3

    Excellent video as always. I made some mods using the Russel 1000, and instead of equal weights, I run PypfOpt Efficient Frontier and Discrete Allocation in every selection, optimizing for Sharpe ratio and using exponentially weighted covariance matrix. For 2022 alone, cumprod goes from 1.10 to 1.28 doing that. Even more interesting, I ran it weekly (26, 13 and 6 weeks), which gives me a cumprod of 1.30 with mean, and 1.57 with discrete allocation. I'll keep experimenting. Thanks for the great quality work you put out!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thank you very mate for both the appreciative words and also sharing your strategy!

  • @MONIQUE_MUSIC
    @MONIQUE_MUSIC ปีที่แล้ว +1

    I really like your videos. Thank you so much. They help me

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thank you very much Monique!

  • @davidcooper3871
    @davidcooper3871 ปีที่แล้ว +3

    I did this in an Excel spreadsheet starting in 1993. It was based on a mutual fund portfolio in my 401(k) account. I had excellent returns during those years. The strategy was to move money toward funds that were increasing in momentum, While pulling money out of funds that were decreasing in momentum. If most funds were decreasing, the strategy was to park the money into stable value fundS. Of course the brokerage rules changed as time went on, which meant mandatory longer wait periods of time between trades. Evolved Very much like your monthly analysis period example. My original strategy, was one month 15 days five days.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Cool man, thanks a ton for sharing. How did it work out? 😄

    • @davidcooper3871
      @davidcooper3871 ปีที่แล้ว +1

      @@Algovibes I retired at 59.

  • @tomalapapa100
    @tomalapapa100 ปีที่แล้ว +1

    Great video. I would love to see the next step in optimization. Keep it up!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks mate. Well that would be actually quite an interesting idea. Kind of find the optimal lookback/holding period out of the cascade. Thanks for your input!

  • @flatironsdigital
    @flatironsdigital ปีที่แล้ว +1

    Thanks for the video! I found it interesting that if you held an equal weight portfolio from the inception of the strategy you outperform the cap weighted index by a factor of 2x `(df.dropna(axis=1).sum(axis=1).pct_change() + 1).cumprod().plot()` . Am I thinking about this properly?

  • @rajeevmenon1975
    @rajeevmenon1975 ปีที่แล้ว +1

    Awesome buddy. The wait was worth.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      thanks mate :-)

  • @rame2rame
    @rame2rame ปีที่แล้ว

    Thank you for this !
    Can you tell me how can I apply the risk managed momentum formula from the paper Momentum has its moments (Barroso, Santa-Clara) to this ?
    Moreover, for comparison purposes I would like to combine the cross sectional and time series momentum to see which one performs better… do you have any idea ?
    Thanks in advance

  • @victorbartolo287
    @victorbartolo287 ปีที่แล้ว +6

    thanks for a great presentation. Kindly consider adding code to mitigate the survivorship bias issue. Also adding limiting drawdown % as suggested in the comments below, myself i was using a 200SMA filter. I am currently working on a momentum strategy but had difficulty in determining what time windows to use so this video was invaluable to me. Thanks to Federico as well.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Welcome mate! Happy you could extract value out of the video.

  • @martintrapp1992
    @martintrapp1992 ปีที่แล้ว +2

    This example clearly shows how fees killing the most strategy at 22:22. Even with just 1 percent of fee, it went from 20x to 5x… ehh. I liked the content though, great video!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hi mate, thanks a lot for watching!
      Agreed on the one hand, on the other hand 1% is way too much. I took a way to conservative approach here, that's why it is crushing the PnL to that extent.

  • @tonymascali
    @tonymascali ปีที่แล้ว

    Hi Dale, love your coding style and share your passion for algo trading but in the end the algos which incorporate chart pattern recognition will rule the future.

  • @TheIvanlisi
    @TheIvanlisi ปีที่แล้ว +1

    I liked your code very much! So clean.
    The performance of the strategy is almost the same as the index.
    Strategy performance - Market performance < Headache of maintaining a trading bot

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks mate. Yeah but you have to consider that I filtered out the astronomic performers like Air BNB and TSLA to diminish the survivorship bias. That will ofc make the performance way worse then it actually would have been.

  • @112358henry
    @112358henry ปีที่แล้ว +2

    Great stuff, small suggestion here - would be great to plot 2 equity curves on one graph, also showing the return% on y and date on x.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks buddy. Nice suggestion!

  • @Lindsey_Lee
    @Lindsey_Lee ปีที่แล้ว +1

    Excellent video. Very comprehensive. Appreciate your patience in the presentation. A few comments:
    1. I am using Jupyter Notebook. I was unable to use pd.read_html to access the list of the 100 NASDAQ stocks. Ending up copying the table to an Excel spreadsheet, save in .csv format then load the data using pd.read_csv.
    2. Interesting to see what the result of a momentum based long-short strategy.
    3. Instead of comparing strategy results to IXIC, I suggest comparing results to an equal weighted portfolio of the surviving stocks.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hi buddy, very good points. Thanks a lot for sharing!

  • @asssets
    @asssets ปีที่แล้ว

    Thank you for the video and detailed explanation of the process. I repeated the code and have a few observations to share.
    1. The list of companies used in the test changes a few times a year. NASDAQ - 100 changes annually in December. When we use list from a wiki page combined with long term backtesting we don't compare apples to apples. Using Tesla as an example, data is missing on 2010-01-01 as it IPO 6 months later in June 2010 but was only part of the NASDAQ - 100 in 2013. # You probably mentioned this as you said it is not entirely free of survivorship bias.
    2. Why did you compare portfolio returns to IXIC instead of NDX or QQQ?

  • @ytuser7967
    @ytuser7967 ปีที่แล้ว +5

    Thank you. Yes, without survivorship bias would be great.

    • @ytuser7967
      @ytuser7967 ปีที่แล้ว +2

      @@rame2rame Testing strategies with survivorship bias delivers unrealistic results, because we only test on securities that have survived.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      @@ytuser7967 thanks for your feedback mate

    • @ytuser7967
      @ytuser7967 ปีที่แล้ว +1

      @@Algovibes Your are very welcome.

  • @teacher2414
    @teacher2414 ปีที่แล้ว +1

    the full survivorship bias video would be great!!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks for your feedback mate!

  • @mumbai59
    @mumbai59 ปีที่แล้ว

    I was wondering if you can create a video on dual-momentum strategy as per Gary Antonacci's book.

  • @mikul_
    @mikul_ ปีที่แล้ว +2

    If there is anything that is missing on the internet, it's a real strategy that uses the ichimoku cloud in the right way! I tried to get chat gpt to make it but it had no idea how to create it.
    The real icumoku cloud has 2 different ways to give you a signal.
    First one is : Price above the cloud, lagging span above the price, and conversion line crossing the baseline above the cloud, then a green portion of the cloud 26 periods in front of the price.. That is a trend continuation signal.
    Then you have the pump signal:
    Price above the cloud, green portion of the cloud 26 period in front, cross below or inside the cloud, lagging span above the cloud

    • @mikul_
      @mikul_ ปีที่แล้ว +1

      I have made half of that in pine script if you want to have a look at it, but it's not that good... I'm quite shitty as a programmer. But i have some ideas. 😉

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hey Mikul, really appreciate your comment. Sorry for my late reply. I noted that for potential future content.

  • @jitkadyan
    @jitkadyan ปีที่แล้ว +1

    Great Video again , Sir Waiting for your New Video

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks my man! New video is in production.

  • @JonnyQuest0077
    @JonnyQuest0077 ปีที่แล้ว +1

    Great video presentation! Enjoyed both the strategy and the Python implementation. Would you consider doing a follow on video where you vary the holding period of the top 10 stocks? Say for 3 months or 6 months before you refresh with a new set of stocks? Just curious whether backtesting such a strategy would improve the performance. Also interested to see how this could be implemented in Python. Thanks! (Enjoyed subscribing to your channel and learning from the other topics you've covered with Python!)

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks a lot Jonny! Cool idea also.

  • @KontrolledSubstance
    @KontrolledSubstance ปีที่แล้ว +1

    Hello...this video was awesome! I have no experience with coding at all but i assume this could be done with commodities and futures correct?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks mate! You can surely backtest momentum on commodities. The index component side (pick best of index) of this strategy I see quite difficult to mirror with commodities.

  • @Ryanwong.6688
    @Ryanwong.6688 ปีที่แล้ว

    which version of your python is ? i've tried to type and install yfinance in python 3.11, but it failed to comply and kept telling me there is syntax error.

  • @urban2327
    @urban2327 ปีที่แล้ว +6

    Nice strategy and presentation! As an easy approach to consider the survivorship bias, could it be that you may just replace NaN with 1.0 (like holding cash). This would also mean that in bad months where lots of shares have returns < 1, you start holding cash and only hold shares with return > 1.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks mate. The problem with my approach is, that I fully exclude them from my analysis as I do not know when the came into the index. There is some point in time when they climbed in the index and from this point in time on I have to consider them as well.

    • @BigMiner3000
      @BigMiner3000 ปีที่แล้ว +3

      @@Algovibes So? Just replace NaN with 1.

  • @newdata
    @newdata ปีที่แล้ว +1

    maybe do the program on bigger unverse of stocks out of the index would minimimse survivalship bias

  • @jonathanstanford1603
    @jonathanstanford1603 ปีที่แล้ว

    I don't seem to manage to upload the libraries such as pandas or finance in Jupiter Notebook. I have to use PyCharm that works. How do you get these libraries t work in Jupiter? I've tried launching Notebook via Anaconda, but I have the same issue... thx

  • @itayhilel2168
    @itayhilel2168 ปีที่แล้ว +1

    Great video

  • @arunkamath
    @arunkamath ปีที่แล้ว +1

    Great video. I was wondering does the strategy assumes we are holding the stock or when do we exit?

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Thanks mate! Was taking a holding period of 1 month here.

  • @khalilkafrouni
    @khalilkafrouni ปีที่แล้ว +3

    In order to remove the survivorship bias, where would you get a dataset of the constituents of NASDAQ over time? It would be great if you could make a video about that. Great work, super helpful!

    • @chriscappel9536
      @chriscappel9536 ปีที่แล้ว +2

      This data is not free unless you create it yourself. Norgate is a data provider that can provide this to you.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Yep! Chris is 100% right (unfortunately). When doing academic research you are usually working with the CRSP database which is not available for free. My idea was to take a table showing the changes in the last years and merge that table with the strategy. Table doesn't go back too much into the past but this is at least taking out the survivorship bias for the last decade.

  • @FastbreaKHere
    @FastbreaKHere ปีที่แล้ว +2

    Hi have you ever thought about trying a strategy that takes volatility into account? Adapting position sizing or being/not being in a position based on how much volatility is on that particular asset? Also similar considerations can be made on volumes.... a video on that would be great! have a good day!

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Hey Luigi,
      yes there are actually older videos on my channel that but in my newest video I am using the Sharpe ratio as my optimization objective. Stay tuned! :-)

    • @jerryware1970
      @jerryware1970 ปีที่แล้ว

      Normalize position sizing accounting for volatility. And scale out if the trade goes against you, ie: sell a third of the position if lose x% or monthly low

  • @kennethszulczyk6681
    @kennethszulczyk6681 ปีที่แล้ว +1

    It is really cool. Python makes the coding simple.

  • @psymadra
    @psymadra ปีที่แล้ว +3

    Hi Algovibes,
    i would be glad about an implementation of an regime filter e.g. QQQ has to be over 200 SMA or 3 Month-Perf of QQQ has to be over 0 %. About this Video: For me (a real beginner) was it much easier to follow this video than with the last momentum update video with the S&P500. Without to understand everything, this time the programming seems like more straight forward (man brech ich mir auf englisch einen ab ;)
    Thank you

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks for your feedback!
      Und außerdem Danke für deine sprachlichen Bemühungen! :-)

  • @esseindividuo
    @esseindividuo ปีที่แล้ว +1

    06:43 i had to add df.index = pd.to_datetime(df.index) in the line before mtl = (df.pct_change() +1)[1:].resample('M').prod() otherwise resample didn't work

  • @sazamhashmi
    @sazamhashmi ปีที่แล้ว +1

    Keep us amazed buddy, and thank you so much for these ideas. I have a strategy which i would want to test it. How is it possible to reach you?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks mate :-) Sure, just drop me a mail (can be find in about me) and I'll see what I can do!

  • @lorenzobaggi161
    @lorenzobaggi161 ปีที่แล้ว +2

    You are an angel fallen from the heaven. Thank you

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Same is true for you leaving a comment like that :-) Thanks for your support man.

  • @teacher2414
    @teacher2414 ปีที่แล้ว +1

    survivorship bias full excluder would be great!!

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks for your feedback!

  • @prajwaltuladhar6742
    @prajwaltuladhar6742 ปีที่แล้ว +4

    Hi Algovibe. Can you also test low volatility strategy on NASDAQ (or any stock universe)? Curious to see the strategy results

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Interesting suggestion! Anything specific you have in mind?

    • @prajwaltuladhar6742
      @prajwaltuladhar6742 ปีที่แล้ว +2

      @@Algovibes test for low volatility anomaly based on past 36 months returns standard deviation (or beta), and rebalance on monthly or quarterly basis. I tested for S&P 500 and getting opposite results from what academic research suggests. So want to see how others are implementing the strategy 🙏

  • @OliverFoote
    @OliverFoote ปีที่แล้ว +1

    Super cool content

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Happy to read. Thanks a lot :-)

  • @mistycsoul
    @mistycsoul ปีที่แล้ว +1

    You make great videos.Could you make a video with a strategy on renko chart!?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks a ton for your suggestion and your comment mate :-)

  • @bryan-9742
    @bryan-9742 ปีที่แล้ว +1

    I was going to ask you why you don't subtract one from MTL but it looks like you want to maintain (1+r) so that when you apply the rolling function we can, for example take the last n=window=12 months within the get_rolling_ret(df,n) function. feeding to the function seems to provide you (1+r)_1 * (1+r)_2 * ...(1+r)_12 correct?
    Also, ret_12, ret_6, and ret_3 could have been calculated in a triple loop but this way is much more efficient correct?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hi Bryan, Yep! You got it 100% right. Nothing to add :-)

    • @bryan-9742
      @bryan-9742 ปีที่แล้ว

      @@Algovibes I did the portfolio sort with GICS industries AND the same idea. I may turn this into a class but I'm going to add a conditional via volatiility and observe results. I also think trying to combine momentum with a short-term reversal would be interesting. FYI The optimization you're about to do is going to interesting to see from a looping perspective. If you only use the quadratic and linear constraint (return and variance with no other constratins) it's not going to make any sense. You may want to add a max trade size condition.

  • @terminatorhere
    @terminatorhere ปีที่แล้ว +1

    Hi Algovibes, great video as usual but it still has survivorship bias as some of the companies might not be in Nasdaq 100 10 years back, they might have replaced some companies and made it in to list. Another point when I start it from 2000, I might again remove some of the great companies of that time.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Thanks mate. Yes, that's right. If you watch the video again I stated that in the video 😁

  • @LegionXVX
    @LegionXVX ปีที่แล้ว +1

    Is the strategy idea only to look at the last year of data? For instance if I wanted to pick 10 stocks for my portfolio for this month, should I only include 2022 data or does this historical going back to 2010 (or beyond) matter for accuracy?

    • @PatzyBeats
      @PatzyBeats ปีที่แล้ว +1

      this is a momentum strategy. It looks at 3 time frames 12 month, 6 month, and 3 month. And chooses 10 stocks to buy and hold for a month. Its back tested on data going back to 2010 which gives you those returns.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks @PatzyBeats that's right!

  • @aribolab
    @aribolab ปีที่แล้ว +1

    Thanks for this.
    Could anyone help me to understand why removing the stocks that were not on NASDAQ from the chosen data would help to overcome survivorship bias?

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Welcome man! I just released a new video explaining and coding survivorship bias. That should answer your question hopefully. If not - pls let me know.

    • @aribolab
      @aribolab ปีที่แล้ว +1

      @@Algovibes great! Thanks! Will watch and if I have questions I’ll post them as comments.

  • @denniscarver9147
    @denniscarver9147 ปีที่แล้ว +1

    im sort of stuck on something. I was testing this out with a different set of stocks. The portoflio returns im getting, at the end, are all the same. The return is the same on every day.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Hey Dennis,
      If you elaborate a bit more on your problem I could help you. Or just post the problem in the Discord. People may solve it for you!

  • @juuttuub
    @juuttuub ปีที่แล้ว +2

    Great video! I am trying to replicate, but I get performance value for first months also, not NaN as it should. At what point do you make the check for if there are returns for 12, 6, 3 months?
    With .index you get stock names and from mtl I get " Date
    2010-02-28 1.040044" for the 10 stocks from index. I shouldn't get that while 12,6 and 3 months don't have any returns.
    I have it like this:
    def pf_performance(date):
    portfolio = mtl.loc[date:, get_top(date)][1:2]
    return portfolio.mean(axis=1).values[0]
    returns = []
    for date in mtl.index[:-1]:
    returns.append(pf_performance(date))

  • @bendanziger3682
    @bendanziger3682 ปีที่แล้ว +1

    Shouldn't you be working with log returns? backtest not accurately reflecting performance with percentage changes, right?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Quiet straightforward answer: No.
      When and why you should use log returns is explained here:
      th-cam.com/video/fWHQwqT3lNY/w-d-xo.html

  • @claytonslade2366
    @claytonslade2366 ปีที่แล้ว +1

    TSLA probably causing major skew. Would be interesting to run excluding TSLA outlier.
    Edit: Oh I see you address this at the end

    • @claytonslade2366
      @claytonslade2366 ปีที่แล้ว +2

      On the other hand, this strategy would certainly seem likely to ride a stock like TSLA. Just saying, I wouldn't count another outlier like that. Would be interesting to see how this strategy performs with the S&P500 before TSLA was added to it.

  • @tarochat7600
    @tarochat7600 ปีที่แล้ว +1

    Will this strategy perform in the S&P 500 or Nikkei 225?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Good question. Has to be tested. You have everything what you need to test it so go for it 😛

  • @leonardobruni6887
    @leonardobruni6887 ปีที่แล้ว +1

    What Python Framework are you using, it seems Google Collaborate, but looks faster!

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Just Jupyter Notebook :-) Thanks for watching mate

  • @alfonsomunoz5456
    @alfonsomunoz5456 ปีที่แล้ว

    Great video, but it is not taking in consideration that in many countries for each winning position that is closed you have to give a cut to the government as taxes

  • @a1b290
    @a1b290 ปีที่แล้ว +1

    Nice lecture! Are you able to post the python code? Thanks.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Even better: You can become a channel member, support the channel with that and get access to the code and discord :-)
      Be invited to join here:
      th-cam.com/channels/87aeHqMrlR6ED0w2SVi5nw.htmljoin

  • @khtan5531
    @khtan5531 ปีที่แล้ว +1

    Hi algovibes, there is a github by a gentleman Teddy Koker that discusses how to construct a sp500 dataset free of survivorship bias, using free data sources. Perhaps you can cover this in your next video ?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hi buddy, thanks a lot for the suggestion. Anyhow if you check out his note:
      "EDIT 2020: iShares no longer publishes historical holdings to their website (perhaps because of this abuse). Constituents until mid-2019 are available in constituents.csv"

    • @khtan5531
      @khtan5531 ปีที่แล้ว

      @@Algovibes hi, i suppose it is still possible to update the 2019 - 2022 constituents by hand since the sp500 Wikipedia would have captured the changes.
      Even with a dataset dating to 2019 , it would be helpful if you can do a video to guide us on backtesting a momentum strategy on a dataset free of survivorship bias.

  • @rajeshmanjrekar3614
    @rajeshmanjrekar3614 ปีที่แล้ว +1

    very good video, but the dates part at the end is a bit confusing

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Thanks buddy, agreed but in the end I am just setting an index for the series. Nothing complicated. But I was making it way more complicated then it actually is.

  • @vikram8520
    @vikram8520 ปีที่แล้ว +1

    Why did you add 1 with pct change ?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Hi, for everything related to return calculation please watch this video:
      th-cam.com/video/fWHQwqT3lNY/w-d-xo.html
      Let me know if there is anything unclear left!

  • @abdelmalikberrada2375
    @abdelmalikberrada2375 3 หลายเดือนก่อน

    Is it safe to combine stocks from multiple indexes ?

    • @Algovibes
      @Algovibes  3 หลายเดือนก่อน

      Can you elaborate? thx!

    • @abdelmalikberrada2375
      @abdelmalikberrada2375 3 หลายเดือนก่อน

      @@Algovibes Is it safe to mix stocks from several indexes and build a lookback portfolio from all these mixed stocks?

  • @ericschaack1028
    @ericschaack1028 ปีที่แล้ว +1

    Please show the version without Surivorship Bias

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Sure! Thanks for your feedback :-)

  • @stanislav6668
    @stanislav6668 ปีที่แล้ว

    Whats the practical use of that so-called strategy? To check how much could you earn if invested in those stocks 12 years ago? Very informative as a coding example but useless as a trading strategy)

  • @shawnm8232
    @shawnm8232 ปีที่แล้ว +1

    Which python IDE is he using ?

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Using Jupyter Notebook here.

  • @jerryware1970
    @jerryware1970 ปีที่แล้ว +1

    If a security reaches monthly new highs buy a little. Then if it reaches three month new highs buy a little more.

  • @TheSimpleRobots
    @TheSimpleRobots ปีที่แล้ว +1

    Hi. How I can contact you? we need an educational lesson

    • @Algovibes
      @Algovibes  ปีที่แล้ว +1

      Hi! I am currently quite swamped but you are invited to drop me a mail. You will find this in the About section on my channel.

    • @TheSimpleRobots
      @TheSimpleRobots ปีที่แล้ว

      @@Algovibes I wrote you on 27 november

  • @tosunabi1664
    @tosunabi1664 ปีที่แล้ว +2

    I'm blown by the Python. What you can do with lots of coding is being done in few lines. Must learn for quick analysis.

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Yes it's awesome. Thanks for your comment my man :-)

  • @newdata
    @newdata ปีที่แล้ว +1

    pip install pandas==1.3.0.................for those who cannot run resample for bugs in other pandas

  • @LowQuant
    @LowQuant ปีที่แล้ว

    The strategy guy’s goal was clearly not met. Excluding NAs has no effect at all and the backtest has 100% survivorship and look-ahead bias in it.

    • @Algovibes
      @Algovibes  ปีที่แล้ว +4

      Hi Johannes, you need to grab a coffee ☕️, sit back and watch the whole video again.
      I clearly stated in the video I left out the survivorship bias part as well as clearly communicated the impact of dropping the NaNs.
      Don't worry about the strategy guy. Federico already thanked me and was 100% satisfied.
      By the way: Leave a like and share the video for the survivorship bias part!

  • @charleslynch340
    @charleslynch340 ปีที่แล้ว +1

    Do people actually use this? Wow, makes my programs looks somewhat sophisticated lol

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      I personally don't use it but consider momentum. I am always open for new strategies. Send me yours per mail and I am happy to challenge it 😁

  • @thinkrapido8997
    @thinkrapido8997 ปีที่แล้ว

    You fools who praise this video. First, it has a wrong calculation and, secondly, it doesn't take a decreasing nasdaq into account like it has been in 2009. The calculation starts at 2010. But anyhow, if you overcome these issues the video is helpful. If you get the calculation right you get about -12% in the last year. If you improve more then you can get +12% out of each year with 0.01 substracted from profits.

    • @KeenanTan
      @KeenanTan ปีที่แล้ว

      boo

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      I strongly disagree on this comment just for the record.
      Nobody is a fool for praising high quality content from an actual expert in the field.
      Calculations are correct and lookback is more than enough. Survivorship bias is an issue, which has been covered here:
      th-cam.com/video/OHYExP6RVFU/w-d-xo.html

  • @thanosxypolytos4093
    @thanosxypolytos4093 ปีที่แล้ว

    Mate please write a script before you do a video this is so painful to hear

    • @Algovibes
      @Algovibes  ปีที่แล้ว

      Sorry to hear but I won't write a script. I played around with scripting but people clearly prefer it freestyle as it seems. Besides that I don't have time for setting up a script - it simply isn't worth it.
      Thanks for your understanding!

  • @CriticalTrading
    @CriticalTrading ปีที่แล้ว

    #1 mistake when testing on historical stock data - survivor ship bias, which would drastically affect the performance of a strategy like this; the real-world performance would be around 30% worse than presented in this video

    • @Algovibes
      @Algovibes  ปีที่แล้ว +2

      Hi buddy, did you watch the video? I clearly stated that multiple times.

  • @user-by5if9io9i
    @user-by5if9io9i 10 หลายเดือนก่อน

    I tried to step by step but I got vaild error.I need some help ! Would you mind solve the problem? What's wrong? Thank you so much.
    File ~\anaconda3\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
    exec(code, globals, locals)
    File c:\users\py
    asdaq momentum.py:50
    portfolio = mtl.loc['2010-12-31':,get_top][1:2]
    File ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexing.py:1094 in __getitem__
    key = tuple(com.apply_if_callable(x, self.obj) for x in key)
    File ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexing.py:1094 in
    key = tuple(com.apply_if_callable(x, self.obj) for x in key)
    File ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\common.py:379 in apply_if_callable
    return maybe_callable(obj, **kwargs)
    File c:\users\py
    asdaq momentum.py:41 in get_top
    top_50 = ret_12.loc[date].nlargest(50).index
    File ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexing.py:1103 in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
    File ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexing.py:1330 in _getitem_axis
    raise ValueError("Cannot index with multidimensional key")
    ValueError: Cannot index with multidimensional key
    import yfinance as yf
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    ticker_df = pd.read_html("en.wikipedia.org/wiki/Nasdaq-100")[4]
    tickers = ticker_df.Ticker.to_list()
    df = yf.download(tickers,start='2010-01-01')['Adj Close']
    print(df)
    df = df.dropna(axis=1)
    mtl = (df.pct_change() +1)[1:].resample('M').prod()
    print(mtl)
    def get_rolling_ret(df,n):
    return df.rolling(n).apply(np.prod)
    ret_12, ret_6, ret_3 = get_rolling_ret(mtl,12),get_rolling_ret(mtl,6) ,get_rolling_ret(mtl,3)
    print(ret_12)
    print(ret_6)
    print(ret_3)
    top_50 = ret_12.loc['2010-12-31'].nlargest(50).index
    top_30 = ret_6.loc['2010-12-31', top_50].nlargest(30).index
    top_10 = ret_3.loc['2010-12-31', top_30].nlargest(10).index
    print(top_50)
    print(top_30)
    print(top_10)
    def get_top(date):
    top_50 = ret_12.loc[date].nlargest(50).index
    top_30 = ret_6.loc[date, top_50].nlargest(30).index
    top_10 = ret_3.loc[date, top_30].nlargest(10).index
    return top_10
    get_top('2010-12-31')
    mtl.loc['2010-12-31':][1:2]
    portfolio = mtl.loc['2010-12-31':,get_top][1:2]
    portfolio.mean(axis=1).values[0]
    def pf_performance(date):
    portfolio = mtl.loc[date:, get_top(date)][1:2]
    return portfolio.mean(axis=1).values[0]
    pf_performance('2010-12-31')
    mtl.index[:-1]
    print(mtl)
    returns = []
    for date in mtl.index[:-1]:
    returns.append(pf_performance(date))
    mtl.index[1:]
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod().plot()
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod()
    nas_df = yf.download('IXIC', '2010-01-01')
    print(nas_df)
    (nas_df['Adj Close'].pct_change() +1).cumprod()
    (nas_df['Adj Close'].pct_change() +1).cumprod().plot()
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod().plot()
    portfolio = mtl.loc['2010-12-31':,get_top][1:2]
    portfolio.mean(axis=1).values[0]
    def pf_performance(date):
    portfolio = mtl.loc[date:, get_top(date)][1:2]
    return portfolio.mean(axis=1)
    pf_performance('2010-12-31')
    mtl.index[:-1]
    print(mtl)
    returns = []
    for date in mtl.index[:-1]:
    returns.append(pf_performance(date))
    mtl.index[1:]
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod().plot()
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod()
    nas_df = yf.download('IXIC', '2010-01-01')
    print(nas_df)
    (nas_df['Adj Close'].pct_change() +1).cumprod()
    (nas_df['Adj Close'].pct_change() +1).cumprod().plot()
    pd.Series([i-0.01 for i in returns],index=mtl.index[1:]).cumprod().plot()