Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Saturday, May 25, 2024

Pine Script: A Profitable MEAN REVERSION STRATEGY

 hey Traders welcome back to another post thanks for tuning back into my blog uh sorry for the delay between posts I was on holiday for a couple of weeks but I'm back now and I'm excited to show you guys another trading view strategy so today's strategy is a daily time frame long only mean reversion system designed for us equities that's what I originally designed this system for but it does work on all markets it's not necessarily profitable on all markets but this system should work on any Market you apply it to but when I initially designed it I have been using the Russell 2000 as my sort of in Sample data set for developing the system so the system was originally created in Amy broker as some of you may know I've been learning how to use Amy broker to back test more sophisticated systematic trading systems and this is a system I developed in Amy broker I've been testing and developing in Amy broker and I've converted the code from Amy broker's language into Pine script because I think this is a really cool system it's quite simple and it will be a great way to demonstrate some features in Pine that I haven't demonstrated yet such as using limit orders to enter positions so I haven't finished optimizing the system I haven't finished the the entire development and back testing process I'm about halfway through that process at the moment but the system is profitable at least according to my initial testing let me bring up some trading results here so we have a single run back test here on the Russell 3000 using 50 margin or leverage so I can trade double my account balance and according to a 20 position portfolio where I'm trading 10 of My Equity per position it had a roughly 20 annual return with a drawdown around 20 not fantastic numbers but also not too bad so there is definitely potential to this system has a 57 win rate and over 6 000 trades so it seems pretty robust I've done a little bit of Monte Carlo just testing on the system just to see what the distribution of results are over you know slightly randomized data sets and entry criteria that sort of thing and it seems pretty robust it definitely needs some work before I would actually put real money at risk using the system but it's in a decent enough position now that I feel comfortable sharing my idea and my code with you guys so this system was inspired by information I've learned from Nick Rogers many of you will know if you've been following my channel for a while I've been enrolled in a mentorship program with Nick for about a year now and I've learned tons and tons of incredibly valuable information from Nick if you've never heard of Nick go and check out his chat with Traders interviews they're fantastic I'll leave a link in the video description but basically this system is attempting to buy healthy stocks experiencing short-term sell-offs so right here is a perfect example of what this system is designed to capture so what we're looking at here is a 200 period EMA this is my directional bias filter so I need the market to be trading Above This long-term moving average before I even start looking for trading signals the second blue line here is a 20 period EMA so we've got two EMAs here 200 period EMA a 20 period EMA and you can see these upper and lower lines these are an ATR stretch from this middle EMA so what this is officially called is celt I can't even say it Keltner bands so kalthner is a Trader who invented this technique and we're just simply subtracting with the default settings a one ATR distance from this Central Moving average and this gives us basically volatility bands as kind of like Bollinger Bands but instead of using standard deviations we're just using the ATR I did try using Bollinger Bands with this system when I initially started testing the idea and from my testing Kelton abandons just seem to work better so I've stuck with them while developing the system I'm also not a mathematical minded person so I find an ATR and moving averages just easy to wrap my head around than standard deviations and all that sort of stuff that I'm still admittedly learning and I'm not that proficient with my understanding of that sort of thing I come from a musician background so when it comes to me developing trading systems I'd like to keep it simple so that my dumb mind can wrap my head around what I'm doing but the good news is for people like me you don't need to be that advanced with your systems in order to develop profitable systems and strategies so anyway we're using Keltner bands one ATR stretch above and below this Central Moving average the upper band I don't we use in my system I'm only drawing it there just for reference purposes that's why it's quite faint it's like a 50 transparent gray color what we really are focusing on is this middle blue band this green band and this red moving average long-term filter and what I want to happen before I enter a trade is I want price action to be trading below this lower band this green band so I want price to be trading away from the mean and I Define the mean in this system as this 20 period short-term moving average so long as the market is trading Above This longer term moving average I consider this an upward trending stock and when it trades below this lower band I'm hoping for it to revert to the mean which is our Central Moving average but I don't just buy because price has closed below this lower band I tried testing that it didn't seem very profitable so what I've done this is a technique I've learned from Nick is I'm using an ATR stretch to place a limit order to enter my positions so as soon as price closes below this lower band while trading above the long-term moving average I place a buy limit order one ATR from the low of that bar so that on the next day if price action trades down and hits that limit order I enter long on this Market this stock and so you can see here that we generated a buy limit order for this day here on that next day did not get filled price did not trade that low but then on that following day we generated another buy limit order one ETR from the low and on that next trading day it did in fact get filled by a price we went long and then my exit criteria is either if price continues lower and closes below this 200 EMA if that happens I get out and that's my stop loss if that does not happen what I wait for is price to revert to the mean and the way I Define that is by having the high of a daily bar touch our 20 EMA so on this bar here price touched the Central Moving average and on the next bars open we exit our position for a small but reasonable profit and if you do that over and over again over 84 trades on this particular Market Southwest Airlines we can generate a decent return so we've got a thousand percent return over however many years of trading this stock and a 26 Max drawdown not too bad that's a comfortable drawdown for me and keep in mind that this is trading 100 of our equity on this Market what I would normally do and what I'm doing in Amy broker when I'm developing the system is I would trade this on a portfolio of stocks so I would trade 10 to 20 stocks at a time that would be my Max open position count and so these numbers would reflect on a fraction of My overall account balance so maybe I would have about a hundred thousand dollars invested in the system um so I would have a 26 Max drawdown on this Market on ten thousand dollars worth of My overall equity and these numbers would be sort of averaged down across multiple markets and so this would just be a micro cosm of the overall system the overall portfolio so keep all of that in mind so now that we understand what the system is doing let's break down the source code it's not too complicated and then I'll give you some final thoughts at the end of the video okay so let's get coding what I have here is a essentially blank strategy script I've just titled it ATR reversion system we've got overlay set to true so that we're drawing over price action and not into our own indicator box we have initial Capital set to 100 000 US dollars I believe um base currency default I might actually Define my base currency here as well and I've already forgotten which parameter that is currency I guess currency equals currency dot USD and by the way the trading view team have released a really cool update to the Pine editor and now the editor runs on the same infrastructure software as Microsoft Visual Studio if you've ever used that that's quite a quite a um fun editing program which I don't often use the word fun to describe a text editor but it's really convenient really efficient so now the pine editor has some really cool features that we'll go over in today's video as well nothing major has changed but we have some quality of life improvements and things that make coding more efficient we'll cover some of those throughout the video so we have overly set to True our base currency is US Dollars our initial Capital 100 000 our default quantity type is a percentage of equity this is our position sizing our default position sizing type is a percent of our overall account balance and the default value or position size is 100 of our account balance so the very first trade we take will invest one hundred thousand dollars into that trade and then someone the commission type is set to commission cash per order so when we buy I pay 9.95 when I sell I pay a flat rate of 9.95 that's the self-wealth broker fees I use self wealth to operate some of my Equity trading systems I also use Interactive Broker and they operate a little bit differently they use a it's like a like different brackets depending on your position sizing so I think the default one I normally pay is about 0.005 cents per share but for today's lesson I'm going to keep things simple we're just going to go with a flat commission rate of about 10 bucks per trade 10 US dollars per trade so those are our default parameters the next thing to do is get some user input I'm just going to copy this code over to save time since it's not that important what we're doing here I'll tidy up these a little bit to make them easy to read just by indenting everything it's a new habit I've gotten into that I quite like makes the code easier to read so what we're getting here is our long-term EMA so a 200 period EMA by default our short term EMA which is a 20 period by default a ATR period which is five by default so we're calculating the ATR based on the past five daily bars our ATR band distance is a multiplier of the ATR by default it's set to one our ATR bias stretch is the stretch from the lower band that we place our buy limit order at that's also set to 180r by default then we have which band to sell at so this is our mean reversion sell Point by default it's set to the middle band which is our short term EMA and the price value value here I underscore sell Source short for input underscore cell source is a price source and it is the high of the bar by default so when the high of the bar touches our Central Moving average the 20 period EMA I consider price to have reverted to the mean and I exit on the next Bar's open so those are our user inputs the next thing we need to do is get our indicator values paste that in there so we're getting our long-term EMA using the ta.ema inbuilt function we pass in the price Source we want to calculate our EMA on and the length so that's 200 by default and our short-term EMA is 20 by default and then we get our current ETR value the next thing we need to do is get our ATR bands so I'll type this out get ATR bands so we need ATR band top and now I can demonstrate some of the cool new features of this new editor I see when we start to type all this stuff popping up at first it's overwhelming if you're new to Pine but it's actually extremely efficient and convenient what this pop-up is and I'll explain how to use it in a second but we have ATR top and bottom so to calculate the ATR bands top we need to add our ATR band input to our Central Moving average so to do that I need to reference our EMA short and see how this has popped up I can just simply hit tab now and it will automatically fill that out which makes coding in Pines so much faster um than it used to be you used to only be able to autofill built-in functions but now we can reference even our own custom variables and things like that so it's really cool makes coding in Pine a real um a real pleasure to be honest so we need to add our ATR value the current ATR multiplied by our input ATR band so that's this input here so one ATR by default but we can adjust that in the settings and we can see how that affects our strategy performance for the lower band the one we actually use to reference for our buy conditions we need to subtract the same values so EMA short term minus the ATR value multiplied by our ATR band that gives us our two uh bands so before we continue let's draw all of this to the Chart so that we can see what our script is actually doing so the first thing we're going to do is plot our EMA long term I'll give it a title of EMA filter this is our filter for filtering out trees that we shouldn't take when price is trading below this EMA I'll set the color to color.red and the line width to two you can see as I'm typing this out it actually references which parameter we're working with which is really cool it also shows the color that we'll be drawing onto the chart when I save this code so little things but they do add up to make working with pine just so much more efficient and easier we can actually change the color here with a click of a mouse really cool new feature the next thing we're going to plot is our EMA short term I'll call this ATR Band Middle and I'll give it a color of color.blue and then I'll just copy and paste the other plots over to save time since you get the idea now of what I'm what I'm doing here so we're plotting the EMA long term the EMA short term or our middle band we're plotting the ATR top and bottom and then we are going to plot our limit order the price that we are going to place our limit order but we haven't written that code yet so I'll comment that out for now and we'll add that in later but now if I saved my code we should be getting our core indicators drawing to the Chart we have our Central Moving average the two bands and our long term price filter directional bias filter so when price is trading below this the system does nothing it's a long only System since stocks especially U.S stocks tend to Trend upwards over time far more often than they Trend downwards this system is taking advantage of that overall directional bias and then we're just buying short-term weakness in stocks that are trading above their long-term moving average so now we have everything we need in order to combine this information to create our buy and sell filters or conditions so to do that I'm going to first Define my price stretch variable so that's just going to be a float or a price value and I'm going to call this buy limit price and I'm going to initialize it as n a or not a number nothing null to begin with and then we'll reassign this value later to our actual Buy price once we've calculated that so the next thing we need to do is check our setup conditions or in other words is the bar close below the ATR band the lower band and is it above our long term EMA pretty simple entry criteria for this system so I can create a new variable here called setup condition and this will be set to is the current bars closing price lower than our lower band our ATR band bottom and is the low of the current bar greater than our EMA long term so price is trading above the EMA and below our lower band so it's in this sort of Zone here this is what I consider to be trading away from the mean and we are looking for price to have a sharp sell-off and then revert back to that mean um that's what this system is attempting to capture so I'm getting a little bit ahead of myself here but the next thing we're going to do is clear any pending limit orders so when you place a limit order using the strategy tester in Pine that limit order stays there indefinitely until it gets filled basically or canceled so what I'm going to do here before we even place the limit order is we're going to cancel any pending limit orders using the strategy dot cancel all function so if we have a limit order that has not been filled yet we cancel that immediately on the start of each new bar so if the limit order was not filled on the previous bar and it was placed on the previous bar we just cancel that order because we don't want the limit order staying on the chart indefinitely if it doesn't get filled the next day then we basically the trade's gone and we just keep repeating the process waiting for the next bar to exceed one ATR from our lower band and that's how the system works so now that we've got all our limit orders cleared we have all our entry criteria set up and ready to go the final thing to do is enter and exit our positions so to enter our trades I'll just say here enter trades on next bar after our setup condition is met our setup criteria is met which is this line of code here so I'm going to use an if statement here if setup condition is true and then we need to tab to indent within the scope of this if statement otherwise we won't compile this script will give an error if we don't do this so if our setup condition is met we need to calculate our buy limit price so I'm going to set by limit price to the current bars low and then we need to subtract the current ATR value multiplied by our ATR stretch so this is the stretch from the lower band that we want to place our limit order at by default it's set to one ATR so basically once price is trading below our lower band we place a buy limit order 180r below that lower band sorry below that Bar's low and we're hoping for a Sharp sell-off like this bar here followed by a quick reversion to the mean that's the edge that this system is trying to capture so now we need to strategy dot entry we use this function to enter our position we need to give it an ID so this is a long only system so I'll just call this entry ID long and then we need to tell it which direction we are trading in so I'll just say here strategy dot long and we now need to specify some of these other parameters you can use stop to enter a buy stop above price action you can use quantity to set your position size and OCA stand stands for one cancels all I'll cover these in a different video that's on my to-do list pretty soon it's been requested a few times to show how this parameter works but for today's lesson we are focusing on limit so limit is a buy limit price so we need to specify our limit as this variable here that we just calculated so the low minus one ATR is our buy limit price now that we've defined by limit price we can uncomment this code here and now this will draw a little cross to identify which price we are placing our limit order at so we are now entering our positions but we're not exiting them yet so we need to add a couple more lines of code here the first thing we're going to do is because I've defined in the settings menu this option here that allows the user to select which band to sell at and which price source to reference we need to do a couple of things here the first thing we need to do is get the cell whoops get sell price get which price we we are referencing as our mean our average that we are reverting to I'm going to use a switch statement here to Define this value sell price because it's just a little bit more efficient than using several if statements and what how this function works is we need to pass in a value so I'm going to pass in my cell band input which is this setting here so we're passing that into our switch statement and then what the Syntax for this switch statement is to Simply say is cell band equal to this value top if so then we want to reference our ATR band top price value otherwise if it's not top we check is it middle if it's middle then we set it to our EMA short term and then finally if it's bottom then we set it to ATR band bottom and I'll indent these to make it a little easy to read and that's it we now have our sell price variable defined depending on which setting the user selected here that will dictate which value gets selected as this variable's value and finally we can exit our trades so the criteria for exiting our trades on this particular system is if our price source which is this parameter here the high by default so with the default settings we're going to check is the current bars High greater than or equal to sell price which is the variable we just defined here so depending on which one we've selected will dictate which sell price we are looking at so by default it's the middle band our short term moving average the 20 EMA so by default this would be saying if the current bar is high is greater than or equal to the 20 EMA or price has closed below our long-term moving average remember that's our stop loss so if uh the current bars closing price is less than EMA long term or our red line then we need to exit our trade either for profit hopefully not always this condition will not always mean that we're exiting for a profit because price might have trickled lower and then touched the 20 EMA after we bought higher than that EMA it doesn't happen often but it can happen so this will usually exit the trade for a profit or a small loss this on the other hand is our sort of Fail-Safe if price just continues plummeting lower we want to exit at some point we don't want to hold on Forever Until price comes back up to that 20 EMA because who knows when that might happen once the 200 EMA is breached so if price has touched our 20 EMA or closed below our 200 EMA we call strategy Dot close and this function will close any open orders we need to pass in the ID of the order to close in that case now in this case that's long that's the only order type we have open so passing along there and this is optional but I'm going to add a comment here uh comment equals exit trade the reason I'm doing this is because otherwise uh the strategy tester has a really long label for exiting your long trades I'll show you what I mean in a moment that's how script completed we have finished writing all the code we need hopefully I haven't made any mistakes and when I save this it should compile and we should have that first trade popping up here there we go so I'll show you what I mean with this comment if I get rid of this comment which you don't need to include but if I get rid of that this label up here uh it just clutters up your chart when you have a lot of trades in a short period of time so I like to include this comment just to tidy up my charts a little bit just a matter of OCD preference but here we go so let's go over this one more time we have our 200 period moving average and a giant drawing tool don't know what happened there one second hit the wrong hotkey so again we got the 200 EMA this is our filter price must be trading above this red line then we have our short-term moving average the 20 EMA price must be trading one ATR below that EMA so price must close below this green line and then these Green Dots here or crosses are our buy limit orders so on this bar here we close below the band and we place the buy limit order one ATR below the low it was not hit on the next bar and so we canceled our pending orders on this bar and then we we repeat the process so this bar also closed below our green line so our buy conditions are still met so we place another buy limit order one ATR below the low and this time on the next bar it was actually filled by Price action and we entered long when price came down and hit ow buy limit order if this bar had gapped down lower than our buy limit order and opened down here somewhere let's say this was a green bar and this was the open then our entry price would actually be the open of this bar not where we placed our buy limit order because when the Market opens if it's trading below our buy limit order it's basically giving us a better price than we wanted and so our broker would enter us long down here instead of up here it doesn't happen often but it can happen it's not a bad thing because it just means we're getting a better price than we wanted and oftentimes a big gap down will be followed by a short-term rally back to the mean and two quite often when that does happen unless there's a steep sell-off like during the covert crash and price just plummets throughout 200 EMA and stops us out for a loss we'll use it usually get a nice snap back to the mean after that sort of price action and so that's completely fine with the system in this case this price opened up here traded down throughout the day eventually exceeded our buy limit order and then closed up here and then on the next few days we sort of plateaued here we Consolidated for a couple days and then we had that reversion to the mean price tagged out upper moving average and we exited on the next bars open for a small profit so that's our script completed uh before I wrap up this lesson obviously the source code will be in the video description if you want to play around with it yourself but let's go over some of these settings and see how they affect this system so first of all let's try seeing what happens if we change sell it band to the top band this gray band so if I hit Top now we exit all the way up here so we still enter down here but now we hold on to our trade much longer it's not really a mean reversion trade now because we're exceeding the mean the 20 EMA by quite a bit here so this is now more of a pullback system that's trading Trend continuation setups just by changing that one parameter another thing we could do is change the band to the lower band now this is a more conservative mean reversion system now the system is entering Along on this bar and then the next bar tags our lower band and so on the bar after that we exited the open so that's a more conservative approach uh it can still be profitable I found in my testing that it um over the Russell 3000 Universe of stocks it's still profitable but just not quite as much as the middle band the top band is a little bit too aggressive and I have found that it increases the drawdown without increasing the return much the middle band is the sweet spot for this sort of system I've found at least with the default parameters and so that's what I use I have also played around with the price Source that's why we have these two inputs while I'm developing the system once I decide which parameters best suit the system I will hard code this and you won't be able to select it when I finish my script in Amy broker but if you want to you can play around with different price sources so for example we could sell after a close above the 220 Emmy instead of just touching it with the high so that's another option for this particular system on this particular stock it performs pretty similarly to referencing the high so if I reference the high pretty much same drawdown a little bit less profit but obviously this is cherry picking and data mining one single stock you'd want to see how this performs on multiple stocks preferably hundreds of stocks if not thousands because the nature of the system doesn't take that many trades so we need a larger sample size to be able to dictate whether or not this system is performing acceptably within our risk metrics so our we want the system to trade with a Max drawdown that we're comfortable with while also producing a profit and a win rate that we're comfortable with and that is acceptable to us anyway that's it for this system I'll just quickly run through a few markets here so this one wasn't that profitable um neither was this one this one was not profitable at all this one was basically break even a little bit profitable only took three trades on this one um this a bit better 60 return with a 10 drawdown 40 return with a 60 drawdown is pretty rough but again trading over a large portfolio of stocks that wouldn't be as bad um 86 return with 28 drawdown um 34 return with a six percent drawdown but only nine trades so you get the idea we need a larger sample size in order to determine if uh this system is profitable or not Netflix not too bad 130 return with a 30 drawdown over multiple years and multiple stocks with a larger portfolio of positions the system would give you results much closer to what we see here where you can see that over the past 30 years or so the system has been quite profitable it's pretty volatile it does have some pretty major down months but every year pretty much besides two years in the current year which isn't over yet were losses so we had two maybe three losing years over the past 30 years with a reasonable return a pretty big year here in 1999 it's obviously during the tech crash there's probably a lot of mean reversion happening and sell-offs around this period so it does pretty well during a sell-off market let's look at 2018 2019 it did okay did okay the past couple of years this is a single run back test so you can't depend on this data too much but it gives us a fair idea of uh you know 20 Max drawdown if we ran a few Monte Carlo tests and added some more parameters and filters this might be a pretty profitable and acceptable system to trade so before I wrap up this video I just want to mention one last thing in relation to um one of the potential risks when using limit orders enter your trades it's important that you guys are aware that the use of limit orders introduces the potential for selection bias now selection bias is a sneaky risk that not many Traders understand until they've been burned by it through experience but selection bias basically manifests itself in real time trading you may get very different results in real time than you did on historical price data due to the fact that the system generates lots of variations of signals when you use limit orders so even when we're using leverage or margin depending on the quantity of signals that gets generated by your system there will be times when your system generates more signals than you can actually execute due to Capital limitations or not having enough money so if your system generates a hundred buy limit orders for the next day you're not going to get filled on all on all 100 of those and you're not going to know ahead of time which ones will get filled and which ones won't that introduces selection bias because now either you have to choose which limit orders to place which is the classic definition of selection bias or your system basically just has a random selection based on whichever stocks fill your limit orders first when back testing on a daily time frame unless you have access to intraday price data for the past 30 plus years and you can run your system and detect which limit orders were filled first you kind of have this issue now there are several ways you can mitigate the issue of selection bias which I'll probably cover in a future video because this video is already long enough and it's not just a problem related to this particular system but it affects all systems that generate lots of signals see how this performed on bitcoin not great profitable but not great anyway the main ways that I know to mitigate selection bias is to increase the sophistication of your signal generation to reduce the signal quantity so your system will just produce less signals to trade based on having more sophisticated entry criteria now this is not ideal and not always suitable for all strategies as generally speaking talking when it comes to trading simple is better but depending on the system sometimes simple means you get a ton of signals so other than increasing the set of conditions required to generate a trading signal my two favorite methods are to introduce signal ranking into the system so for example you might take the rate of change as a percentage over the past 100 bars and only take the top 10 trades ranked by that metric so if your system generates a hundred trades you only take the 10 that had the highest rate of change over the past 100 bars or in other words the strongest trending stocks over that sample size doesn't necessarily mean that the trades are more likely to win but it does reduce the subjectivity the discretion involved in which trades to actually execute and then your real-time results will be closer to the metrics discovered through your back testing this method is appropriate and quite powerful for systems where you can actually choose which trades to enter so trades where you enter on the next bars open for example instead of using a limit order but for today's system it's not really appropriate because we don't know ahead of time which limit orders are going to get filled on any given day so an alternative ranking method might be to only place 10 or 20 limit orders based on a ranking system and how you want to distribute your Capital over those 10 or 20 trades and whether you're using margin leverage or not and then if some of those 10 or 20 limit orders get filled that's great if some don't then you just skip those trades the negative side effect of this approach is that you might significantly reduce your trading opportunities and exposure which will result in probably slower Equity gains but the benefit is that you almost entirely eliminate selection bias and your real-time trading results should be much closer to the metrics discovered through your historical back testing process anyway there are a ton of methods for reducing the damage caused by selection bias but we'll cover them in a future videos I could speak on this subject alone for an hour easily and we haven't even mentioned the plethora of other devices that can pop up When developing systematic strategies like this one that we made today but anyway I've kept you and rambled long enough I'll wrap up this video here thanks for watching as always I hope you found it interesting and I hope it inspires some ideas for you to go out and test yourself please in the comments section let me know your thoughts on the system let me know what changes you would make to it if it reminds you of any existing systems as Traders we often get excited that we've discovered some magic system and then you find out that it was written down in a book 10 20 years ago and you're basically Reinventing the wheel or stealing someone else's idea without realizing it that's a problem with music as well by the way I used to write songs years ago and get all excited that I'd found this awesome Melody and then realize a couple days later that I just ripped off a song that was in my subconscious or something but anyway thanks for watching good luck with your trading as always if you want to learn more about Pine script or steal my best code go to panscriptmastery.com you can find my courses there including a course where I give the source code to every script I've ever created including several trading systems that I used to trade the Forex crypto and stock markets profitably with all that said I will see you in the next video take care and have a great weekend [Music]

No comments:

Post a Comment