Scripting Tutorial 2 - Triple Exponential Moving AveragesThis script is for a triple exponential moving average indicator. It is meant as an educational script with well formatted styling, and references for specific functions.
Tutorial
Scripting Tutorial 1 - Simple Moving AverageThis script is for a simple moving average indicator. It is meant as an educational script with well formatted styling, and references for specific functions.
How To Use Dynamic ZonesExample of how to apply and use Dynamic Zones with an indicator by injecting it's source into my adaptation of the original idea by Leo Zamansky, Ph.D., and David Stendahl.
• Load your desired oscillating indicator on your chart (CCI, RSI, etc).
• Load my "How To Use Dynamic Zones" indicator on your chart.
• In the "How To Use Dynamic Zones" indicator settings choose your desired oscillating indicator as the Oscillator Source.
You will now have dynamic overbought and oversold levels. I have also included alerts which may be used to indicate when these conditions occur.
If desired you may repeat the above process by loading additional indicators along with additional copies of my indicator to use with each oscillator.
Oscillator Source: CLOSE uses your chosen indicator as a source or you may use price as a source
Sample Length: 70 uses number of previous values for evaluating
Hi is Above X% of Sample: 88 sets overbought zone
Lo is Below X% of Sample: 88 sets oversold zone
The simplest explanation of what these default settings are doing is that they take 70 previous values of your chosen indicator, then create an overbought level that is above 88% of those previous values and an oversold level that is below 88% of those previous values. As new bars form the levels are dynamically reevaluated and updated.
---
"This investing style follows a very simple form of logic: Enter the market only when an oscillator has moved far above or below traditional trading levels. However, these oscillator driven systems lack the ability to evolve with the market because they use fixed buy and sell zones. Traders typically use one set of buy and sell zones for a bull market and substantially different zones for a bear market. And therein lies the problem.
Once traders begin introducing their market opinions into trading equations, by changing the zones, they negate the system’s mechanical nature. The objective is to have a system automatically define its own buy and sell zones and thereby profitably trade in any market — bull or bear. Dynamic zones offer a solution to the problem of fixed buy and sell zones for any oscillator-driven system."
Reference: Stocks & Commodities V15:7 (306-310): Dynamic Zones by Leo Zamansky, Ph.D., and David Stendahl
---
NOTICE: This is an example script and not meant to be used as an actual strategy. By using this script or any portion thereof, you acknowledge that you have read and understood that this is for research purposes only and I am not responsible for any financial losses you may incur by using this script!
Security() Correction - Realtime vs. Historical BarsProblem
Pine's implementation of the security() function behaves differently in realtime vs. historical bars. Specifically, for historical bars, calling security() for a time frame (TF) larger/slower than the current chart's TF will return information about the last completed bar of the higher TF. However, for realtime bars (i.e. if you allow the chart to continue to plot in realtime), security() returns information about the presently in-progress bar of the higher TF. Clearly, this leads to discontinuity that is arbitrarily dependent upon when the user last loaded or refreshed the chart.
Solution
Fortunately, after understanding the problem, solving it is trivial: use security() normally for historical bars, but switch to explicitly requesting prior candle bars once the indicator is operating on realtime bars. I leave the source open here for any to use as they see fit. For testing, I include an input to allow switching back and forth between standard and corrected behavior.
Figure 1 displays the standard behavior we see in security() calls, and Figure 2 displays the behavior after my correction:
Figure 1: Typical security() behavior in Pine
Figure 2: Corrected security() behavior, forcing historical and realtime bars to refer to the same higher TF bar offset.
I publish this mostly as a reminder to myself, so I will not forget and then have to figure it out again next time it comes up in my scripting.
V21: Initial release.
TRADING VIEW INDICATOR - PINE TUTORIAL 5After a long gap, I have written the 5th tutorial for the pine script. You can find the others below, if you read through all of these you should be good to do your own writing.
This script mimics the Trading View Indicator . For example this one below.
www.tradingview.com
It shows the net result of the 28 indicator, either as buy or sell. I have worked hard to make sure it matches the trading view results but I am not in hundred percent agreement with tradingView on SMA, EMA and Ichimoku indicator.
There are many commented plots because I needed to check separately if each indicator is working correctly.
Someone else wrote this code but they did not make it public. It took me about 3 weeks to write this and to be honest it could be cleaner and better commented.
If you find any mistake please let me know. I hope it will be useful in your learning.
META: Kahan Summation (Scripting Exercise)I was curious to see what Pine uses to accumulate numbers. It looks like it uses the simple "add em up" approach, rather than a compensated summation. This means that especially for large numbers, there is an inherent error amount.
This script implements the Kahan Summation Algorithm, also known as compensated summation.
en.wikipedia.org
This is part 2 of my study into the builtin stdev function. I think this is why it differs so much from the simple two-pass solution.
META: STDEV Study (Scripting Exercise)While trying to figure out how to make the STDEV function use an exponential moving average instead of simple moving average , I discovered the builtin function doesn't really use either.
Check it out, it's amazing how different the two-pass algorithm is from the builtin!
Eventually I reverse-engineered and discovered that STDEV uses the Naiive algorithm and doesn't apply "Bessel's Correction". K can be 0, it doesn't seem to change the data although having it included should make it a little more precise.
en.wikipedia.org
Pine Script Tutorial #2In this second tutorial we build upon the previous tutorial. We add color shading for each different day and highlight Wednesday.
The idea here is to manually count if on Wednesdays close is bigger then open.
Hope it helps.
Feel free to comment.
MartinMystere
My Tutorial #1If you are just like me and cant just get your head around pine script, I have created this simple code so you get the main concept.
Unfortunately there are no good step by step tutorials out there teaching scripting.
Hope this helps.
Comments are welcome.
MatinMystere
Back to zero: Understanding seriestype: pine series basic example
time required: 10 minutes
level: medium (need to know the "array" data variable as a generic programming concept, basic Pine syntax)
tl;dr how variables and series work in Pine
Pine is an array/vector language. That's something that twists how it behaves, and how we have to think about it. A lot of misunderstandings come from forgetting this fact. This example tries to clear that concept.
First, you need to know what an array is, and how it works in a programmig language. Also, having javascript under your belt helps too. If you don't, google "javascript array basic tutorial" is your friend :)
So, in pine arrays are called "series". Every variable is an array with values for each candle in the chart. if we do:
myVar = true
this is not a constant. It is a series of values for each candle, { true, true,....., true }
In practice, the result is the same, but we can access each of the values in the series, like myVar{0}, myVar{7}, myVar{anyNumber}....
Again, it is not a constant, since you can access/modify the each value individually
so, lets show it:
plot (myVar, clolor = gray)
this plots an horizontal line of value 1 ( 1 is equal to true ) so it's all good.
On to a more usual series:
tipicalSeries = close > open ? true : false
plot(tipicalSeries, color= blue)
This gives the expected result, a tipical up and down line with values at 1 or 0. Naturally, "tipicalSeries" is an array, the "ups" and "downs" are all stored under the same variable, indexed by the candles.
In Pine, the ZERO position in the array is the last one, which corresponds to the last candle on the right. Say you have a chart with 12 candles. The close would be the closing value of what we intuitively think as first candle, the one on the left. then close ... and so on.... until close , the value of the "last" candle, the one on the right. It actually helps to start thinking of the positions backwards, counting down to zero, rocket launch style :)
And back to our series. The myVar will also be the same size, from myVar to myVar .
When we do some operation with them, something simple like
if ( myVar == tipicalSeries)
what is really happening is that internally, Pine is checking each of the indexes, as in myVar == tipicalSeries , myVar == tipicalSeries .... myVar == tipicalSeries
And we can store that stuff to check it. simply:
result = (myVar == tipicalSeries) ? true : false //yes, this is the same as tipicalSeries, but we're not in a boolean logic tut ;)
plot (result)
The reason we can plot the result is that it is an array, not a single value. The example indicator i provide shows a plot where the values are obtained from different places in the array, this line here:
mySeries3 = mySeries2 and mySeries1
this creates a series that is the result of the PREVIOUS values stored (the zero index is the one most at the right, or the "current" one), which here just causes a shift in the plotted line by one candle.
Go ahead, grab a copy of my code, try to change the indexes and see the results. Understanding this stuff is critical to go deeper into Pine :)