[00:00] When the time comes to buy, you won't want to. This is a quote by Walter Deamer, who is known for studying various market timing indicators. He even has a website at WalterDeamer.com where he publishes some articles and a book by the same title. [00:15] He studies a lot of these different breath thrust indicators. So he's often talking about things like these wide breath thrusts, the whaling breath thrusts that's described in this Planes, Trains, and Automobiles article. [00:27] And also he has this article called Rekway Momentum where he discusses the AD ratio and how to use it to detect market volumes. There's also a variety of Twitter accounts that discuss when market sentiment is really negative and there's a sudden breath or upset that indicates a change in momentum, including this Twitter account, Sentiment Trader. [00:48] So you can see on March 16th and March 18th, just three or four weeks ago, these accounts were discussing the NASDAQ falling to a 52-week low, right? Multi-year lows, very bad sentiment. [01:00] And shortly thereafter, there was a huge change in momentum, indicating a tradable bottom. There's also this popular Twitter account, MacroCharts, that talks about this as well. He talks about on March 12th how a sentiment was very overspilled and negative, some of the most in history. [01:15] And on March 17th, he pointed out massive strength in tech. And March 18th, he talks about the strongest three-day moves in history and these extremely rare breath thrusts that occurred, indicating a sudden change in momentum once again and a tradeable bottom maybe setting up, right? [01:32] And I'm going to focus on this particular week of January 2019 when there was extreme fear in the market and one of these breath thrusts occurred. And it ended up being a huge buying opportunity as described by this article in Humble Fear in the Markets, a rare, what's my credit card limit buy signal? [01:50] Where it's like, hey, this is as good of a setup as it gets. You got to take a big swing right here. And I often do exactly that. So this particular tutorial is going to be all about breath thrust. and it's essentially an extension of the last video I just made on fear and greed. [02:06] So the setup here is usually that there's an extreme amount of fear in the market. You can feel it all around you. Everyone just has this really negative attitude. If you're watching all the tweets out there, everyone's like, oh, the world is ending, I'm selling all my stocks, a recession is happening, etc., etc. [02:23] So the idea here is you're not just buying when there's the first sign of fear, right? There was extreme fear actually occurred here in probably early December of 2018. But if you would have bought there, you would have had to deal with this entire drawdown here. [02:37] So the market actually went down probably at least another 10% here. So the idea here is you're not just buying when there's extreme fear. You're also looking for a sign that momentum has shifted in the other direction. And that's what this breathless indicator is trying to tell you. [02:51] So you don't just buy it on the way down here. you're actually waiting for this thrust off the bottom and the signal actually occurs around here on January 7th I believe and that's when this red thrust indicator would tell you you should enter. As you can see after this [03:04] capitulation and test that occurred here it was pretty smooth sailing in 2019. There was a little bit of a trade war fierce here but other than that there wasn't a huge fall down after that and actually from this point you could [03:16] pretty much hold the entire year from January 2019 through December of 2019. On the trading view chart here you can see where the signal occurred so I have this Zweig breathless indicator on here and you can see whenever the market is [03:28] deeply oversold and the change from momentum is seen here when it goes from below 40 here to above 61 I believe is the numbers here and according to this Zweig breathless here this change in momentum has to occur very quickly here [03:43] so this this change from oversold to overbought needs to happen in a period of less than 10 days. And so what I want to do in this tutorial is get a better understanding of this indicator by coding it using Python. I'm going to show you that in a Jupyter notebook, [03:57] and we're going to download the data. We're going to calculate this and make sure we understand it a little better. We'll start by discussing this occurrence in January 2019, but then we'll go back and look at some older occurrences of this indicator and some variations. We'll also discuss [04:11] some of these threats that occurred in the present. So let's head over to Google Colab here, and I'm going to walk you through this code I've written in this Jupyter notebook and share it with you. So let's go ahead and get started with writing some Python code. [04:24] So at the top here, I've provided a few useful links. First of all, the definition of breadth thrust from a benzopedic year and a description of the Zweig breadth thrust. And I also linked to the training view pine script by LazyBear that actually implements this in training view. [04:40] So it's an indicator that measures a change in mark momentum during a compressed period. That's why breath arrest occurs. Breath arrest indicator rises from below 40%, so below 40% here, to above 61.5%. [04:54] And this occurs within a 10-day period. So from here to here, you see how quickly that happened. That indicates, boom, taken off, changed momentum in a short amount of time, right? And so this formula here is shown here. [05:07] It says computed by calculating the number of advancing issues on an exchange, such as the New York Stock Exchange, and dividing by the total number of issues advancing plus declining on it and generating a 10-day moving average of this percentage. [05:22] I've also linked this humble student of the markets article that discusses the occurrence in January of 2019 and some previous occurrences here that occurred, looks like in 2004, coming out of the dot-com crash. [05:35] So there this bear market from 99 through the bottom in 2003 and how there a buy signal in 2004 after it looked like this had fully bottomed out Coming out of the bottom here in 2009 after this 20 decline in 2011 [05:49] and also this continuation looks like it occurred in 2013. And the unique thing about this occurrence in 2015 is this wasn't the final bottom. It actually revisited the lows and went a little bit lower in 2016 here. [06:03] But if you buy here in 2015, you see you were still pretty happy here through 2018. And then the final occurrence that's being discussed in this article was actually occurring in the present when this article was written in January 2019 after this roughly 20% decline that occurs at the end of 2018. [06:20] So how do you actually calculate these signals? That's what we do on this channel. I show you how to code these things in Python, and I hope that's developed a better understanding here. So the first thing we need is a list of all tradable stocks on the New York Stock Exchange. [06:34] So we need to download this list from somewhere. There's a couple ways to get this. One way is to go to this NASDAQ website that I've linked here, and you can actually download a CSV file. You'll have to mess with these filters right here, and you can download a CSV file and parse that out. [06:49] Another way to get this list is to use my sponsor, Alpaca. Alpaca is a developer-first company that provides a stock and crypto trading API. You can do paper trading to test your strategies. [07:03] You can do crypto trading, fractional trading. You can do short selling. They have a brokerage API. You can build an entire FinTech application on top of this. So if you're interested in coding these types of applications [07:15] and following along, and you want to support the channel, please visit Alpaca and sign up using the link below. So what I've done here in the Jupyter Notebook is I've imported get pass here. And what that allows me to do is give myself an input prompt here. [07:29] That way I don't have to embed my API key inside of the Jupyter Notebook. I can just ask for it right here. And then in my Alpaca account, I can just copy the API key like that, hit enter, and enter a secret key. [07:44] And then I can just shut down this super notebook later. And when I share this out, I don't have to include my API key, right? And so I've added an API key. And then what I do here is in the notebook, I can start with an exclamation point here, and I can install any Python package. [08:00] And so I'm installing the Alpaca Trade API just like that. That way, I'll be able to use the Alpaca Trade API in my Jupyter Notebook. So I'm installing it right there. And so within the Alpaca API, I can set up a new REST client. [08:13] So I'm importing REST here. And I can call this method called listAssets. And this is all in the documentation. And so what I'm doing here is getting a list of assets from Alpaca and filtering them down to the ones that are on the New York Stock Exchange [08:27] and where their status is active. And I'm building this list of symbols. and I printed this symbol list out right here in case you just want to copy it. And so I can just put symbols right there in the Jupyter notebook [08:39] and it should show me all the different symbols. And look at that. I have a huge list of symbols I can work with. And the nice thing about Alpaca's historical data API is I can just pass it a list of symbols. [08:52] So rather than just calling this one at a time as with some other APIs, I can pass this entire list of like two or three thousand symbols to it and just say get me all the bars in a certain date range. And since I'm interested in that first week of January, [09:07] what I can do here is I get all the data for December and that first week of January and call it get bars and that'll give me this bars data frame right here. So I can run this bit of code to get all the historical data [09:20] for thousands of symbols all at once for the entire month of December and the first week of January. And this takes a little bit of time, but it's actually pretty quick. So you can see I have all that data now from A through Z, so symbol AA all the way through ZYME. [09:34] And it doesn't show all the ones in the middle there, but you see there's actually 54,000 rows here. I have open, high, low, close for every single symbol along with the volume, trade count, and VWAP for each day and for all those symbols, [09:46] so thousands and thousands of rows. And so once I have all of this historical data for all the stocks in the New York Stock Exchange, I wanna calculate this Zweig breath rush. And if you'll remember, the first step in calculating [09:59] this breath thrust indicator is to calculate the number of advancers and the number of decliners. So how many of these on any given day went up and how many of them went down, right? [10:11] And to get that, we can, first of all, calculate the percent change for every day. And so we can look at the close and we'll create a new column. So we have this VARS data frame. So I'm going to create a new column called percent change. [10:24] And in there, I'm going to store the percent change of each of the closes here. So pandas has this percent change function that I can run. And then also for each of those percent changes, I can get the sign of that percent change. [10:37] So it's got a positive value or a negative value. And if I run that, you'll see we have this percent change with each row, and we have this sign column. And so if you look at this percent change, for instance, on this last row here, [10:50] you can see the open was 1560 and the close was 1580. and you see the percent change was like roughly 1.4, 1.5%. And that's a positive value, so I have a positive one in the sign column now, [11:04] since I called np.sign, so numpy.sign. And you can see for the ones that went down, I have a negative one here. So I have a clear distinction of the number that are positive and the number that are negative. So I have a column here that clearly shows for every single day which stocks went up and which stocks went down. [11:21] But I still have this 54 rows here So I wanna actually group these and do a count similar to like group by and count in SQL I want to kind of summarize the total number of the ones that are positive and the total ones that are negative on any given day [11:37] So what I can do here is create a new data frame and call bars.groupBy. And I say I want to group by the timestamp. So I want to aggregate and get all the different symbols on January 10th. [11:51] I want to group them all together and group them by sign and I want to count the number for each sign. And then I want to put this in a new column. So this bit of magic here, and I looked this up to figure out how to do this, but what this does is just aggregate this all and stores it in a new column. [12:06] And you can see for every single day starting December 3rd of 2018 through January 10th of 2019, I have a count of each sign. So there's three different values for January 3rd. [12:18] I have the number that have a negative one, the number that are unchanged or didn't trade, and the number that are positive, right? And so you can see the number of advancing issues on January 10th was 1,252, [12:30] and the number of declining issues here that have a negative one sign are 730. And so I'm well on my way to calculating the use-wide run thrust because now I have the number of advancers and the number of decliners. [12:44] But you see I have three of these rows for each date. I want to kind of transform this a bit to make it look a little different. That way I can calculate some of these percentages in moving averages. And so this bit of magic here, this pandas.pivot table, what it does is rearranges the data frame so that I have all of these on one row. [13:04] So for January 3rd, for instance, now I have columns called negative 1, 0, and 1. So I know the decliners and the advancers here. And I have them grouped. And there's just one row for each day, just like that. [13:16] So I see the decliners there and the advancers there. And that's nicely summarized. And I want my columns to be called negative 1 and 1.0. So what I can do is call dataprime.rename, and I can rename those columns advancers and decliners. [13:31] And now look at that. For every single day, I have the number of decliners and advancers, just like that. And I'm almost there. So now I just want the percent that are advancing and the percent that are declining. [13:44] and as our definition indicated, we want the total number of advancers divided by the total number of advancers plus decliners. And so I just calculate the percentage advancing like that and I just [13:57] get the number of advancers in this column and divide it by the number of advancers plus decliners in each of those rows and then I get this percent advancing and the percent declining. And now we're getting even closer. And first of all, let me run all these just to make sure all this data is fresh. [14:13] So I've already gotten the bars. I've run this and got the percentage changes. This is the group by. There's my table there. And this is the rename columns. And then you see I was actually experimenting with this for May of 2020. So that's why I wanted to rerun this to make sure I'd get it for the period of time we're discussing right now. And so now you see we have these percentages here. And look at these percent advancing. You'll notice in that sharp decline in December, the percent advancing was like 13%. [14:43] 24%, 31%, 70%, 12%. You see just everything was selling off. So there was a very few stocks that were going up during this period. And then you see at the bottom there, on December 24th there, you see it's 20%. [14:59] So that was the bottom. We see the 26th, the next day, 90% of the stocks here that we pulled were advancing. So there was a sudden spike off the bottom where there was a sudden change in momentum. [15:12] But the Zwei breath thrust doesn't just want a huge one-day bounce before continuing its decline, right? That's why part of the definition involves a moving average. So the Zwei breath thrust specifies a 10-day exponential moving average. [15:27] And so you want to make sure this thrust is powerful enough to start a new bull market, right? And so we can calculate a new column called EMA. And what we do is calculate the 10-day moving average here, right? [15:39] So across a 10-day period, this percentage advancing has to be very, very powerful. So when I calculate this EMA column, you can see how this EMA is like 30%, 28%, 26% at the bottom here. [15:54] And even though there's that big spike on the 26, you see that EMA is only at 38%. And so the rule here for these wide breadth breaths is that it goes from under 40% here to above 61% up here, right? [16:07] And so that move has to occur very quickly in a 10-day period. So that 10-day moving average needs to go from less than 40% to above 61% in less than 10 days, right? And so if I look at this on December 24th, you see it was at 26% right here. [16:24] And in 1, 2, 3, 4, 5, 6, 7, 8 days here, it was at 61%. So here, January 7th and January 8th in this short period of time, it went from deeply oversold to coming out of that bottom, and that was the signal there. [16:41] I believe it was on January 7th, and that day is when the Zweig breath rest told us it was time to buy. So that's how you calculate the Zweig breath rest using Python code. [16:53] I also mentioned that I wanted to discuss a couple other variations of this and a couple other time periods. So I wanted to touch on this article and a link called Breakaway Momentum. and he talks about the advance decline ratio here And in here he calculates this 10 ratio of advancers to decliners And so I shown these occurrences here And one unique thing here is that he points out this signal occurred [17:17] on June 3rd, 2020. And there's another post on Humble's Student of the Markets in June of 2020 that discuss this additional breadth thrust that occurred. And that's kind of interesting, [17:29] right? Because if you look in the year 2020, there was this move off the bottom, But then you notice in June of 2020, there was another breast thrust right here. And what you need here is not coming off the bottom. It's actually happening in the context of an uptrend. [17:44] And what that indicates here is that potentially there's another huge upleg in stocks that is about to occur. And indeed, that was the case. A lot of people were expecting after this initial up move for there to be a huge sell-off or that we were going to retouch the lows. [17:59] A lot of people were like, oh, we've got to retouch the lows first. And what happened after June 2020? Did we go back and reset the lows? No, the S&P 500 went from just above 3,000 all the way to January of 2022, all the way to like 4,800 there. So the market just went on another tier after this additional breath rush. [18:22] And so in this notebook here, I've included an additional calculation for this period from May through June of 2020, where I calculate this breakaway momentum indicator as described in this article by Walter Diemer. [18:36] And as you can see right here, once again, I'm getting bars again, but I'm getting it for the period of May of 2020 through June 10th of 2020, just to study and make sure we understand the signal. I'm getting, once again, the percentage change in the sign and grouping and pivoting and reading and so forth. [18:52] But this calculation is a little bit different. So there's only a few lines that are different here. What we do is find the number of 10-day advancers and 10-day decliners. And what he does is actually sum them up for a 10-day period. [19:05] And so we're adding them cumulatively here. So I'm getting the sum of the last 10 days. So you see my 10-day advancers here and my 10-day decliners right here. And then we're just getting this ratio and calling it breakaway momentum. [19:19] And so you get the sum of the 10-day advances and the sum of the 10-day declines. And this ratio needs to be above 1.97, I think is the number he used. And you can see on June 3rd here, this number is at 2.05. [19:34] He has it at 2.07. And this slight difference can be explained since I pulled, it's 2022 now, and I pulled the NYSE symbol list today. But back in June of 2020, this was slightly different. So there's going to be slight differences in these populations. [19:48] As you can see, this breakaway momentum signal happened right here. Just another variation using advances and declines, and you see that the market went on a chair for like 18 more months if you held the S&P 500. [20:01] The final variation of this breath thrust I want to discuss is this Whaley breath thrust here, and I've also linked this article, Planes, Trains, and Automobiles, in case you want to read through this. So this article is just another discussion of breath thrust and market momentum. [20:13] them. It calls it the advanced decline thrust, and it takes the sum of advances for, it looks like it's five days in a row, and the sum of declines, and it does this advancers over advancers plus [20:25] decliners. And so what Whaley does here is look at this five-day ADT, advanced decline thrust, and determines that when this percentage is above 70%, it's statistically significant. So we look at [20:38] 252 trading days and the percent change that occurs after this threat and you see when it's above 70% the percent change the S&P 500 rose 18% when it's above 75% the percent change is [20:52] About 22 or 23 percent which is very statistically significant now these numbers here when it's 7 or 8 percent We can ignore those right because the S&P 500 is on average on a given year of about you know [21:05] seven eight nine percent so these extreme threats here are statistically significant so I've included his calculation here all I did was instead of 10 day I got the five day advancers five day decliners got that sum here and I just set whaley percent equal to five day advancers [21:22] over five day advancers plus five day decliners and did that for the year 2020 and this number on June 5th is over 75 percent and according to this article that he wrote back in 2009 a number over 75% is statistically significant, and I think he even said it had a perfect track record. [21:41] And indeed, after that breath of breath in June of 2020, as many people were expecting a retest or stocks to go back to the lows, stocks continued to go on a tear and performed very, very well over the next year and a half. [21:56] The final takeaway is there's a lot of fear and anxiety that's happening in the present moment about what's happening in the world and also with a possible upcoming recession that people are trying to predict, and it's very hard to predict. [22:09] But I'm keeping an eye out right now this year. It says neutral right now, but I'm watching for when this might shift over to extreme fear for the ideal opportunity to deploy a significant amount of capital. And so that's why I wanted to revisit the fear and greed index [22:22] and also talk about these different breadth thrust indicators to detect when a significant tradable bottom may have occurred. So I hope you like this tutorial, and I hope you like this Jupyter Notebook approach. I'm hoping to incorporate this a little bit more into this channel, [22:35] but whenever I do a full stack app, I'll switch back to Visual Studio Code. So thanks a lot for watching, and stay tuned for the live interview, the live stream this weekend with the author of Jesse Trade. That's going to be really good. [22:48] And then I'm going to be posting a full stack tutorial once again. So, thanks a lot for watching, stay tuned for the next video. Thanks.