Algorithmic vs. Quantitative Trading: Which Path Should You TakeI’ve always wondered why anyone would stick to traditional trading methods when algorithms and mathematical models could do all the heavy lifting.
I started questioning everything:
• Why do so many mentors still swear by discretionary trading when algorithms could handle all the heavy lifting?
• Do they really have solid proof of their “own” success, or is it just talk?
• Or are they keeping things complex and discretionary on purpose, to confuse people and keep them as members longer?
• Why deal with the stress of emotions and decisions when an algorithm can take care of it all?
• Imagine how much further ahead you could be if you stopped wasting time on manual trades and instead focused on market research and developing your own models.
When I first got into trading, I thought Algorithmic Trading and Quantitative Trading were basically the same thing. But as I dug deeper, I realized they’re two completely different worlds.
Algorithmic Trading: It’s simple – you set the rules and the algorithm executes the trades. No more sitting in front of the screen “controlling your emotions” and trying to manage every little detail. Instead, you let the algorithm handle it, based on the rules you’ve set. It frees up your time to focus on other things rather than staring at price charts all day.
But here’s the thing – it’s not perfect. You’ll still need to test the rules to make sure the data and results you’re getting aren’t overfitted or just random.
Quantitative Trading: A whole different level. It’s not just about executing trades; it’s about understanding the data and math behind market movements. You analyze historical price, economic, and political data, using math and machine learning to predict the future. But it can be complex – techniques like Deep Learning can turn it into a serious challenge.
The upside? This is the most reliable way to trade, and it’s exactly what over 80% of hedge funds do. They rely on quant models to minimize risk and to outperform the market.
So, which path should you choose?
Quantitative Trading can feel overwhelming at first, I recommend starting with the basics. Begin with Pine Script coding in TradingView—start building a foundation with simple strategies and indicators. As you grow more confident, start coding your own ideas into rules and refining your approach to eventually automated your trading strategy.
TradingView is a great tool for this, and I’d highly suggest grabbing the Premium plan. This will give you access to more data and features to make your learning journey smoother.
Dive into the Pine Script documentation , and begin bringing your ideas to life.
I promise, the more you focus on this, the better and more independent you’ll become in trading.
Every day, aim to get just 1% better.
To Your success,
Moein
Pinescript
Big Runner - Running'Big Runner' - This pine script strategy is available in my scripts section and is fully open source, here it is performing algorithmic trades on SPX 4hour timeframe.
This strategy works seamlessly with any instrument, showing visuals on the chart for moving averages and ribbons to execute Long and Short trades.
I'm working to update it's script to further improve its use case.
Use modern tools to automate your trading.My partner @Mayfair_Ventures and I like innovation, but we have been sceptical of bot-driven trading. This if for one simple reason. If it was available and consistently profitable, then someone would be doing it, then others would find out, then everyone would be doing it. No one would need a job.
If you know about chaos theory, then you'll recognise trading as one example of where it fits. Chaotic things are inherently extremely hard to predict, as a rule. The best we can do is predict small amounts, like what the weather may do this afternoon. What it's going to do in 5 days' time is exponentially harder.
Let's stick to the "we can predict this afternoon" model. At this level I think bots can be useful, and recently we've been looking at short-term trading on the 1 minute time-frame (Even though we don't recommend it) because people always ask us about it.
There are a couple of streams here..
www.tradingview.com
www.tradingview.com
Now to automation. We started to mess around with @TradingView indicators and web hooks first. Web hooks allow you to propagate alerts from TradingView to an outside platform, like your phone, or email, whatever. Best of all, you can do it from your custom indicators as well.
Then we thought: "how about just letting our indicator do the trade, so we can carry on with our round of golf"? As long as the timing is right, in other words, if we were at the screen we would take the trade, this makes sense. We can make our indicator only send signals at certain times of day, or whatever other thing we can think of.
There are a few programs that will do this. I had a look at one from 3Commas. Others exist but I haven't looked at them yet. It takes the signal just like your phone does.
You need to add your exchange (I use Binance) to it.
I write 2 bots using simple templates they supply. One to go long, one to exit the long. You don't need an stop loss because it knows your max risk and does it for you.
I set alerts based on my indicator (yes you have to get ChatGPT to make an indicator for you or write one!), not a price, so when my indicator is hit, the alerts fire and whichever bot is connected to the alert bot does a trade.
That's it. I am playing about with it on a demo account first, because I am not an idiot.
Yes it's true, ChatGPT can write Pinescript. It gets it wrong sometimes, but just tell it and it tries to fix it.
Thinking in Pine - Functions Containing Var VariablesHello everyone, welcome back to "Thinking in Pine" short video tutorials. In this video, we have discussed special cases of using var variables inside function definitions.
If you are not familiar with var variables, please take a step back and watch our earlier video - "Thinking in Pine - var, varip and regular variables"
🎲 Summary
Using var within a function scope and how it behaves with multiple invocations.
Using the functions containing var variable definitions within a loop.
🎯 Example Program Used
increment()=>
var i = 0
i+=1
var1 = increment()
var2 = increment()
var3 = increment()
// The code above is equivalent to
// var i1 = 0
// i1+=1
// var1 = i1
// var i2 = 0
// i2+=1
// var2 = i2
// var i3 = 0
// i3+=1
// var3 = i3
plot(var1, "Counter 1", color=color.blue)
plot(var2, "Counter 2", color=color.red)
plot(var3, "Counter 3", color=color.purple)
arr = array.from(var1, var2, var3)
for i=1 to 3
arr.push(increment())
// The code above is equivalent to
// var i4 = 0
// i4+=1
// arr.push(i4)
if(bar_index == 4)
log.info('Value of array containing incremental values : {0}', arr)
🎲 References
Pine Script® User Manual - Variable declarations
Pine Script® Reference Manual - var
Thinking in Pine - Time Series Special CasesHello Everyone,
Welcome back to "Thinking in Pine" short video series. In this session, we have discussed few special cases of time series variables and using historical operator within local scope.
If you have not watched our previous video - "Thinking in Pine - Time Series" , request you to do that before continuing this video.
🎲 Summary of our today's discussion
How historical operator works for variables defined inside an conditional block
How historical operator works for variables defined in a loop.
🎯 Example Program Used
// Time series for variables within a condition
varip showLogInLoop = true
if(bar_index%3 == 0)
specialBarIndex = bar_index
if(bar_index > last_bar_index-3 and showLogInLoop)
log.info('Current and Previous special bar index are : {0} and {1}', specialBarIndex, specialBarIndex )
showLogInLoop := false
// Time series of variables within a loop
arrayOfX = array.new()
arrayOfLastX = array.new()
for i = 1 to 5
x = i*10
arrayOfX.push(x)
arrayOfLastX.push(x )
if(barstate.islastconfirmedhistory)
log.info('Array of X : {0}', arrayOfX)
log.info('Array of last X : {0}', arrayOfLastX)
🎲 References:
Pine Script® User Manual - Execution Model
Pine Script® User Manual - Time Series
Pine Script® User Manual - History Referencing Operator
Pine Script® Reference Manual - History Referencing Operator
Thinking in Pine - Time SeriesHello everyone,
Welcome back to "Thinking in Pine" short video series. In this video, we discuss the concept of time series variables in Pinescript.
If you are not familiar with var and varip type of variables - please step back and watch this video before continuing - "Thinking in Pine - var, varip and regular variables"
🎲 Summary of our discussion is as follows
What are time series variables, and how are they used in Pinescript?
How do we access historical values of time series?
Limitations of accessing historical values
🎯 Example Program Used
currentBar = bar_index
var currentBarUsingVar = 0
currentBarUsingVar := bar_index
varip showLog = true
valueAt200thBar = ta.valuewhen(bar_index == 500, currentBar, 0)
if(barstate.islast and showLog)
log.info("Current Bar Values using regular and var variables : {0}, {1}", currentBar, currentBarUsingVar)
log.info("Last Bar Values using regular and var variables : {0}, {1}", currentBar , currentBarUsingVar )
log.info("Values 500 bars ago using regular and var variables : {0}, {1}", currentBar , currentBarUsingVar )
offset = bar_index-25000
log.info("Values at 25000th bar using regular and var variables : {0}, {1}", currentBar , currentBarUsingVar )
showLog := false
plot(bar_index, "Bar Index", color = color.blue, display = display.data_window)
There are pitfalls of using historical operators within loop or under if condition. We will discuss that in our next video.
🎲 References:
Pine Script® User Manual - Execution Model
Pine Script® User Manual - Time Series
Pine Script® User Manual - History Referencing Operator
]Pine Script® Reference Manual - History Referencing Operator
Thinking in Pine - var, varip and regular variablesThis is our first video session on "Thinking in Pine" series. Before we start, we want to explain a bit about our new initiative.
🎲 What is "Thinking in Pine"?
In our journey to empower the trading community, we're excited to introduce "Thinking in Pine," a series of concise, 5-10 minute videos dedicated to unraveling the complexities of Pine Script®. We have our own list of topics to be covered, and we will start releasing the videos one by one. However, if you're grappling with any aspect of Pine Script® or stuck on an implementation, we encourage you to reach out to us or drop a comment here. We aim to address your queries by breaking down challenging concepts or implementations into easily digestible content.
What kind of videos are covered in "Thinking in Pine"?
Pine Script® Focus: We try to keep our focus on Pine Script® concepts and implementations.
General Utility: We prioritize topics that offer broader learning value. Though it's challenging to quantify this, we'll use our judgment to select topics that benefit the wider audience.
Time-Efficient Demonstrations: Ideally, we want to keep our demonstrations to 5–10 mins of time.
We're here to demystify Pine Script®, one topic at a time, making it accessible for everyone from beginners to advanced users. Stay tuned for insightful sessions with "Thinking in Pine"!
🎲 Demonstrating var, varip and regular variables in Pine Script®
In this video, we have demonstrated the difference between var, varip and regular variables by using an example implementation of OBV indicator.
🎯 Logic of OBV Calculation
Start with the value 0
On each bar, add volume to the indicator if close price is higher than previous bar close price.
On each bar, remove volume from the indicator is close price is lesser than previous bar close price
🎯 Highlights
Regular variables are initialized separately on each bar and does not propagate value to next bar unless coded to do it.
var variables are initialized once and then can be reassigned any number of times using := operator . The variables declared as var will propagate the current values to the next bar.
varip variables are initialized once and then can be reassigned any number of times using := operator . varip will behave similar to var on historical bars. However, on real time bars, they are recalculated on every tick, and they remember the state of each tick.
🎯 Example Program Used
Here is the example program used in the demonstration.
//Plot built-in OBV value for reference
plot(ta.obv, "OBV Built In", color=color.yellow)
//Volume multiplied by +-1 based on change in close price compared to previous bar.
volumeBySign = math.sign(nz(ta.change(close), 0))*volume
//Obv calculation by using regular variable. Code need to access and add last bar value using obvByRegular
obvByRegular = 0.0
obvByRegular += nz(obvByRegular , 0) + volumeBySign
plot(obvByRegular, "OBV By Regular Variable", color=color.blue)
//Obv calculation using var variable. Since var variables propagate values to next bar,
// we do not need to use historical operator to get the last bar value
var obvByVar = 0.0
obvByVar += volumeBySign
plot(obvByVar, "OBV by var Variable", color = color.maroon)
//Obv implementation using varip. The OBV is calculated based on every tick. Histoical values will match the same as that of other implementation.
//However, in real time, the calculations are done based on the tick values
varip obvByVarip = 0.0
varip lastPrice = close
varip lastVolume = volume
if(barstate.isnew)
lastVolume := 0
obvByVarip += math.sign(close-lastPrice)*(volume-lastVolume)
lastPrice := close
lastVolume := volume
plot(obvByVarip, "OBV by varip Variable", color = color.purple)
🎲 References:
Pine Script® User Manual - Variable declarations
Pine Script® Reference Manual - var
Pine Script® Reference Manual - varip
Pine Script® User Manual - Operators
3 Must-haves for Top TradersStats published by exchanges clearly show that 80% of traders lose money. So the inquiry is not “how to get into the top 20%?” Who wants to settle for mere profitability? The inquiry becomes “how do I get into the upper 3% of traders?” - The “fly around in private jets” and “build whole schools in Africa” traders?
The answer is simple. Stop being human. It’s our human emotions that trip us up every time. We close winning trades too early (take the money and run) and hang onto losing trades too long (pray for a miracle).
Top traders (the ones with private jets) have one thing in common. They all know how to code. And they automate their trading to take the human element out of it. So here’s your quick list of must-haves skills and tools to invest in. Your best investments to get you into the upper 3%. The journey from staring at your computer doing live Technical Analysis to sitting on the beach while your bot trades for you.
Get Tradingview Premium. If you’re serious about making money, you need the ability to back-test. The deep-backtester that comes with a premium level account is going to give you the accurate results you need. Trading code that hasn’t been properly back-tested and optimized is a game of russian roulette. The money you make from trading well tested strategies will pay for this investment ten-fold. Which brings me to my third and final point, optimization.
Master Pine Script. Shout-out here to Matt Slabosz who developed Pine Script Mastery - an excellent overview course for beginners. Matt is not only a solid trader and exceptional coder, his true brilliance is being able to explain complex coding concepts in simple terms. Given that the last time I’d coded was punching fortran cards in University, taking his course was a pleasant surprise in how easy and addictive learning to code Pine Script can be.
Optimize your strategy. There are solid strategies published on tradingview that look unprofitable at first glance. That’s simply a matter of knowing the correct settings for the derivative and market conditions you’re trading. So you have two choices.
Sit at your computer all night and run scenarios on the deep back-tester, or
Buy an optimization tool that will run scenarios while you sleep.
Being way past the age where I’m willing to give up my sleep, the answer, for me, is a no-brainer. TradingTools.software is my top pick for optimizing your TradingView strategy. It allows you to pinpoint the weak areas of your strategy down to the window of where the biggest losses are occuring. This information is pure gold to creating strategies to filter against market conditions where your automated strategy would otherwise fail.
Learning the skills and buying the tools you need is critical to mastering any profession. Trading is no different.
Manage Input variables with Pine Script v5Welcome to this new tutorial that helps traders and investors better understand the powerful Pine Script programming language v5.
In this tutorial, we will program together three Input variables:
Color type Input: a color input is a parameter that allows specifying a custom color for the indicator or script. It can be used to set the color of lines, areas, texts, or other graphical components in the indicator.
Float type Input: a float input is a parameter that allows specifying a floating-point numerical value for the indicator or script. It can be used to set parameters such as threshold levels, indicator sizes, or any other numerical value that requires decimal precision.
Integer type Input: an integer input is a parameter that allows specifying an integer numerical value for the indicator or script. It can be used to set parameters such as moving average periods, length of a time interval, or any other integer numerical value.
IMPORTANT: The code used in this tutorial has been created purely for educational purposes.
Our indicator is a simple indicator that plots the close data of the underlying asset on the chart in a weighted manner. The displayed data is the sum of the close price plus 20%. The goal of the indicator is to provide a fully dynamic tool that can vary its parameters from the user interface and update automatically.
Here is the complete code for this tutorial:
//@version=5
indicator("Input Tutorial", overlay = false)
pond = input.float(defval = 0.20, title = "Float", minval = 0.10, maxval = 1, step = 0.10)
color_indicator = input.color(defval = color.red, title = "Color")
data = close + (close * pond)
linewidth_feature = input.int(defval = 1, title = "Integer", minval = 1, maxval = 10, step = 1)
plot(close, color = color_indicator, linewidth = linewidth_feature)
//@version=5
Indicates the version of the Pine Script language used in the code.
indicator("Input Tutorial", overlay = false)
Set the name of the indicator as "Input Tutorial", and overlay=false indicates that the indicator should not overlap the main chart.
pond = input.float(defval = 0.20, title = "Float", minval = 0.10, maxval = 1, step = 0.10)
Create a float input called "pond" with a default value of 0.20. The input title is "Float", and the minimum value is 0.10, the maximum value is 1, and the step is 0.10.
color_indicator = input.color(defval = color.red, title = "Color")
Create a color input called "color_indicator" with a default value of red color. The input title is "Color".
data = close + (close * pond)
Calculate a new value "data" by adding the closing price value with the closing price multiplied by the "pond" input.
linewidth_feature = input.int(defval = 1, title = "Integer", minval = 1, maxval = 10, step = 1)
Create an integer input called "linewidth_feature" with a default value of 1. The input title is "Integer", and the minimum value is 1, the maximum value is 10, and the step is 1.
plot(close, color = color_indicator, linewidth = linewidth_feature)
Plot the chart of the closing value with the color specified by the "color_indicator" input and the line width specified by the "linewidth_feature" input.
Next Steps: Introduction to Pine ScriptWelcome back, traders! In our previous video, we took our first steps into Pine Script™ and learned about creating indicators. Today, we're going to dive deeper into the Pine Script™ landscape and provide some valuable pointers to guide you on your journey of mastering Pine Script™. So let's get started!
The first important distinction we need to make is between "indicators" and "strategies" in Pine Script™. Indicators are primarily used for calculations and displaying information on charts. They are lightweight and don't require the broker emulator, making them faster to execute. You can use indicators to analyze market data and generate visual representations of technical analysis tools, such as moving averages, oscillators, and custom calculations. Indicators are a great choice when you don't need to backtest your strategies.
On the other hand, strategies are used for backtesting and forward testing. They include trade order functionality and can simulate trade executions. With strategies, you can define entry and exit conditions, apply risk management rules, and evaluate the performance of your trading ideas. Strategies provide detailed backtest results in the "Strategy Tester" tab, located next to the "Pine Script™ Editor" tab. They allow you to assess the historical performance of your trading strategy before deploying it in live markets.
Now, let's talk about how scripts are executed in Pine Script™. Unlike traditional programming languages, Pine Script™ runs in a loop-like fashion, executing once on each bar of the chart from left to right. Historical bars refer to those that have already closed when the script executes on them, while the last bar, known as the realtime bar, remains open. The script then executes whenever a price or volume change is detected and once again when the realtime bar closes. This execution model enables real-time monitoring of market conditions and the opportunity to react to price and volume movements.
It's important to note that the script doesn't recalculate on historical bars during realtime execution. This optimization improves efficiency by avoiding unnecessary calculations on past data that have already been processed. Pine Script™ provides this performance enhancement by storing the calculated values of historical bars, allowing the script to focus on updating the current and future bars efficiently.
In Pine Script™, a fundamental concept is the time series. Time series are data structures that hold values for each bar the script executes on. They continuously expand as the script progresses through more bars. By using the history-referencing operator, which is denoted by square brackets , you can access past values of a time series. For example, close refers to the close value on the preceding bar, close refers to the close value two bars ago, and so on. This powerful feature allows you to incorporate historical data into your calculations and create complex trading algorithms.
It's crucial to understand the time series and how they differ from traditional arrays. While the indexing mechanism may resemble arrays, thinking in terms of arrays can be detrimental to understanding this key Pine Script™ concept. Time series in Pine Script™ expand dynamically with each bar, and their values are automatically updated as new data becomes available. This dynamic nature enables you to create adaptive and responsive trading strategies that take into account changing market conditions.
Moving on, let's discuss script publishing. TradingView is a vibrant community of Pine Script™ programmers and traders from around the world. Once you become proficient in Pine Script™, you have the option to share your scripts with others. Before publishing, ensure your scripts are original and well-documented. All publicly published scripts undergo analysis by TradingView's moderators and must comply with Script Publishing Rules. These rules maintain the quality and integrity of the scripts available on the platform.
If you prefer to use your Pine scripts for personal use, you can simply write them in the Pine Script™ Editor and add them to your charts without publishing them. However, if you want to share your scripts with a select group of individuals, you can publish them privately and provide your friends with the browser link to your private publication. This way, you can collaborate with others and receive valuable feedback on your scripts.
To navigate the Pine Script™ documentation effectively, it's essential to spend time exploring the available resources. Our main documentation sources are the Pine Script™ v5 User Manual and the Pine Script™ v5 Reference Manual. The User Manual provides comprehensive explanations and examples to help you grasp the fundamentals of Pine Script™. The Reference Manual serves as a detailed reference guide, documenting the functions, variables, and keywords available in Pine Script™. It's a valuable tool for every Pine Script™ programmer and is essential for writing scripts of reasonable complexity.
Remember to consult the documentation corresponding to the version of Pine Script™ you are working with. It's crucial to stay up to date with the latest advancements and improvements in Pine Script™ by regularly checking the Release Notes.
That wraps up our introduction to Pine Script™ and its landscape. We hope you found these insights helpful in your journey to become a proficient Pine Script™ programmer and trader. Remember to practice, explore, and experiment with the concepts we discussed today. By combining time series with the built-in functions designed to handle them efficiently, you'll be amazed at what you can accomplish with just a few lines of Pine Script™ code.
Thank you for joining us today, and we wish you success in mastering Pine Script™ and achieving your trading goals!
Making Your First Indicator: Introduction to Pine Script Welcome back, traders! In today's video, we'll explore the powerful features of the Pine Script™ Editor, where we'll be working on our scripts. This editor offers a range of advantages that make our coding experience more efficient and enjoyable.
The Pine Script™ Editor is specially designed for writing Pine scripts, and it brings several benefits to the table. First, it highlights your code according to Pine Script™ syntax, making it easier to read and identify any errors. Additionally, it provides syntax reminders for built-in and library functions when you hover over them, helping you navigate the language effectively.
Furthermore, the Pine Script™ Editor offers quick access to the Pine Script™ v5 Reference Manual. Just Ctrl+Click (Cmd+Click on Mac) on a Pine Script™ keyword, and a handy popup with relevant information will appear. This allows you to explore the documentation without leaving the editor.
To speed up your coding process, the editor provides an auto-complete feature. Just press Ctrl+Space (Cmd+Space on Mac), and it will suggest code completions based on what you're typing, saving you time and reducing errors. These features combined make coding in Pine Script™ a breeze!
While not as feature-rich as some top editors out there, the Pine Script™ Editor still offers essential functionalities such as search and replace, multi-cursor support, and versioning. It's a reliable tool for writing and managing your Pine scripts effectively.
Now, let's dive into the practical aspect of using the Pine Script™ Editor. To open it, click on the "Pine Script™ Editor" tab at the bottom of your TradingView chart. This will bring up the editor's pane, ready for you to start coding.
For our demonstration, we'll create our first working Pine script, an implementation of the MACD indicator. Let's walk through the steps together:
Click on the "Open" dropdown menu at the top right of the editor.
Select "New blank indicator" to start from scratch.
Replace the existing code in the editor with the example script you see pasted here on my screen.
Click "Save" and give your script a name. It will be saved in your TradingView cloud account.
Finally, click "Add to Chart" in the editor's menu bar to see the MACD indicator in a separate pane below your chart.
Great job! Your first very own Pine script is running on your chart, and the MACD indicator is now displayed on your screen. Keep an eye on those blue and orange lines representing the MACD and signal values, respectively.
Now, let's level up our script by using built-in Pine Script™ functions. The second version of our script will showcase the ta.macd() function, specifically designed for calculating the MACD indicator.
To create the second version of our script, follow these steps:
Open the "New blank indicator" option from the "Open" dropdown menu.
Replace the existing code in the editor with the example script you see pasted here on my screen.
Save the script with a different name.
Click "Add to Chart" to see the updated "MACD #2" indicator in a separate pane.
Well done! In this version, we introduced inputs to allow us to change the lengths of the moving averages. By using the ta.macd() built-in function, we simplified the code and made it more readable.
With the second version of our script, we have improved our code and made it more flexible. Now, we can easily adjust the lengths of the moving averages, tailoring the indicator to our needs.
That's a wrap for this video, traders! We've explored the Pine Script™ Editor, created our first two versions of the MACD indicator, and learned valuable coding techniques. Stay tuned for the next episode, where we'll continue enhancing our indicators and strategies with Pine Script™. If you have any questions or ideas for future episodes, feel free to reach out to me. Until next time!
First Steps: Introduction to Pine Script Welcome back, fellow traders, to another exciting episode of our Pine Script™ journey! In our previous video, we explored how to use existing scripts and indicators on TradingView. Today, we'll take the next step and dive into the fascinating world of reading and writing Pine Script™.
In this episode, we'll focus on the fundamental aspects of reading Pine Script™ code and understanding its structure. By studying the code written by talented programmers, we can gain valuable insights and improve our own understanding of the language.
Reading code written by proficient programmers is the most effective way to enhance your knowledge of any programming language, and Pine Script™ is no exception. Luckily, there are numerous reliable sources for high-quality code on TradingView.
To start, you can explore the built-in indicators provided by TradingView. These indicators serve as excellent examples of well-written code. Simply load an indicator on your chart and hover over its name to access the "Source code" icon. Clicking on this icon will open the Pine Script™ Editor, where you can view the indicator's code.
The Pine Script™ Editor allows you to explore and modify the code. If you want to experiment with a specific indicator, you can make a copy of the code by selecting "Make a copy" from the "More" menu. This way, you can freely modify and save your changes without affecting the original indicator.
Another fantastic resource for reading code is the vast collection of Community Scripts on TradingView. These scripts, created by talented traders and programmers like yourself, offer a wealth of inspiration and knowledge. When browsing through Community Scripts, look for scripts without a gray or red "lock" icon, indicating that they are open-source.
Opening a script's page allows you to view its source code. By examining different scripts, you can gain insights into various trading strategies and techniques. This exposure to different coding styles will broaden your understanding of Pine Script™ and help you improve your own coding skills.
Now that we've explored reading code, it's time to unleash our creativity and start writing our own Pine Script™ scripts. Whether you're a beginner or an experienced programmer, Pine Script™ provides a user-friendly yet powerful platform for developing indicators, strategies, and even libraries.
Pine Script™ empowers us to write three types of scripts: indicators, strategies, and libraries. Indicators, like RSI and MACD, help us analyze market data. Strategies, on the other hand, include trading logic and can be backtested and forward-tested. Lastly, libraries enable advanced programmers to create reusable functions for other scripts.
I invite you all to embark on this exciting journey of writing your first indicator. With Pine Script™, we have a language that is both approachable for beginners and flexible enough for advanced traders. Let's unlock our creativity and develop trading tools tailored to our unique strategies.
Thank you for joining me today as we explored the art of reading and writing Pine Script™. Stay tuned for the next episode, where we'll dive deeper into writing indicators and unleash the full potential of this remarkable language. Until then, keep trading with passion and continue honing your coding skills!
Welcome: Introduction to Pine Script Video SeriesWelcome, fellow traders, to the exciting world of Pine Script™, TradingView's powerful programming language! I'm Stock Justice, and I'm here to guide you through the ins and outs of this incredible tool. So, buckle up and get ready to dive into the world of creating your own trading tools and strategies.
Before we delve into the magnificent content of the Pine Script™ v5 User Manual, let me explain what makes this language so significant. Pine Script™ empowers you to develop custom indicators and strategies, harnessing the full potential of TradingView's vast library of built-in tools. And guess what? Most of those tools were created using Pine Script™!
Pine Script™ is like a secret code that unlocks a world of possibilities. With its lightweight and user-friendly syntax, it's accessible to traders of all levels, whether you're a seasoned pro or just starting out. It's designed to make your trading journey easier and more efficient.
Now, you might be wondering, "What can I use Pine Script™ for?" Well, the answer is simple: anything you can dream of! From creating custom indicators that suit your unique trading style, to developing complex strategies and backtesting them to ensure their effectiveness, Pine Script™ is your key to unlocking untapped potential in the market.
But it doesn't stop there. Pine Script™ is not just a language; it's a vibrant community of passionate traders and programmers. With over 100,000 Community Scripts and counting, you have a wealth of resources at your fingertips. Collaborate, share, and learn from like-minded individuals who are eager to push the boundaries of what's possible.
My mission is to make Pine Script™ and its incredible capabilities accessible to the widest audience possible. That's why I'm embarking on this epic journey to create a comprehensive video explainer, piece by piece, using TradingView's screen recording feature. I'll break down the content of the Pine Script™ v5 User Manual into digestible segments, and together, we'll explore each topic step by step.
So, fellow traders, get ready to embrace your inner coder and revolutionize your trading experience. Join me on this educational adventure, where we'll uncover the power of Pine Script™ and transform the way we trade forever.
Welcome to the Pine Script™ revolution! Together, we'll conquer the markets, one line of code at a time. Stay tuned for the first exciting episode of our video series, where we'll dive deep into the fundamentals of Pine Script™. Until then, keep trading with passion and integrity!
3rd Pine Script Lesson: Open a command & send it to a Mizar BotWelcome back to our TradingView tutorial series! We have reached lesson number 3 where we will be learning how to open a command on TradingView and send it to a Mizar Bot.
If you're new here and missed the first two lessons, we highly recommend starting there as they provide a solid foundation for understanding the concepts we'll be covering today. In the first lesson, you will be learning how to create a Bollinger Band indicator using Pine Script:
In the second lesson, you will be guided through every step of coding the entry logic for your own Bollinger Band indicator using Pine Script:
In this brief tutorial, we'll walk you through the process of utilizing your custom indicator, Mikilap, to determine the ideal timing for sending a standard JSON command to a Mizar DCA bot. By the end of this lesson, you'll have the ability to fine-tune your trading strategies directly on Mizar using indicators from TradingView. So, sit back, grab a cup of coffee (or tea), and let's get started!
To establish a common starting point for everyone, please use the following code as a starting point. It incorporates the homework assignment from our Pine Script lesson number 2. By using this code as our foundation, we can collectively build upon it and delve into additional concepts together. So, sit back, grab a cup of coffee (or tea), and let's get started!
// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// Mizar Example Code - Lesson I - Coding an indicator
// version 1.0 - April 2023
// Intellectual property © Mizar.com
// Mizar-Killer-Long-Approach ("Mikilap")
//@version=5
// Indicator script initiation
indicator(title = "Mizar-Killer-Long-Approach", shorttitle = "Mikilap", overlay = true, max_labels_count = 300)
// Coin Pair with PREFIX
// Bitcoin / USDT on Binance as example / standard value on an 60 minutes = 1 hour timeframe
string symbol_full = input.symbol(defval = "BINANCE:BTCUSDT", title = "Select Pair:", group = "General")
string time_frame = input.string(defval = "60", title = "Timeframe:", tooltip = "Value in minutes, so 1 hour = 60", group = "General")
int length = input.int(defval = 21, title = "BB Length:", group = "Bollinger Band Setting")
src = input(defval = close, title="BB Source:", group = "Bollinger Band Setting")
float mult = input.float(defval = 2.0, title="BB Standard-Deviation:", group = "Bollinger Band Setting")
float lower_dev = input.float(defval = 0.1, title = "BB Lower Deviation in %:", group = "Bollinger Band Setting") / 100
int length_rsi = input.int(defval = 12, title = "RSI Length:", group = "RSI Setting")
src_rsi = input(defval = low, title="RSI Source;", group = "RSI Setting")
int rsi_min = input.int(defval = 25, title = "", inline = "RSI band", group = "RSI Setting")
int rsi_max = input.int(defval = 45, title = " < min RSI max > ", inline = "RSI band", group = "RSI Setting")
// Defintion of a Pine Script individual function to handle the Request and avoid Repainting Errors
Function_Mikilap(simple string coinpair, simple string tf_to_use) =>
int function_result = 0
bool barstate_info = barstate.isconfirmed
open_R, high_R, low_R, close_R = request.security(coinpair, tf_to_use, )
// Bollinger part of MIKILAP
src_cp = switch src
open => open_R
high => high_R
low => low_R
=> close_R
lower_band_cp = ta.sma(src_cp, length) - (mult * ta.stdev(src_cp, length))
lower_band_cp_devup = lower_band_cp + lower_band_cp * lower_dev
lower_band_cp_devdown = lower_band_cp - lower_band_cp * lower_dev
bool bb_entry = close_R < lower_band_cp_devup and close_R > lower_band_cp_devdown and barstate_info
// RSI part of MIKILAP
src_sb = switch src_rsi
open => open_R
high => high_R
low => low_R
=> close_R
rsi_val = ta.rsi(src_sb, length_rsi)
bool rsi_entry = rsi_min < rsi_val and rsi_max > rsi_val and barstate_info
// Check if all criteria are met
if bb_entry and rsi_entry
function_result += 1
if function_result == 1 and ticker.standard(syminfo.tickerid) == coinpair
label LE_arrow = label.new(x = bar_index, y = low_R, text = " 🢁 LE", yloc = yloc.belowbar, color = color.rgb(255,255,255,25),
style = label.style_none, textcolor = color.white, tooltip = str.tostring(open_R))
function_result
// Calling the Mikilap function to start the calculation
int indi_value = Function_Mikilap(symbol_full, time_frame)
color bg_color = indi_value ? color.rgb(180,180,180,75) : color.rgb(25, 25, 25, 100)
bgcolor(bg_color)
// Output on the chart
// plotting a band around the lower bandwith of a Bollinger Band for the active CoinPair on the chart
lower_bb = ta.sma(src, length) - (mult * ta.stdev(src, length))
lower_bb_devup = lower_bb + lower_bb * lower_dev
lower_bb_devdown = lower_bb - lower_bb * lower_dev
upper = plot(lower_bb_devup, "BB Dev UP", color=#faffaf)
lower = plot(lower_bb_devdown, "BB Dev DOWN", color=#faffaf)
fill(upper, lower, title = "BB Dev Background", color=color.rgb(245, 245, 80, 80))
Open a command to send to a Mizar Bot.
Let‘s continue coding
Our target: Use our own indicator: Mikilap, to define the timing to send a standard JSON command to a Mizar DCA bot.
(1) define the JSON command in a string, with variables for
- API key
- BOT id
- BASE asset (coin to trade)
(2) send the JSON command at the beginning of a new bar
(3) setup the TradingView alert to transport our JSON command via
Webhook/API to the Mizar DCA bot
Below you can see the code, which defines the individual strings to prepare the JSON command. In the following, we will explain line by line, what each individual string and command is used for.
// Defintion of a Pine Script individual function to handle the Request and avoid Repainting Errors
Function_Mikilap(simple string coinpair, simple string tf_to_use) =>
int function_result = 0
bool barstate_info = barstate.isconfirmed
open_R, high_R, low_R, close_R = request.security(coinpair, tf_to_use, )
//Text-strings for alerts via API / Webhook
string api_key = "top secret" // API key from MIZAR account
string symbol_prefix = str.replace(symbol_full, "BINANCE:", "", 0)
string symbol_name = str.replace(symbol_prefix, "USDT", "", 0)
string bot_id = "0000" // BOT id from MIZAR DCA bot
// String with JSON command as defined in format from MIZAR.COM
// BOT id, API key and the BASE asset are taken from separate variables
DCA bot identifier:
string api_key = "top secret"
string bot_id = "0000"
These both strings contain the info about your account (BOT owner) and the unique id of your bot, which should receive the JSON command.
BASE asset:
string symbol_prefix = str.replace(symbol_full, "BINANCE:", "", 0)
string symbol_name = str.replace(symbol_prefix, "USDT", "", 0)
The shortcut of the base asset will be taken out of the complete string for the coin pair by cutting out the CEX identifier and the quote asset.
JSON command for opening a position:
Entry_message = '{ "bot_id": "' + bot_id + '", "action": "' + "open-position" + '", "base_asset": "' + symbol_name + '", "quote_asset": "' + "USDT" + '", "api_key": "' + api_key + '" }'
If you want to have more info about all possible JSON commands for a DCA bot, please look into Mizar‘s docs: docs.mizar.com
As the JSON syntax requires quotation marks (“) as part of the command, we define the string for the entry message with single quotations ('). So please ensure to open and close these quotations before or after each operator (=, +, …).
Current status:
- We have the entry logic and show every possible entry on the chart => label.
- We have the JSON command ready in a combined string (Entry_message) including the BOT identifier (API key and BOT id) as well as the coin pair to buy.
What is missing?
- To send this message at the opening of a new bar as soon as the entry logic is true. As we know these moments already, because we are placing a label on the chart, we can use this condition for the label to send the message as well.
alert(): built-in function
- We recommend checking the syntax and parameters for alert() in the Pine Script Reference Manual. As we want to send only one opening command, we are using the alert.freq_once_per_bar. To prepare for more complex Pine Scripts, we have placed the alert() in a separate local scope of an if condition, which is not really needed in this script as of now.
if bb_entry and rsi_entry
function_result += 1
if function_result == 1
alert(Entry_message, alert.freq_once_per_bar)
if function_result == 1 and ticker.standard(syminfo.tickerid) == coinpair
label LE_arrow = label.new(x = bar_index, y = low_R, text = " 🢁 LE", yloc = yloc.belowbar, color = color.rgb(255,255,255,25),
style = label.style_none, textcolor = color.white, tooltip = str.tostring(open_R))
IMPORTANT REMARK:
Do not use this indicator for real trades! This example is for educational purposes only!
Configuration of the TradingView alert: on the top right of the chart screen, you will find the clock, which represents the alert section
a) click on the clock to open the alert section
b) click on the „+“ to create a new alert
c) set the condition to our indicator Mikilap and the menu will change its format (configuration of the TradingView alert)
For our script nothing else is to do (you may change the expiration date and alert name), except to add the Webhook address in the Notification tab.
Webhook URL: api.mizar.com
Congratulations on finishing the third lesson on TradingView - we hope you found it informative and engaging! You are now able to code a well-working easy Pine Script indicator, which will send signals and opening commands to your Mizar DCA bot.
We're committed to providing you with valuable insights and practical knowledge throughout this tutorial series. So, we'd love to hear from you! Please leave a comment below with your suggestions on what you'd like us to focus on in the next lesson.
Thanks for joining us on this learning journey, and we're excited to continue exploring TradingView with you!
HOW TO USE CHATGPT TO CODE PINESCRIPT (ACTUALLY) ChatGPT is an advanced language model that can help you write code more efficiently and accurately. By using ChatGPT, you can generate high-quality Pinescript code without the need for extensive coding knowledge or experience.
In this article, we will focus on using the free version of ChatGPT to code Pinescript indicators and strategies. We'll provide step-by-step instructions, highlighting potential issues you may encounter and how to resolve them. By the end of this article, you'll have the tools you need to leverage ChatGPT to create profitable trading strategies.
So, whether you're an experienced trader or just starting out, read on to discover how you can use ChatGPT to revolutionize your Pinescript coding, and even explore the other exciting possibilities it offers.
Things to know before we continue
💡ChatGPT can generate Pinescript code for both versions 4 and 5, but it's important to note that there are some differences between the two versions. It's recommended to specify which version you want your code written in before using ChatGPT. Additionally, it's worth noting that ChatGPT has more knowledge of Pinescript version 4, so you may want to consider having it write code in version 4 and then use the Tradingview editor to convert it to version 5.
💡It's true that ChatGPT can help you generate Pinescript code without extensive coding knowledge. However, for more complex scripts, it's recommended to have a basic understanding of Pinescript to make the most of ChatGPT. That way, you can better understand the generated code and make adjustments as needed.
💡ChatGPT is a tool that can help you improve your Pinescript coding, not a replacement for it. It's best to use ChatGPT to solve specific issues or come up with solutions for certain parts of your code rather than relying on it to write the entire code for you.
WHAT WE WILL BE CODING FOR OUR FIRST EXAMPLE.
🔸In our example, we will be coding an indicator that uses two moving averages with exposed periods to determine the direction of the market. Additionally, we will be using the stochastic RSI indicator as a momentum indicator to determine when to buy in an uptrend and when to sell in a downtrend. After we have created this script as an indicator, we will use ChatGPT to convert it to a strategy. This will enable us to backtest it using the Tradingview backtesting framework.
Lets begin.
1: The first thing we want to do is let CHatGPT know exactly what we want it to do. And have it come up with a solution to the issue. For our example we are going to type the following below.
Note how I specified the version of pinescript we will be coding in.
2: I am going to let ChatGPT know the description of the indicator we are going to code
🔸As you can see, ChatGPT provided me with Pinescript based on the information I provided. It is worth noting that, while this code worked for me, others may receive slightly different code due to the nature of ChatGPT's predictions. Additionally, ChatGPT explained the code in further detail in its response. Our next step is to test the code to determine whether it meets our requirements, and to note any issues we encounter. If there are any issues, we will provide them to ChatGPT for further assistance. To begin, I will copy and paste the generated code into the Pinescript editor without making any modifications, and attempt to add the script to the chart.
For reference here is the code provided by GPT below :
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=false)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Determine buy and sell signals based on Stochastic RSI
buySignal = trendUp and crossover(stoch, oversold)
sellSignal = trendDown and crossunder(stoch, overbought)
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
🔸The code had no syntax errors and met all the requirements specified in my prompt. The periods for the moving averages and the stochastic RSI were exposed, allowing them to be adjusted as needed. However, there is one issue that is not a result of ChatGPT, but rather caused by my failure to specify it in the prompt. The indicator is not being overlaid on the chart and is instead being displayed as an oscillator in a separate window below, similar to the RSI indicator. However, for our purposes, we want the indicator to be displayed over the candles themselves.
3: After testing the code and verifying that it meets my requirements, I will provide feedback to GPT that the code is functioning properly. However, I will also request that the indicator be displayed over the candles instead of in a separate window. It's important to communicate clearly with GPT to avoid any unnecessary changes to the code.
🔸Now we will test the code again.
Updated code listed below
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Determine buy and sell signals based on Stochastic RSI
buySignal = trendUp and crossover(stoch, oversold)
sellSignal = trendDown and crossunder(stoch, overbought)
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
🔸Great. Now the code is displaying as we would want it to as well!.
4: Now, let's make some improvements to the code. In addition to generating buy and sell signals, I would also like to see the moving averages displayed on the chart. This will allow me to visually understand why the signals are being generated.
Code reference below:
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Determine buy and sell signals based on Stochastic RSI
buySignal = trendUp and crossover(stoch, oversold)
sellSignal = trendDown and crossunder(stoch, overbought)
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
// Plot moving averages on chart
plot(ma1, color=color.blue)
plot(ma2, color=color.orange)
🔸Great! Now that we can see the moving averages, we have a better understanding of why the buy and sell signals are being generated. However, before we convert the indicator into a strategy, we need to make one final adjustment: reducing the number of signals being generated. There are various ways to achieve this such as using an ADX filter or a volatility filter. However, for this example, we will simply limit the number of signals generated for each cross of the moving averages to 1.
5: Final adjustments, During the tutorial, ChatGPT crashed, which can happen from time to time. If this happens, simply create a new chat session, copy the code from PineScript, and ask ChatGPT what the script does. Once ChatGPT advises you, you can ask it to act as an expert and help you make any necessary adjustments to the code in PineScript version 4.
🔸Here is when we started to have issues.
Here is my prompt and here is the code provided by ChatGPT
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Initialize buy and sell signals to false
var buySignal = false
var sellSignal = false
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Generate buy signal if a signal has not already been generated and the conditions are met
if trendUp and crossover(stoch, oversold) and not buySignal
buySignal := true
// Generate sell signal if a signal has not already been generated and the conditions are met
if trendDown and crossunder(stoch, overbought) and not sellSignal
sellSignal := true
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
// Reset buy and sell signals if a new trend develops
if trendUp and sellSignal
sellSignal := false
if trendDown and buySignal
buySignal := false
// Plot moving averages on chart
plot(ma1, color=color.blue)
plot(ma2, color=color.orange)
🔸Once I inputted the code provided I started to get a signal for every candle which is not what we wanted.
So I advised GPT of the issue.
It then attempted to solve the issue but instead it modified the code to only generate a buy signal or sell signal if the moving averages and the stochastic conditions where met all AT THE SAME TIME, Resulting in little to no signals.
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Keep track of current trend direction
var currentTrendUp = trendUp
var currentTrendDown = trendDown
// Determine buy and sell signals based on Stochastic RSI
buySignal = false
sellSignal = false
if trendUp and not currentTrendUp and crossover(stoch, oversold)
buySignal := true
currentTrendUp := true
else if trendDown and not currentTrendDown and crossunder(stoch, overbought)
sellSignal := true
currentTrendDown := true
// Reset trend direction if moving averages cross
if not trendUp and currentTrendUp or not trendDown and currentTrendDown
currentTrendUp := trendUp
currentTrendDown := trendDown
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
// Plot moving averages on chart
plot(ma1, color=color.blue)
plot(ma2, color=color.orange)
I advised ChatGPT of the issue once again. And was more clear in what I wanted.
This time, GPT was successful in solving the issue and the code was working exactly how I wanted it to. As you can see, one of the major challenges with using GPT to generate code is clearly articulating what you want it to do and limiting the number of iterations and changes it makes to the code. Additionally, providing feedback on what it is doing right and wrong is crucial in achieving the desired outcome.
//@version=4
study(title="Moving Average and Stochastic RSI Indicator", shorttitle="MA+Stoch RSI", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Initialize trend direction and signal variables
var trendUp = ma1 > ma2 ? true : false
var trendDown = ma1 < ma2 ? true : false
var signalUp = false
var signalDown = false
// Determine trend direction based on MA crossover
if ma1 > ma2
trendUp := true
trendDown := false
else
trendUp := false
trendDown := true
// Determine buy and sell signals based on Stochastic RSI
buySignal = false
sellSignal = false
if trendUp and crossover(stoch, oversold) and not signalUp
buySignal := true
signalUp := true
signalDown := false
else if trendDown and crossunder(stoch, overbought) and not signalDown
sellSignal := true
signalUp := false
signalDown := true
// Plot signals on chart
plotshape(buySignal, style=shape.arrowup, location=location.belowbar, color=color.green, size=size.small, text="Buy")
plotshape(sellSignal, style=shape.arrowdown, location=location.abovebar, color=color.red, size=size.small, text="Sell")
// Plot moving averages on chart
plot(ma1, color=color.blue)
plot(ma2, color=color.orange)
6: With our indicator now functioning properly, we can move on to the next step of converting it into a strategy for testing on Tradingview. To accomplish this, we'll need to establish specific take profit and stop loss criteria I've decided to use the price of the slow moving average as the exit of the trades. Which will also act as a trailing stop loss
//@version=4
strategy("MA+Stoch RSI Strategy", overlay=true)
// Input variables
ma1_length = input(title="MA1 Length", type=input.integer, defval=20, minval=1)
ma2_length = input(title="MA2 Length", type=input.integer, defval=50, minval=1)
stoch_length = input(title="Stochastic RSI Length", type=input.integer, defval=14, minval=1)
overbought = input(title="Overbought Level", type=input.integer, defval=80)
oversold = input(title="Oversold Level", type=input.integer, defval=20)
// Calculate moving averages
ma1 = sma(close, ma1_length)
ma2 = sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = rsi(close, stoch_length)
rsiH = highest(rsi1, stoch_length)
rsiL = lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Initialize flag variables
var hasBoughtSignal = false
var hasSoldSignal = false
// Generate signals
if trendUp and crossover(stoch, oversold) and not hasBoughtSignal
strategy.entry("Buy", strategy.long)
hasBoughtSignal := true
hasSoldSignal := false
if trendDown and crossunder(stoch, overbought) and not hasSoldSignal
strategy.entry("Sell", strategy.short)
hasBoughtSignal := false
hasSoldSignal := true
// Set stop loss and take profit levels
if strategy.position_size != 0
if strategy.position_size > 0
strategy.exit("StopLoss", "Buy", stop=ma2, qty_percent=100)
strategy.exit("TakeProfit", "Sell", limit=close - (ma2 - close), qty_percent=100)
else
strategy.exit("StopLoss", "Sell", stop=ma2, qty_percent=100)
strategy.exit("TakeProfit", "Buy", limit=close + (close - ma2), qty_percent=100)
// Plot moving averages on chart
plot(ma1, color=color.blue)
plot(ma2, color=color.orange)
And that's it! Our code is complete. The final step is to convert it to version 5
And here is the final code
//@version=5
strategy('MA+Stoch RSI Strategy', overlay=true)
// Input variables
ma1_length = input.int(title='MA1 Length', defval=20, minval=1)
ma2_length = input.int(title='MA2 Length', defval=50, minval=1)
stoch_length = input.int(title='Stochastic RSI Length', defval=14, minval=1)
overbought = input(title='Overbought Level', defval=80)
oversold = input(title='Oversold Level', defval=20)
// Calculate moving averages
ma1 = ta.sma(close, ma1_length)
ma2 = ta.sma(close, ma2_length)
// Calculate Stochastic RSI
rsi1 = ta.rsi(close, stoch_length)
rsiH = ta.highest(rsi1, stoch_length)
rsiL = ta.lowest(rsi1, stoch_length)
stoch = (rsi1 - rsiL) / (rsiH - rsiL) * 100
// Determine trend direction based on MA crossover
trendUp = ma1 > ma2 ? true : false
trendDown = ma1 < ma2 ? true : false
// Initialize flag variables
var hasBoughtSignal = false
var hasSoldSignal = false
// Generate signals
if trendUp and ta.crossover(stoch, oversold) and not hasBoughtSignal
strategy.entry('Buy', strategy.long)
hasBoughtSignal := true
hasSoldSignal := false
hasSoldSignal
if trendDown and ta.crossunder(stoch, overbought) and not hasSoldSignal
strategy.entry('Sell', strategy.short)
hasBoughtSignal := false
hasSoldSignal := true
hasSoldSignal
// Set stop loss and take profit levels
if strategy.position_size != 0
if strategy.position_size > 0
strategy.exit('StopLoss', 'Buy', stop=ma2, qty_percent=100)
strategy.exit('TakeProfit', 'Sell', limit=close - (ma2 - close), qty_percent=100)
else
strategy.exit('StopLoss', 'Sell', stop=ma2, qty_percent=100)
strategy.exit('TakeProfit', 'Buy', limit=close + close - ma2, qty_percent=100)
// Plot moving averages on chart
plot(ma1, color=color.new(color.blue, 0))
plot(ma2, color=color.new(color.orange, 0))
🔸I will also publish this script along with this article for others to use. However, I want to stress that this is not a guaranteed profitable system and users should use it at their own risk. This tutorial is simply an example of how to use ChatGPT to create your own script and test it.
🔸While using ChatGPT, you may encounter some issues, such as incomplete responses due to word limits. In such cases, you can refer to the end of the code and ask ChatGPT to provide only the additional part of the response. Additionally, the longer the chat history, the more likely you may encounter issues as GPT makes more modifications to the code. Therefore, it's important to limit the number of changes and provide clear feedback to help GPT understand your desired outcome. You may sometimes need to start a new chat if having many issues.
🔸Another way to utilize GPT for more complex tasks, especially when you already have programming knowledge, is to use it to brainstorm solutions for specific issues instead of writing the code. For example, if you're working with multiple timeframes, GPT may be unable to generate the code for you, but it can help you come up with ideas and potential solutions to the problem. Here is an example below :
Indicator usage knowledge ☆♡
TradingView PineScript indicator code involves understanding the code, installing it on TradingView, testing it on historical data, optimizing it for your trading strategy, and implementing it in your live trading. By following these steps, you can make the most of your indicator and increase your chances of success in the market.
To install a script on TradingView, follow these steps:
• Open TradingView and click on the "Pine Editor" tab at the bottom of the screen.
• Once you are in the Pine Editor, create a new script by clicking on the "New indicator" button in the top left corner.
• Argument how and what your indicator should calculate , plot and generate alerts in.
• After definening your indicator script, click on the "Save" button in the top left corner to save the code.
• Next, click on the "Add to Chart" button in the top right corner to add the code to your chart.
• Finally, customize the settings of the indicator as needed while testing it using the backtesting feature on TradingView.
Once you have installed the code, you can modify it to suit your trading needs. Be sure to test the modified code on historical data using the backtesting feature on TradingView before using it in live trading.
You are on your way to optimizing your trading strategy and increasing your profits.
• Understand the Code: Start by going through the code and understanding what it does. You can do this by studying the way to argument your indicatot script. It's important to know what the code is doing before using it in your trading strategy.
• Install the Code: Once you understand the code, install it on TradingView. Be sure to check for any errors.
• Test the Code: After installing the code, it's important to test it on historical data. This will help you verify that the indicator works as expected and can be useful in your trading strategy. You can do this by using the backtesting feature on TradingView.
• Optimize the Code: Depending on your trading style, you may need to optimize the code. This means tweaking the parameters to fit your specific trading strategy. For example, you may need to adjust the timeframe, the number of periods, or the signal thresholds.
• Implement the Code: Once you are satisfied with the code, you can start using it in your live trading strategy. Be sure to monitor your trades and adjust your strategy as needed.
It is important to remember that no trading strategy is foolproof, and there is always a risk of losing money. Always practice proper risk management and trade with caution.
"By analyzing market sessions using indicators , traders can gain a better understanding of the market dynamics during different times of the day. This information can be used to identify high-probability trading opportunities, as well as to manage risk in periods of low liquidity or high volatility. When used in conjunction with other technical indicators, such as RSI4, volumes, awesome oscillators and market session indicators, analysis if the market will provide a more complete picture, helping you make more informed trading decisions."
-Happy Foreign Exchange Trading - J
2nd Pine Script Lesson: Coding the Entry Logic - Bollinger BandWelcome back to our Trading View tutorial series! In this second lesson, be learning how to code the entry logic for a Bollinger Band indicator using Pine Script.
If you're new here and missed the first lesson, we highly recommend starting there as it provides a solid foundation for understanding the concepts we'll be covering today:
In this hands-on lesson, we'll guide you through every step of coding the entry logic for your own Bollinger Band indicator using Pine Script. By the end of this lesson, you'll have a functional indicator that you can use to inform your trading decisions. So, sit back, grab a cup of coffee, and let's get started!
Code the entry logic
a) This is where we are calling the Mikilap function with two arguments:
- the coinpair and
- the timeframe we want to use.
// Calling the Mikilap function to start the calculation
int indi_value = Function_Mikilap(symbol_full, time_frame)
b) In the function initiation we convert the strings into simple strings.
// Definition of a Pine Script individual function to handle the Request and avoid Repainting Errors
Function_Mikilap(simple string coinpair, simple string tf_to_use) =>
c) As we are calling the function to get an integer value, we have to define an output variable as an integer and place this variable as the last line in the local scope of the function code to return the integer value.
int function_result = 0
// placeholder for indicator calculations
function_result
Step 1:
Using the lower bandwidth of the Bollinger Band based on SMA (close, 21) and a standard deviation of 2.0 and try to highlight bars, where close is next to the lower band
a) Requesting the values for the coinpair with request.security()
= request.security(coinpair, tf_to_use, )
We recommend using repainting functions like request or barstate only in a local scope (inside a function) and not to request complex calculated values. For saving calculation capacity it is useful to only request the classic four OHLCs and do any calculation with these four after the r equest.security() .
b) Calculation of the lower Bollinger Bands values as we need the global info, which type of source, length, and deviation value to use for the calculation, let‘s cut & paste the input for the Bollinger Band in the general starting section of the code and as we want to look for close values „next“ to the lower bandwidth, we need to define what „next“ means; let‘s do it in another input variable, perhaps we want to play with the definition later.
string symbol_full = input.symbol(defval = "BINANCE:BTCUSDT", title = "Select Pair:", group = "General")
string time_frame = input.string(defval = "60", title = "Timeframe:", tooltip = "Value in minutes, so 1 hour = 60", group = "General")
int length = input.int(defval = 21, title = "BB Length:", group = "Bollinger Band Setting")
src = input(defval = close, title="BB Source", group = "Bollinger Band Setting")
float mult = input.float(defval = 2.0, title="BB Standard-Deviation", group = "Bollinger Band Setting")
float lower_dev = input.float(defval = 0.1, title="BB Lower Deviation in %", group = "Bollinger Band Setting")/100
First, let‘s make it visible on the chart by re-writing the Bollinger Bandplot, which is not needed anymore.
// Calling the Mikilap function to start the calculation
int indi_value = Function_Mikilap(symbol_full, time_frame)
// Output on the chart
// Part 2 - plotting a Band around the lower bandwidth of a Bollinger Band for the active CoinPair on the chart
lower_bb = ta.sma(src, length) - (mult*ta.stdev(src, length))
lower_bb_devup = lower_bb + lower_bb * lower_dev
lower_bb_devdown = lower_bb - lower_bb * lower_dev
upper = plot(lower_bb_devup, "BB Dev UP", color=#faffaf)
lower = plot(lower_bb_devdown, "BB Dev DOWN", color=#faffaf)
fill(upper, lower, title = "BB Dev Background", color=color.rgb(245, 245, 80, 80))
c) Now we use the same calculation for the coinpair inside the function and start with the selection of the source (OHLC) to use, which is activein the respective input variable.
// Defintion of a Pine Script individual function to handle the Request and avoid Repainting Errors
Function_Mikilap(simple string coinpair, simple string tf_to_use) =>
int function_result = 0
bool barstate_info = barstate.isconfirmed
= request.security(coinpair, tf_to_use, )
src_cp = switch src
open => open_R
high => high_R
low => low_R
=> close_R
lower_band_cp = ta.sma(src_cp,length) - (mult*ta.stdev(src_cp, length))
lower_band_cp_devup = lower_band_cp + lower_band_cp * lower_dev
lower_band_cp_devdown = lower_band_cp - lower_band_cp * lower_dev
// placeholder for indicator calculations
d) As the bandwidth for the interesting close values is defined by our band, the only thing missing for the part of the Bollinger Band in our Mikilap indicator is to check if the close value of a bar is inside our band. As we are talking about closed bars, let‘s be sure that it is really closed by using barstate.isconfirmed (repainting built-in function!) and save it in a variable in the head of the function to avoid requesting this info too often.
bool barstate_info = barstate.isconfirmed
Now let‘s check if the close value of a bar is inside our band.
bool bb_entry = close_R < lower_band_cp_devup and close_R > lower_band_cp_devdown and barstate_info
And increase the output variable by 1 in case the close value is inside.
if bb_entry
function_result += 1
By using bb_entry , we are referring to the last bar next to the actual bar, because we want to enter on the opening of the bar after the criteria has been met.
e) And to make these possible entries visible, we want to place a label below the bar and show the entry price (=open value of the bar) as mouseover (tooltip). This should only happen if the active coinpair on the chart is the same coinpair, which is in the calculation of the function.
if function_result == 1 and ticker.standard(syminfo.tickerid) == coinpair
label LE_arrow = label.new(x = bar_index, y = low_R, text = " ↑ LE", yloc = yloc.belowbar, color = color.rgb(255,255,255,25),style = label.style_none, textcolor = color.white, tooltip = str.tostring(open_R))
Note:
You will love labels (!) and in case you are looking for text symbols that can be used as labels, look here: www.messletters.com
If you need help use the Pine Script Reference Manual, which explains 99% of everything in Pine Script, here: www.tradingview.com
f) As our function now returns different integer values (0 or 1), we can use this info to color the background on the actual chart in case it is 1.
// Calling the Mikilap function to start the calculation
int indi_value = Function_Mikilap(symbol_full, time_frame)
color bg_color = indi_value ? color.rgb(180,180,180,75) : color.rgb(25,25,25,100)
bgcolor(bg_color)
g) To finish this little Pine Script lesson and to achieve our initial targets, we just need to integrate the second indicator (RSI) into the function. We want to use the RSI for 0,5 days (12 hours) and use it to ensure to not go into a long entry in an oversold (< 25) or overbought (> 70) market. We will use RSI (low, 12) within 25 to 45 as the range to go for.
Your tasks:
define new input variables for RSI: src_rsi and length_rsi
define new input variables for the RSI range we want to use: rsi_minand rsi_max(please use the „inline“ format of an input type)
calculate the RSI (src_rsi, length_rsi) inside our Mikilap-function
define a boolean variable (rsi_entry) to check if the calculated RSI value is inside the range (please add as last check the barstate_info)
add the RSI entry check to the Bollinger Band entry check to combine them
Congratulations on finishing the second lesson on Trading View - we hope you found it informative and engaging!
We're committed to providing you with valuable insights and practical knowledge throughout this tutorial series. So, we'd love to hear from you! Please leave a comment below with your suggestions on what you'd like us to focus on in the next lesson.
Thanks for joining us on this learning journey, and we're excited to continue exploring Trading View with you!
1st Pine Script Lesson: Coding an Indicator - Bollinger Band
Welcome to this lesson on Trading View, where we will be learning how to create a Bollinger Band indicator using Pine Script.
Bollinger Bands are a popular tool that helps measure an asset's volatility and identify potential trends in price movement. Essentially, the indicator consists of three lines: a middle line that's a simple moving average (SMA), and an upper and lower band that are two standard deviations away from the SMA. The upper band represents the overbought level, meaning the price of the asset is considered high and may be due for a correction. The lower band represents the oversold level, meaning the price is considered low and may be due for a rebound.
Pine Script is a programming language specifically used for creating custom indicators and strategies on Trading View. It's a powerful tool that allows traders to customize their technical analysis to fit their special trading needs and gain deeper insights into the markets..
In this lesson, we'll be taking a hands-on approach to learning. We'll walk through each step of creating our own Bollinger Band indicator using Pine Script, with the goal of helping you gain confidence in your ability to customize and create indicators that meet your unique trading needs. So, grab a cup of coffee and let's get started!
Step 1: Set up a new chart
Let‘s set up a new clean chart to work with for this example. You will find the menu to manage your layouts on the top right of the TradingView screen.
a) add a new layout
b) rename it to „Mizar Example“
c) select BTCUSDT from Binance
d) set the time frame to 1 hour
e) clean the screen (closing the Volume indicator)
f) save it
Step 2: Coding an indicator
Let‘s code our new indicator („Mizar-Killer-Long-Approach“)and make the possible entry moments visible on the chart. You will find the Pine Editor on the bottom left of the TradingView screen.
a) open the Pine Editor
b) use „Open“ in the Pine Editor menu bar
c) use the item: create a new indicator
d) let‘s use full screen for a better overview use the three dots on the right end of the Pine Editor menu bar and open the script in a separate new browser tab
e) rename it to “Mikilap“ by clicking on the current name
f) save it
Step 3: Coding an indicator
Let‘s start coding Our target:
1. create an own new indicator: Mikilap, which bases in general on RSI and Bollinger Band
2. define the parameter for Mikilap, to select the long entries
3. show the long entries on the chart by - putting a label below the bar - change the background color of the timeframe for the bar on the chart
Initiation/Generals
• Indicator initiation
//Indicator script initiation
indicator(title = "Mizar-Killer-Long-Approach", shorttitle = "Mikilap", overlay = true, max_labels_count = 300)
indicator = Pine keyword for an indicator script
title = Long form of the name
short title = Short form of the name as shown on the chart
overlay = true: output like labels, boxes, … are shown on the chart
false: output like plots, … are shown in a separate pane
• General variables and input
// Coin Pair with PREFIX
// Bitcoin / USDT on Binance as an example / standard value on an 60 minutes = 1-hour timeframe
string symbol_full = input.symbol(defval = "BINANCE:BTCUSDT", title = "Select Pair:", group = "General")
string time_frame = input.string(defval = "60", title = "Timeframe:", tooltip = "Value in minutes, so 1 hour = 60", group = "General")
Using the input type of a variable allows you to change this setting in the setup on the chart without changing the Pine Script code.
Framework Code on Main Level
• Framework code on the main level around the indicator calculation function
// Defintion of a Pine Script individual function to handle the Request and avoid Repainting Errors
Function_Mikilap(simple string coinpair, simple string tf_to_use) =>
int function_result = 0
// placeholder for indicator calculations
function_result
// Calling the Milky Way function to start the calculation
int indi_value = Function_Mikilap(symbol_full, time_frame)
Output on the chart - Part 1
// Output on the chart
// Part 1 - plotting a Bollinger Band for the active CoinPair on the chart
int length = input.int(defval = 21, title = "BB Length:", group = "Bollinger Band Setting")
src = input(defval = close, title="BB Source", group = "Bollinger Band Setting")
float mult = input.float(defval = 2.0, title="BB Standard-Deviation", group = "Bollinger Band Setting")
upper_band = ta.sma(src, length) + (mult * ta.stdev(src, length))
lower_band = ta.sma(src, length) - (mult * ta.stdev(src, length))
upper = plot(upper_band, "BB Upper", color=#faffaf)
lower = plot(lower_band, "BB Lower", color=#faffaf)
fill(upper, lower, title = "BB Background", color=color.rgb(245, 245, 80, 80))
Done for today!
• Let‘s save our current script and take a look if we see our Bollinger Band plotted on the chart.
• Step 1: Save (top right)
• Step 2: check in the compiling section, that there are no errors (separate pane below the code)
• Step 3: go to the Mizar Example chart and add an Indicator
How does it look now?
You will see the Bollinger Band as a yellow area around the candles. By pressing the „Settings“ button behind the name of our indicator, the menu for Mikilap will open and you can adjust all the settings we have done with input type variables.
Congrats if you‘ve made it until here! Get prepared for the next lesson, where we will continue with the indicator/entry logic.
The Philosophy of Selling Technical IndicatorsWith a rather odd & convoluted history, the industry of selling access to technical indicators goes back further in time than most traders & investors are aware of.
A rather large majority of investors perceive the act of selling access to technical indicators as being in most relation to selling 'snake-oil'.
While this is true for many vendors who unfortunately market indicators as a 'get rich quick' scheme for trading, it's not true for every vendor.
In this article we are going to do a deep dive exposing what makes a bad vendor, going through the history of indicator vendors, and outlining how vendors can actually have an overall positive impact for the community.
Disclaimer: LuxAlgo is a provider of technical indicators (mostly free, but some paid), however, we will try to be as un-biased as possible in this piece. This article is purely for informational & educational purposes for the greater community.
🔶 WHAT MAKES A GOOD VENDOR?
We could summarize this as a vendor who first & foremost follows TradingView vendor requirements , develops quality products, cares about the community, truly acknowledges that past performance is not necessarily indicative of future results, and has good business practices.
A step by step ruleset to follow of how to be a good vendor could be as follows:
🔹 1. Publish open-source scripts
Aside from the paid scripts, vendors should be easily able to contribute other publications with open-source code for the greater community.
Come on, let the world see that code! There shouldn't be any hesitation to contribute open-source scripts if a vendor is deeming themselves good enough to sell private indicators, right?
Well, there's not many other ways to immediately tell if their products are "quality" if a vendor has no open-source publications to show for themselves as a developer.
If someone is going to sell indicators, we believe in our opinion that they should be able to contribute to the community with open-source work as well in a notable way. This can also be a vendor's way of "giving back" or at least just a way to show they care about the community.
Many vendors completely disregard publishing open source as a means to building a community & also being contributive to the great platform with a userbase they're building a business on top of, while in fact, it does all of this in an extremely productive way.
A possible reason why many vendors do not prioritize publishing open-source scripts could be that they don't know how to do so in any case, so they stick to private script publications mostly (or entirely) to avoid having to be in the public eye of the broader TradingView / Pine Script community.
🔹 2. Don't use misleading marketing practices
Indicators can be marketed as quality, efficient, comprehensive, educational, and supportive tools for traders / investors.
There is a balance a vendor must have when it comes to marketing a technical indicator as a product.
To be clear, of course, it is only logical & common sense to display a product as 'good', and there's nothing wrong with that.
However, if a vendor goes too far, such as saying, "Our indicator has an 89% win rate!" or "How to turn $1k into $100k!" or even "Revealing the game-changing secret weapon that made trader $1M on 1 trade!" - then a vendor is simply using bad practices to acquire customers.
A great analogy can be an advertisement for a food company such as Pizza Hut. Of course, they want to make the pizza look great with excellent visuals, good lighting, & shiny cheese, however, they don't tell you by eating the pizza it will get you a 6-pack rock hard abs.
The same can be applied to marketing technical indicators as products. Of course, a vendor can display their product functioning well in good market conditions primarily, however, by claiming it has any sort of "win-rate" or guaranteed profits, a vendor is being misleading.
The only difference between the Pizza Hut ad & the technical indicator ad being it pertains to the analysis of financial markets, so, in general there should also be proper disclaimers where fit to address consumer expectations using such products.
🔹 3. Don't be misleading in your branding, either.
This goes hand-in-hand with the point made above on marketing.
If a brand itself is in relation to generating profits like "Profit-Bot" or a product / feature is called "10x-Gains-Moving-Average"... the vendor is likely en-route to problems in the long run with the business (bad reviews, business disputes, poor community, etc).
A great business is made on transparency, providing value, caring about customers, and making a difference within an industry for the better.
The more a business does good by customers, the healthier the business will be, & the longer the business will last.
Within the space of technical indicators as products, no matter how transparent the marketing / website is, many customers will still have the impression that they will use these products to help themselves 'make profits'.
While this is of course mostly everyone's goal being involved in financial markets in the first place, it calls for a good balance in the presentation of the indicators as well as setting expectations clear by communicating realistic expectations to customers as best as possible.
One thing vendors can easily do to be transparent, honest, & an overall good actor in the industry is to provide a generous refund policy to ensure consumers who may still have the wrong idea about the intended usage have the opportuntiy to move on with a full refund.
Executing on a good refund policy tends to be the most successful strategy for vendors opposed to free trials even for managing expectations because free trials can attract even less experienced traders who don't want to take the time to learn the product itself no matter how many times they have directed to not follow indicators blindly.
There are many instances of where this is seen as similarly true within digital products in general such as plug-ins, educational programs, etc.
🔹 4. Create unique products
This should be a given, however, it's something we thought we should mention as many vendors tend to impersonate or completely mimic other products already existing in hopes of theirs attaining the same level of attention.
The reality is most technical indicators as products have already seen a high level of adoption from the broader community and it universally is known to them that there are knockoff products existing already.
Joining forces with the knockoffs is not a good bet in any endeavor and we believe that originality can go a long way in this industry as well.
🔶 WHAT MAKES A BAD VENDOR?
Well, this can be easily summed up in 1 image of course.
You know what they say, if something sounds too good to be true... it isn't.
If someone is standing in front of an exotic car, flashing cash, and telling you they got this rad lifestyle by using their trading indicator... it should immediately raise 1,000 red flags for you.
There's no such thing as getting rich quick, especially based on the functionality of a technical indicator. Period.
This type of malicious marketing is extremely harmful to people as it directly gives them false hopes, plays into desperation, and is from a common-sense perspective; a deceptive marketing tactic used by charlatans.
Bad vendors do not publish any open-source contributions and primarily just stick to marketing indicators in misleading ways that overall harm the community.
There are many potential reasons as to why vendors market indicators in misleading ways:
1.) They don't understand indicators & they are actually snake-oil salesmen (image above).
2.) They do understand indicators, maybe have something decent developed, but just don't know how else to market indicators other than promising profits.
3.) They may have tried marketing in non-misleading ways before, found that misleading marketing is producing the most sales for them, so they became fueled with greed & doubled-down on the misleading claims when marketing their product regardless. (Instead of trying to build a reputable business).
🔶 WHY & HOW VENDORS CAN BE GOOD FOR THE COMMUNITY
Vendors have the power to reach more people, since at the end of the day, there is a business established behind them with marketing efforts.
We believe that people will buy indicators no matter what and that this is a real established market as products for traders, regardless of what the majority of investors think of it.
So, as long as there are good actors primarily at the top of the industry, this is what's best for the community overall, and possibly the overall perception of indicator vendors can change eventually.
Good acting vendors with the right practices as listed earlier in this article are able to educate more people through marketing their products, community growth, & open-source contributions that they publish as well.
All in turn, growing the broader interest in the scripting community which helps grow technical analysis further by having a larger number of users provide feedback to each other & further improve the space over time.
In the case of LuxAlgo as a provider for example, it would not have been possible to grow a TradingView following of 200,000+ without the marketing efforts outside of TradingView on platforms like YouTube, Instagram, and even TikTok for all indicators we have created (free & paid).
Which has certainly grown into a large community, which over time has meaningfully contributed to the interest in custom technical indicators & the scripting community overall in general.
In the case of a bad acting vendor, this is the exact opposite & bad for the community overall because they do not make any good contribution to the community and just merely exist to try & sell access to their private indicators.
🔶 DO PAID INDICATORS "WORK" BETTER THAN FREE INDICATORS?
If you are defining the word "work" as "make more profits", then the answer is a hard no in all cases.
If you are defining the word "work" as in "being more useful", then it truly just depends on how comprehensive or unique the indicator is.
We believe that indicators are best used as supportive tools for decision making, so it's important to be asking this question in the right context & with this understanding when considering a product.
In the context of LuxAlgo Premium indicators specifically, we believe the answer is yes due to how the indicators were designed as all-in-one toolkits that include presets, filters, & various customization/optimization methods specifically designed to help traders embrace their trading style.
The position for paid indicators to exist under a subscription model is primarily done since indicators can be frequently updated / improved over time based on the user's feedback.
There are, however, other aspects of paid indicators which could be legitimately more useful than anything you can find for free in some other cases such as unique volume-based tools, extensive market scanner scripts, etc.
Although, it is quite limited when it comes to traditional technical indicators such as moving averages or signal-based indicators to make a strong argument that one is better than another in any meaningful way.
In most cases, you can take one indicator and overfit it to appear "better" or "more accurate" than another indicator by finding more specific market conditions or settings that has an advantage over another.
As a technical analyst, you begin to understand this once you have experimented with vast amounts of technical indicators with different use cases and have thoroughly reflected on its actual benefits to you. It's truly impossible to make an alternative argument in all cases, including debatably all paid technical indicators in existence right now.
🔶 THE REAL VALUE PROPOSITION OF PAID TECHNICAL INDICATORS
Since we can conclude in mostly all scenarios that paid indicators don't "work" better than free indicators in a technical sense when referring to its accuracy or direct visual aid to a trader, it begs to question what the actual value proposition can be for a vendor selling access to indicators.
A large part of the alternative value prop for a vendor may fall under the community & education that it provides under the brand, or additionally, the prospect of a vendor making paid indicators more interoperable with other applications such as large-scale alerts systems or cross-platform functionality.
Many vendors may try to create value propositions for their paid indicators by hosting a signal group where analysts callout trades using their paid indicators, however, this typically will be done in misleading ways over-hyping the usage and is not generally a good practice for vendors or users in our opinion.
With all of this mentioned, it may seem that the entire industry is full of charlatans at times, however, we do not believe the space will remain like this forever.
🔶 SHOULD THIS BE A MORE LEGITIMIZED INDUSTRY?
The history of paid indicators goes all the way back to the 1980's with John Ehlhers & Mark Jurik being two notable figures providing paid tools through websites on various charting platforms.
There was also a rather strange ecosystem of products with generally 'awkward' branding existing on older charting platforms since the early 2,000's. Some of which on these platforms still exist to this day. While interestingly enough, practically none of these brands ever grew past being considered small plug-ins.
Some considerably large educational programs / memberships throughout the 2,000's (& some existing still to this day) have implemented indicators as a part of their offerings, although they typically tend to integrate indicators only to add on to their sales funnel styled websites in hopes to add unique value to their "life changing online course" positioning, so we won't mention any names.
Additionally, while most new traders are likely unaware, TradingView had an app-store marketplace themselves in the 2010's called "marketplace add-ons" where users could purchase indicators from various vendors within their indicators tab alongside the Public Library now called Community Scripts.
Likely as the TradingView platform & Pine Script was mass-adopted on a larger scale, this marketplace was discontinued for various reasons with the adoption of invite-only scripts, where anyone with a premium account can manage access on these types of script publications.
This pivotal shift leveled the playing field for the industry whereas it created a new ecosystem of vendors who all could leverage their ability to manage access to users without appearing as "just another marketplace add-on", but rather, actual brands themselves.
While keeping this piece as un-biased as possible, this is where LuxAlgo was born, & generally speaking, was primarily the inspiration for the hundreds of "Algo" brands popping up all over the internet trying to sell TradingView indicators due to our notoriety in this environment.
In this current landscape, we believe there is an established ecosystem that has potential to mature further into a 'healthy' industry, so to speak... as mentioned earlier, just as long as there are more good actors leading it than bad.
We are also hopeful for platforms to recognize this evolution themselves & directly support the ecosystem to grow more efficiently with stronger operations over time while still allowing these brands their own independence as they have now.
It's very optimistic considering the realization of how popular the ecosystem has become & with the prospect of vendors within it to lead it in positive ways, which overall brings more people to TradingView & grows genuine interest in the Pine Script community from all over the internet very effectively.
🔶 CONCLUSION
We strongly believe indicator vendors will always exist in some capacity considering the 30–40-year history, the rise of digital products on the internet, as well as the growing popularity of indicator vendors in this current landscape. Considering this, it's important to ensure the brands leading the space are good actors so the space itself can mature long-term.
As a prominent figure in this industry, we hope from this article to have provided a lot of transparency for the broader community of traders & investors who may not have been aware of this space in such detail, as well as for any aspiring vendors to hopefully look to us and what we have outlined as a good role model / checklist for the sake of making this industry more legitimized in the future.
Thank you for reading!
- Sean Mack (Founder @LuxAlgo)
Credits
Alex Pierrefeu (TV profile @alexgrover) for being a massive leader in LuxAlgo since the beginning & going deep all the time creating theories w/ me about technical analysis & the industry with genuine fascination.
John Ehlers for being what we call the grandfather of this entire industry dating back to the 1980's with MESA Software.
Mark Jurik as a serious 'wave maker' with Jurik Research and for leading the way in the early 2,000's as a provider of unique tools.
@ChrisMoody for being a real "OG" in the TradingView community & for some cool discussions about the history of the industry early on.
All of the amazing users of LuxAlgo Premium since early 2020 and the entire community who provide us feedback to improve our indicators over time.
Everyone in the Pine Script community who follows us on TradingView & enjoys our contributions.
The @PineCoders team for being extremely helpful moderating the platform & for listening to our feedback / dealing with us throughout the years.
And lastly @TradingView for being the greatest platform for traders / investors and for making all of this possible in the first place.
How to Choose the Right Indicator?Many traders, especially when starting out find themselves in a constant search of the best trading strategy.
A quick Google search is enough to scare anyone starting out, as the number of indicators and strategies to use under different market conditions is overwhelming.
🗒In this article, we will discuss *1* indicators nature and the correct way to use it, *2* how to choose the right indicator, and most importantly *3* how to know if the indicator is reliable or not.
---------------------------------------------------------------------------------------------------------------------
📌 First, what are indicators? Origin and Nature
Indicators are statistical tools that digest price data, OHLC of each candle, add a formula to it, and then convert it into visual information such as graphs or oscillators. Indicators provide information about the strength of a trend, momentum, and possible reversals.
When it comes to indicators, we can divide them into four classes: Momentum indicators, Trend indicators, Volatility indicators, Volume Indicators.
Knowing which one belongs to which category can help you make much better trading decisions. On the other hand, combining indicators in a wrong way can lead to a lot of confusion, wrong price interpretation, and, subsequently, to wrong trading decisions.
📌 The correct way to use indicators. Indicators don’t provide signals.
Most traders never look at the indicators they are using and even less have ever tried to understand the formula the indicator uses to analyze price. They then use their indicators in the wrong context and wonder why nothing works.
🗒Indicators don’t tell you when to buy or when to sell. They don’t even tell you when something is overbought or oversold.
Indicators are great tools if a trader understands their true purpose. Indicators provide information about price, how the price has moved, how candles have shaped, and how recent price action compares to historical price action. Again, not a direct signal to buy or sell.
Thus, the job of a trader is to interpret the information on their indicators in a meaningful way and turn it into a story about price action and buying/selling pressure.
Who is in control right now? Is the market ranging or trending? Is price losing strength or gaining momentum?
📌 How to choose the right indicator? That suits your trading style and personality
-----------------------------------------------------------------------------
📕 * Meaningful: Represents important information.
-----------------------------------------------------------------------------
Your indicator choice should match your trading style. The purpose of indicators/strategies is to offer a way to identify clues and to provide a framework for traders to work in. Our main job, as traders, is to collect clues and combine them in a meaningful way to have an edge over the market.
🗒 Only add indicators that help you put the odds in your favor. -- If it doesn’t, you don’t need it.
-----------------------------------------------------------------------------------------------------------
📕 * Objective: Has a clear operational definition of what is being measured.
-----------------------------------------------------------------------------------------------------------
Indicators are ideal for rule-based trading as indicators take out the guesswork by providing information that is totally objective especially for newbies who are struggling with discipline.
The most successful strategies/indicators are those where not a lot of individual interpretation is required.
🗒 Only use indicators that help you make objective decisions. -- If it doesn’t, you don’t need it.
-----------------------------------------------------------------------------------
📕 * Understandable: Easy to comprehend and interpret.
-----------------------------------------------------------------------------------
Indicators are great tools especially for amateurs who do not know how to relate price data into meaningful relationships.
Indicators' main purpose is to make your life easier, not more sophisticated.
🗒 Remember: K.I.S.S. Keep it simple stupid! -- If it is complicated, you don’t need it.
📕 Last but not least, less is more:
The problem with indicator redundancy is that when a trader picks multiple indicators that show the same information, he/she ends up giving too much weight to the information provided by the indicators.
🗒 “All Strategies / Indicators are good; if managed properly.”
~ Richard Nasr
---------------------------------------------------------------------------------------------------------------------
📌 How to know if the indicator is reliable? Cheat Sheet Checklist
📕 * Does it repaint, disappear or recalculate?
We have all been there. An indicator looking good /profitable on the chart, but perform horribly under live market conditions. Most indicators are designed to only show/keep winning signals. Do not, ever, include an indicator in your trading plan before testing it on a demo account.
🗒 Here is a simple step by step guide on how to test indicators:
- Attach your indicator to any chart.
- Keep your trading platform running for a while for the indicator to plot a couple of signals.
- Take a screenshot of the chart.
- Refresh by switching between the timeframes.
- Compare your chart with the screenshot
If the indicator’s signals /drawings change location or disappear, then it is a red flag. Such indicators are not reliable and shouldn’t be used in any way.
📕 * Does it lag?
In general, indicators are lagging, but so is price action. An indicator can only analyze what has happened already. Just as a candlestick or chart pattern only includes past price data.
Nothing to worry about so far, as we mentioned above, indicators only provide information and do not offer signals.
However, some indicators are too lagging. This kind of indicators looks good on historical data but appear too late under live market conditions.
🗒 Pro Tip: Always take into consideration when, where, and how does the signal appear.
📕 * Is it TradingView friendly?
90% of custom indicators do not work on TradingView, because PineScript does not allow recalculation. Thus, the signal/drawing can’t be modified once it is generated by the indicator.
Therefore, indicators that are available on TradingView stand out from the crowd, and they are considered more reliable.
---------------------------------------------------------------------------------------------------------------------
📌 In brief, indicators are very famous tools and used by millions of traders. However, often traders don’t really know what their indicators are doing or how to use them.
Always be aware of the objectives of your trading style and what you are trying to accomplish with the indicators. Then, adjust accordingly. Once a trader can stop using indicators as signal-tools, he will be able to transform his trading to new heights.
Happy trading!
Always follow your trading plan regarding entry, risk management, and trade management.
~Rich
TRADINGVIEW PINESCRIPT CODERS PRO+ USER NEEDS TRADERS , I'm looking for pine script coder, programmer to create me a automated indicator that can calculate my new (TDV) TOP DOWN VOLUME ANALYSIS INDICATOR idea, using the multi time frame top down analysis approach, I came up with this idea based on math, time frames, percentages of volume calculating it manually taking the color (red) for bearish/shorts and (green) bullish/longs of the last 3 out of 5 candle volumes in each time frame from 1m to 1w with total time frames (18) giving each TF a value #1-3 giving more value and weight to the higher TF and lower values weight to the lower as that's how top down analysis multi time framing work's I'm putting sample on screen with description and my new TDV ANALYSIS logo. IF ANYONE IS INTERESTED IN BUILDING/CREATING THIS INDICATOR please pm me on here so we can talk, just want to say that many traders believe price is king and most indicators are lagging but i believe VOLUME is the true king because its what pushes price and momentum and volatility so i believe there can be a holy grail indicator that has not been adopted or built yet and i think this idea has very good merits and could be just that, a all 4 in one leading indicator to take buy and sell trades based on volume alone as long as you know if its the bulls or bears with the volume power, a signal of say 100% bullish or bearish volume could be a great catalyst for a nice price move and momentum once alerted or signaled.
thanks guys, tradingbugtech & traderdadzz
TRADINGVIEW PINESCRIPT CODERS PRO+ USER NEEDS YOUR HELP ! traders i am looking for help creating a volume strength indicator i have created and back testing manually, everyone believes price is king but i believe price is just the amount of traders trading and how much volume dictates price action, indicators today are great and i do use them 2nd to price action and volume but believe volume is the true king so i created a idea using multi time frame top down method like dr. elders triple screen, im using (14) time frames and getting the most recent 5 bars volume and taking the average of the 5 bars and giving each time frame a vale 1-3% giving the lowest time frames the lowest number percent and the higher time frames the higher value percentage, then i add up each bull/bear volume and put it in a standard win rate calculator to get the winning volume percentage average, im now back testing manually every 1h if i were looking for trade set ups on the hourly tf and the 4h for day trades and intraday trades have written a pdf with all the details on how im back testing and what i want the indicator to signal for buys and sells based on the percentage of overall volume i have manually calculated using my values, please is anyone interested in building this pine script indicator i want to use on trading view as a paid subscription service once its been back tested and has a good win ratio/rate, anyone ,all trading view coders if u think u are interested in building and testing with myself please pm me, thank you.
Pine Beginner with Gr8 Script Idea - Script part need helpHi everyone
So before you get to excited - this is only the half of an idea which needs some Pine Scripting polish before I would classify this idea as one to take note of. With that said, if there's someone reading this that is willing to amend the code of my poor attempt to combine 3 scripts together in to 1 rather successful (potentially) algo/auto-trading script which was initially intended to place trades on MT5 for those who are either stuck, to far tied-in or simply stubborn enough to continue using a broker/s that are not listed on TradingView's list of verified brokers.
I must add that I honestly think this script has the potential to be one hellofa successful strategy for any trader who is considering or attempting to learn this fascinating and exciting coding language that can either leave you more confused than blind deaf old man at a psychedelic's rave OR open up a whole new approach of trading that was previously unfathomable yet now with each unique scripts encounter becoming unquestionably clearer that traders who embrace this path can only empower their trading potentials. I think if more opportunistic scripts like this one (once correctly coded by someone who is not as much a rookie as I am - at Pine Script coding not trading) along with some helpful guidelines for traders who have not discovered the wonders that TradingView has to offer any/all traders - that these "aha" types of doorways will be easily flooded with new interest evoked traders to the TradingView world.
But that's just one traders opinion who is looking towards putting this somewhat overly thought concept to test/s and I welcome any of you who wish to do the same, particularly in terms of trying to make heads or tails of my script that in theory makes perfect sense in my mind by using well known trading concepts by those who don't necessarily need to know how to code them in order to use them. However, in this specific case, the knowledge of how to code them has been given the centre front spotlight so feel free to take your shot in it's lime light if you wish. I would most definitely appreciate it and I'm sure you would benefit from the final scripts results as well.
Thanks to any and all who give it a go.
// Here's the script that I feel is best to share - there is a more recent updated version, however, I feel that my scripting skills or lack of may have made that version a great deal more confusing and messy than what this version below is. Hopefully you can see where Im trying to go with it. If not, please don't hesitate to ask and I'll do my best to try clarify where needed.
//
//@version=4
//
// Thanks to dynausmaux falconCoin LazyBear RicardoSantos LucemAnb andreholanda73 for all the scripts I'm using here.
// Special thanks to TradingView for unarguably the best trading platform in the world that facilitates development and learning.
// Before I begin, TAKE NOTE: I'm not an expert trader or pine script coder as such and all the code used here is copied and/or modified from scripts freely found that are published through TradingView.
//
//
// For those of you who actually do look in to the code behind scripts they come accross - here's logic behind all the colorful shapes all over your charts.
//
// CIRCLES & TRIANGLES:
// - LITTLE CIRCLE: They appear at all WaveTrend wave crossings.
// - GREEN CIRCLE: The wavetrend waves are at the oversold level and have crossed up (bullish).
// - RED CIRCLE: The wavetrend waves are at the overbought level and have crossed down (bearish).
// - GOLD/ORANGE CIRCLE: When RSI is below 20, WaveTrend waves are below or equal to -80 and have crossed up after good bullish divergence (DONT BUY WHEN GOLD CIRCLE APPEAR).
// - None of these circles are certain signs to trade. It is only information that can help you.
// - PURPLE TRIANGLE: Appear when a bullish or bearish divergence is formed and WaveTrend waves crosses at overbought and oversold points.
//
// +BEARS/BULLS FLAG:
// - MFI+RSI Area are RED (Below 0).
// - Wavetrend wave above 0 and crossing over down.
// - VWAP Area below 0 on higher timeframe.
// - This pattern reversed becomes bullish.
// +SIDE NOTE: Check the last heikinashi candle from 2 higher timeframe
// - Bearish/Bullish DIAMOND:
// -- HT Candle is red
// -- WT > 0 and crossed down
study(title = 'VuManChu B Divergences', shorttitle = 'VuMan CBD')
// PARAMETERS {
// WaveTrend
wtShow = input(true, title = 'Show WaveTrend', type = input.bool)
wtBuyShow = input(true, title = 'Show Buy dots', type = input.bool)
wtGoldShow = input(true, title = 'Show Gold dots', type = input.bool)
wtSellShow = input(true, title = 'Show Sell dots', type = input.bool)
wtDivShow = input(true, title = 'Show Div. dots', type = input.bool)
vwapShow = input(true, title = 'Show Fast WT', type = input.bool)
wtChannelLen = input(9, title = 'WT Channel Length', type = input.integer)
wtAverageLen = input(12, title = 'WT Average Length', type = input.integer)
wtMASource = input(hlc3, title = 'WT MA Source', type = input.source)
wtMALen = input(3, title = 'WT MA Length', type = input.integer)
// WaveTrend Overbought & Oversold lines
obLevel = input(53, title = 'WT Overbought Level 1', type = input.integer)
obLevel2 = input(60, title = 'WT Overbought Level 2', type = input.integer)
obLevel3 = input(100, title = 'WT Overbought Level 3', type = input.integer)
osLevel = input(-53, title = 'WT Oversold Level 1', type = input.integer)
osLevel2 = input(-60, title = 'WT Oversold Level 2', type = input.integer)
osLevel3 = input(-75, title = 'WT Oversold Level 3', type = input.integer)
// Divergence WT
wtShowDiv = input(true, title = 'Show WT Regular Divergences', type = input.bool)
wtShowHiddenDiv = input(false, title = 'Show WT Hidden Divergences', type = input.bool)
showHiddenDiv_nl = input(true, title = 'Not apply OB/OS Limits on Hidden Divergences', type = input.bool)
wtDivOBLevel = input(45, title = 'WT Bearish Divergence min', type = input.integer)
wtDivOSLevel = input(-65, title = 'WT Bullish Divergence min', type = input.integer)
// Divergence extra range
wtDivOBLevel_addshow = input(true, title = 'Show 2nd WT Regular Divergences', type = input.bool)
wtDivOBLevel_add = input(15, title = 'WT 2nd Bearish Divergence', type = input.integer)
wtDivOSLevel_add = input(-40, title = 'WT 2nd Bullish Divergence 15 min', type = input.integer)
// RSI+MFI
rsiMFIShow = input(true, title = 'Show MFI', type = input.bool)
rsiMFIperiod = input(60,title = 'MFI Period', type = input.integer)
rsiMFIMultiplier = input(150, title = 'MFI Area multiplier', type = input.float)
rsiMFIPosY = input(2.5, title = 'MFI Area Y Pos', type = input.float)
// RSI
rsiShow = input(false, title = 'Show RSI', type = input.bool)
rsiSRC = input(close, title = 'RSI Source', type = input.source)
rsiLen = input(14, title = 'RSI Length', type = input.integer)
rsiOversold = input(30, title = 'RSI Oversold', minval = 50, maxval = 100, type = input.integer)
rsiOverbought = input(60, title = 'RSI Overbought', minval = 0, maxval = 50, type = input.integer)
// Divergence RSI
rsiShowDiv = input(false, title = 'Show RSI Regular Divergences', type = input.bool)
rsiShowHiddenDiv = input(false, title = 'Show RSI Hidden Divergences', type = input.bool)
rsiDivOBLevel = input(60, title = 'RSI Bearish Divergence min', type = input.integer)
rsiDivOSLevel = input(30, title = 'RSI Bullish Divergence min', type = input.integer)
// RSI Stochastic
stochShow = input(true, title = 'Show Stochastic RSI', type = input.bool)
stochUseLog = input(true, title=' Use Log?', type = input.bool)
stochAvg = input(false, title='Use Average of both K & D', type = input.bool)
stochSRC = input(close, title = 'Stochastic RSI Source', type = input.source)
stochLen = input(14, title = 'Stochastic RSI Length', type = input.integer)
stochRsiLen = input(14, title = 'RSI Length ', type = input.integer)
stochKSmooth = input(3, title = 'Stochastic RSI K Smooth', type = input.integer)
stochDSmooth = input(3, title = 'Stochastic RSI D Smooth', type = input.integer)
// Divergence stoch
stochShowDiv = input(false, title = 'Show Stoch Regular Divergences', type = input.bool)
stochShowHiddenDiv = input(false, title = 'Show Stoch Hidden Divergences', type = input.bool)
// Schaff Trend Cycle
tcLine = input(false, title="Show Schaff TC line", type=input.bool)
tcSRC = input(close, title = 'Schaff TC Source', type = input.source)
tclength = input(10, title="Schaff TC", type=input.integer)
tcfastLength = input(23, title="Schaff TC Fast Lenght", type=input.integer)
tcslowLength = input(50, title="Schaff TC Slow Length", type=input.integer)
tcfactor = input(0.5, title="Schaff TC Factor", type=input.float)
// Sommi Flag
sommiFlagShow = input(false, title = 'Show Sommi flag', type = input.bool)
sommiShowVwap = input(false, title = 'Show Sommi F. Wave', type = input.bool)
sommiVwapTF = input('720', title = 'Sommi F. Wave timeframe', type = input.string)
sommiVwapBearLevel = input(0, title = 'F. Wave Bear Level (less than)', type = input.integer)
sommiVwapBullLevel = input(0, title = 'F. Wave Bull Level (more than)', type = input.integer)
soomiFlagWTBearLevel = input(0, title = 'WT Bear Level (more than)', type = input.integer)
soomiFlagWTBullLevel = input(0, title = 'WT Bull Level (less than)', type = input.integer)
soomiRSIMFIBearLevel = input(0, title = 'Money flow Bear Level (less than)', type = input.integer)
soomiRSIMFIBullLevel = input(0, title = 'Money flow Bull Level (more than)', type = input.integer)
// Sommi Diamond
sommiDiamondShow = input(false, title = 'Show Sommi diamond', type = input.bool)
sommiHTCRes = input('60', title = 'HTF Candle Res. 1', type = input.string)
sommiHTCRes2 = input('240', title = 'HTF Candle Res. 2', type = input.string)
soomiDiamondWTBearLevel = input(0, title = 'WT Bear Level (More than)', type = input.integer)
soomiDiamondWTBullLevel = input(0, title = 'WT Bull Level (Less than)', type = input.integer)
// macd Colors
macdWTColorsShow = input(false, title = 'Show MACD Colors', type = input.bool)
macdWTColorsTF = input('240', title = 'MACD Colors MACD TF', type = input.string)
darkMode = input(false, title = 'Dark mode', type = input.bool)
// Colors
colorRed = #ff0000
colorPurple = #e600e6
colorGreen = #3fff00
colorOrange = #e2a400
colorYellow = #ffe500
colorWhite = #ffffff
colorPink = #ff00f0
colorBluelight = #31c0ff
colorWT1 = #90caf9
colorWT2 = #0d47a1
colorWT2_ = #131722
colormacdWT1a = #4caf58
colormacdWT1b = #af4c4c
colormacdWT1c = #7ee57e
colormacdWT1d = #ff3535
colormacdWT2a = #305630
colormacdWT2b = #310101
colormacdWT2c = #132213
colormacdWT2d = #770000
// } PARAMETERS
// FUNCTIONS {
// Divergences
f_top_fractal(src) => src < src and src < src and src > src and src > src
f_bot_fractal(src) => src > src and src > src and src < src and src < src
f_fractalize(src) => f_top_fractal(src) ? 1 : f_bot_fractal(src) ? -1 : 0
f_findDivs(src, topLimit, botLimit, useLimits) =>
fractalTop = f_fractalize(src) > 0 and (useLimits ? src >= topLimit : true) ? src : na
fractalBot = f_fractalize(src) < 0 and (useLimits ? src <= botLimit : true) ? src : na
highPrev = valuewhen(fractalTop, src , 0)
highPrice = valuewhen(fractalTop, high , 0)
lowPrev = valuewhen(fractalBot, src , 0)
lowPrice = valuewhen(fractalBot, low , 0)
bearSignal = fractalTop and high > highPrice and src < highPrev
bullSignal = fractalBot and low < lowPrice and src > lowPrev
bearDivHidden = fractalTop and high < highPrice and src > highPrev
bullDivHidden = fractalBot and low > lowPrice and src < lowPrev
// RSI+MFI
f_rsimfi(_period, _multiplier, _tf) => security(syminfo.tickerid, _tf, sma(((close - open) / (high - low)) * _multiplier, _period) - rsiMFIPosY)
// WaveTrend
f_wavetrend(src, chlen, avg, malen, tf) =>
tfsrc = security(syminfo.tickerid, tf, src)
esa = ema(tfsrc, chlen)
de = ema(abs(tfsrc - esa), chlen)
ci = (tfsrc - esa) / (0.015 * de)
wt1 = security(syminfo.tickerid, tf, ema(ci, avg))
wt2 = security(syminfo.tickerid, tf, sma(wt1, malen))
wtVwap = wt1 - wt2
wtOversold = wt2 <= osLevel
wtOverbought = wt2 >= obLevel
wtCross = cross(wt1, wt2)
wtCrossUp = wt2 - wt1 <= 0
wtCrossDown = wt2 - wt1 >= 0
wtCrosslast = cross(wt1 , wt2 )
wtCrossUplast = wt2 - wt1 <= 0
wtCrossDownlast = wt2 - wt1 >= 0
// Schaff Trend Cycle
f_tc(src, length, fastLength, slowLength) =>
ema1 = ema(src, fastLength)
ema2 = ema(src, slowLength)
macdVal = ema1 - ema2
alpha = lowest(macdVal, length)
beta = highest(macdVal, length) - alpha
gamma = (macdVal - alpha) / beta * 100
gamma := beta > 0 ? gamma : nz(gamma )
delta = gamma
delta := na(delta ) ? delta : delta + tcfactor * (gamma - delta )
epsilon = lowest(delta, length)
zeta = highest(delta, length) - epsilon
eta = (delta - epsilon) / zeta * 100
eta := zeta > 0 ? eta : nz(eta )
stcReturn = eta
stcReturn := na(stcReturn ) ? stcReturn : stcReturn + tcfactor * (eta - stcReturn )
stcReturn
// Stochastic RSI
f_stochrsi(_src, _stochlen, _rsilen, _smoothk, _smoothd, _log, _avg) =>
src = _log ? log(_src) : _src
rsi = rsi(src, _rsilen)
kk = sma(stoch(rsi, rsi, rsi, _stochlen), _smoothk)
d1 = sma(kk, _smoothd)
avg_1 = avg(kk, d1)
k = _avg ? avg_1 : kk
// MACD
f_macd(src, fastlen, slowlen, sigsmooth, tf) =>
fast_ma = security(syminfo.tickerid, tf, ema(src, fastlen))
slow_ma = security(syminfo.tickerid, tf, ema(src, slowlen))
macd = fast_ma - slow_ma,
signal = security(syminfo.tickerid, tf, sma(macd, sigsmooth))
hist = macd - signal
// MACD Colors on WT
f_macdWTColors(tf) =>
hrsimfi = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, tf)
= f_macd(close, 28, 42, 9, macdWTColorsTF)
macdup = macd >= signal
macddown = macd <= signal
macdWT1Color = macdup ? hrsimfi > 0 ? colormacdWT1c : colormacdWT1a : macddown ? hrsimfi < 0 ? colormacdWT1d : colormacdWT1b : na
macdWT2Color = macdup ? hrsimfi < 0 ? colormacdWT2c : colormacdWT2a : macddown ? hrsimfi < 0 ? colormacdWT2d : colormacdWT2b : na
// Get higher timeframe candle
f_getTFCandle(_tf) =>
_open = security(heikinashi(syminfo.tickerid), _tf, open, barmerge.gaps_off, barmerge.lookahead_on)
_close = security(heikinashi(syminfo.tickerid), _tf, close, barmerge.gaps_off, barmerge.lookahead_on)
_high = security(heikinashi(syminfo.tickerid), _tf, high, barmerge.gaps_off, barmerge.lookahead_on)
_low = security(heikinashi(syminfo.tickerid), _tf, low, barmerge.gaps_off, barmerge.lookahead_on)
hl2 = (_high + _low) / 2.0
newBar = change(_open)
candleBodyDir = _close > _open
// Sommi flag
f_findSommiFlag(tf, wt1, wt2, rsimfi, wtCross, wtCrossUp, wtCrossDown) =>
= f_wavetrend(wtMASource, wtChannelLen, wtAverageLen, wtMALen, tf)
bearPattern = rsimfi < soomiRSIMFIBearLevel and
wt2 > soomiFlagWTBearLevel and
wtCross and
wtCrossDown and
hwtVwap < sommiVwapBearLevel
bullPattern = rsimfi > soomiRSIMFIBullLevel and
wt2 < soomiFlagWTBullLevel and
wtCross and
wtCrossUp and
hwtVwap > sommiVwapBullLevel
f_findSommiDiamond(tf, tf2, wt1, wt2, wtCross, wtCrossUp, wtCrossDown) =>
= f_getTFCandle(tf)
= f_getTFCandle(tf2)
bearPattern = wt2 >= soomiDiamondWTBearLevel and
wtCross and
wtCrossDown and
not candleBodyDir and
not candleBodyDir2
bullPattern = wt2 <= soomiDiamondWTBullLevel and
wtCross and
wtCrossUp and
candleBodyDir and
candleBodyDir2
// } FUNCTIONS
// CALCULATE INDICATORS {
// RSI
rsi = rsi(rsiSRC, rsiLen)
rsiColor = rsi <= rsiOversold ? colorGreen : rsi >= rsiOverbought ? colorRed : colorPurple
// RSI + MFI Area
rsiMFI = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, timeframe.period)
rsiMFIColor = rsiMFI > 0 ? #3ee145 : #ff3d2e
// Calculates WaveTrend
= f_wavetrend(wtMASource, wtChannelLen, wtAverageLen, wtMALen, timeframe.period)
// Stochastic RSI
= f_stochrsi(stochSRC, stochLen, stochRsiLen, stochKSmooth, stochDSmooth, stochUseLog, stochAvg)
// Schaff Trend Cycle
tcVal = f_tc(tcSRC, tclength, tcfastLength, tcslowLength)
// Sommi flag
= f_findSommiFlag(sommiVwapTF, wt1, wt2, rsiMFI, wtCross, wtCrossUp, wtCrossDown)
//Sommi diamond
= f_findSommiDiamond(sommiHTCRes, sommiHTCRes2, wt1, wt2, wtCross, wtCrossUp, wtCrossDown)
// macd colors
= f_macdWTColors(macdWTColorsTF)
// WT Divergences
= f_findDivs(wt2, wtDivOBLevel, wtDivOSLevel, true)
= f_findDivs(wt2, wtDivOBLevel_add, wtDivOSLevel_add, true)
= f_findDivs(wt2, 0, 0, false)
wtBearDivHidden_ = showHiddenDiv_nl ? wtBearDivHidden_nl : wtBearDivHidden
wtBullDivHidden_ = showHiddenDiv_nl ? wtBullDivHidden_nl : wtBullDivHidden
wtBearDivColor = (wtShowDiv and wtBearDiv) or (wtShowHiddenDiv and wtBearDivHidden_) ? colorRed : na
wtBullDivColor = (wtShowDiv and wtBullDiv) or (wtShowHiddenDiv and wtBullDivHidden_) ? colorGreen : na
wtBearDivColor_add = (wtShowDiv and (wtDivOBLevel_addshow and wtBearDiv_add)) or (wtShowHiddenDiv and (wtDivOBLevel_addshow and wtBearDivHidden_add)) ? #9a0202 : na
wtBullDivColor_add = (wtShowDiv and (wtDivOBLevel_addshow and wtBullDiv_add)) or (wtShowHiddenDiv and (wtDivOBLevel_addshow and wtBullDivHidden_add)) ? #1b5e20 : na
// RSI Divergences
= f_findDivs(rsi, rsiDivOBLevel, rsiDivOSLevel, true)
= f_findDivs(rsi, 0, 0, false)
rsiBearDivHidden_ = showHiddenDiv_nl ? rsiBearDivHidden_nl : rsiBearDivHidden
rsiBullDivHidden_ = showHiddenDiv_nl ? rsiBullDivHidden_nl : rsiBullDivHidden
rsiBearDivColor = (rsiShowDiv and rsiBearDiv) or (rsiShowHiddenDiv and rsiBearDivHidden_) ? colorRed : na
rsiBullDivColor = (rsiShowDiv and rsiBullDiv) or (rsiShowHiddenDiv and rsiBullDivHidden_) ? colorGreen : na
// Stoch Divergences
= f_findDivs(stochK, 0, 0, false)
stochBearDivColor = (stochShowDiv and stochBearDiv) or (stochShowHiddenDiv and stochBearDivHidden) ? colorRed : na
stochBullDivColor = (stochShowDiv and stochBullDiv) or (stochShowHiddenDiv and stochBullDivHidden) ? colorGreen : na
// Small Circles WT Cross
signalColor = wt2 - wt1 > 0 ? color.red : color.lime
// Buy signal.
buySignal = wtCross and wtCrossUp and wtOversold
buySignalDiv = (wtShowDiv and wtBullDiv) or
(wtShowDiv and wtBullDiv_add) or
(stochShowDiv and stochBullDiv) or
(rsiShowDiv and rsiBullDiv)
buySignalDiv_color = wtBullDiv ? colorGreen :
wtBullDiv_add ? color.new(colorGreen, 60) :
rsiShowDiv ? colorGreen : na
// Sell signal
sellSignal = wtCross and wtCrossDown and wtOverbought
sellSignalDiv = (wtShowDiv and wtBearDiv) or
(wtShowDiv and wtBearDiv_add) or
(stochShowDiv and stochBearDiv) or
(rsiShowDiv and rsiBearDiv)
sellSignalDiv_color = wtBearDiv ? colorRed :
wtBearDiv_add ? color.new(colorRed, 60) :
rsiBearDiv ? colorRed : na
// Gold Buy
lastRsi = valuewhen(wtFractalBot, rsi , 0)
wtGoldBuy = ((wtShowDiv and wtBullDiv) or (rsiShowDiv and rsiBullDiv)) and
wtLow_prev <= osLevel3 and
wt2 > osLevel3 and
wtLow_prev - wt2 <= -5 and
lastRsi < 30
// } CALCULATE INDICATORS
// DRAW {
bgcolor(darkMode ? color.new(#000000, 80) : na)
zLine = plot(0, color = color.new(colorWhite, 50))
// MFI BAR
rsiMfiBarTopLine = plot(rsiMFIShow ? -95 : na, title = 'MFI Bar TOP Line', transp = 100)
rsiMfiBarBottomLine = plot(rsiMFIShow ? -99 : na, title = 'MFI Bar BOTTOM Line', transp = 100)
fill(rsiMfiBarTopLine, rsiMfiBarBottomLine, title = 'MFI Bar Colors', color = rsiMFIColor, transp = 75)
// WT Areas
plot(wtShow ? wt1 : na, style = plot.style_area, title = 'WT Wave 1', color = macdWTColorsShow ? macdWT1Color : colorWT1, transp = 0)
plot(wtShow ? wt2 : na, style = plot.style_area, title = 'WT Wave 2', color = macdWTColorsShow ? macdWT2Color : darkMode ? colorWT2_ : colorWT2 , transp = 20)
// VWAP
plot(vwapShow ? wtVwap : na, title = 'VWAP', color = colorYellow, style = plot.style_area, linewidth = 2, transp = 45)
// MFI AREA
rsiMFIplot = plot(rsiMFIShow ? rsiMFI: na, title = 'RSI+MFI Area', color = rsiMFIColor, transp = 20)
fill(rsiMFIplot, zLine, rsiMFIColor, transp = 40)
// WT Div
plot(series = wtFractalTop ? wt2 : na, title = 'WT Bearish Divergence', color = wtBearDivColor, linewidth = 2, offset = -2)
plot(series = wtFractalBot ? wt2 : na, title = 'WT Bullish Divergence', color = wtBullDivColor, linewidth = 2, offset = -2)
// WT 2nd Div
plot(series = wtFractalTop_add ? wt2 : na, title = 'WT 2nd Bearish Divergence', color = wtBearDivColor_add, linewidth = 2, offset = -2)
plot(series = wtFractalBot_add ? wt2 : na, title = 'WT 2nd Bullish Divergence', color = wtBullDivColor_add, linewidth = 2, offset = -2)
// RSI
plot(rsiShow ? rsi : na, title = 'RSI', color = rsiColor, linewidth = 2, transp = 25)
// RSI Div
plot(series = rsiFractalTop ? rsi : na, title='RSI Bearish Divergence', color = rsiBearDivColor, linewidth = 1, offset = -2)
plot(series = rsiFractalBot ? rsi : na, title='RSI Bullish Divergence', color = rsiBullDivColor, linewidth = 1, offset = -2)
// Stochastic RSI
stochKplot = plot(stochShow ? stochK : na, title = 'Stoch K', color = color.new(#21baf3, 0), linewidth = 2)
stochDplot = plot(stochShow ? stochD : na, title = 'Stoch D', color = color.new(#673ab7, 60), linewidth = 1)
stochFillColor = stochK >= stochD ? color.new(#21baf3, 75) : color.new(#673ab7, 60)
fill(stochKplot, stochDplot, title='KD Fill', color=stochFillColor)
// Stoch Div
plot(series = stochFractalTop ? stochK : na, title='Stoch Bearish Divergence', color = stochBearDivColor, linewidth = 1, offset = -2)
plot(series = stochFractalBot ? stochK : na, title='Stoch Bullish Divergence', color = stochBullDivColor, linewidth = 1, offset = -2)
// Schaff Trend Cycle
plot(tcLine ? tcVal : na, color = color.new(#673ab7, 25), linewidth = 2, title = "Schaff Trend Cycle 1")
plot(tcLine ? tcVal : na, color = color.new(colorWhite, 50), linewidth = 1, title = "Schaff Trend Cycle 2")
// Draw Overbought & Oversold lines
//plot(obLevel, title = 'Over Bought Level 1', color = colorWhite, linewidth = 1, style = plot.style_circles, transp = 85)
plot(obLevel2, title = 'Over Bought Level 2', color = colorWhite, linewidth = 1, style = plot.style_stepline, transp = 85)
plot(obLevel3, title = 'Over Bought Level 3', color = colorWhite, linewidth = 1, style = plot.style_circles, transp = 95)
//plot(osLevel, title = 'Over Sold Level 1', color = colorWhite, linewidth = 1, style = plot.style_circles, transp = 85)
plot(osLevel2, title = 'Over Sold Level 2', color = colorWhite, linewidth = 1, style = plot.style_stepline, transp = 85)
// Sommi flag
plotchar(sommiFlagShow and sommiBearish ? 108 : na, title = 'Sommi bearish flag', char='⚑', color = colorPink, location = location.absolute, size = size.tiny, transp = 0)
plotchar(sommiFlagShow and sommiBullish ? -108 : na, title = 'Sommi bullish flag', char='⚑', color = colorBluelight, location = location.absolute, size = size.tiny, transp = 0)
plot(sommiShowVwap ? ema(hvwap, 3) : na, title = 'Sommi higher VWAP', color = colorYellow, linewidth = 2, style = plot.style_line, transp = 15)
// Sommi diamond
plotchar(sommiDiamondShow and sommiBearishDiamond ? 108 : na, title = 'Sommi bearish diamond', char='◆', color = colorPink, location = location.absolute, size = size.tiny, transp = 0)
plotchar(sommiDiamondShow and sommiBullishDiamond ? -108 : na, title = 'Sommi bullish diamond', char='◆', color = colorBluelight, location = location.absolute, size = size.tiny, transp = 0)
// Circles
plot(wtCross ? wt2 : na, title = 'Buy and sell circle', color = signalColor, style = plot.style_circles, linewidth = 3, transp = 15)
plotchar(wtBuyShow and buySignal ? -107 : na, title = 'Buy circle', char='·', color = colorGreen, location = location.absolute, size = size.small, transp = 50)
plotchar(wtSellShow and sellSignal ? 105 : na , title = 'Sell circle', char='·', color = colorRed, location = location.absolute, size = size.small, transp = 50)
plotchar(wtDivShow and buySignalDiv ? -106 : na, title = 'Divergence buy circle', char='•', color = buySignalDiv_color, location = location.absolute, size = size.small, offset = -2, transp = 15)
plotchar(wtDivShow and sellSignalDiv ? 106 : na, title = 'Divergence sell circle', char='•', color = sellSignalDiv_color, location = location.absolute, size = size.small, offset = -2, transp = 15)
plotchar(wtGoldBuy and wtGoldShow ? -106 : na, title = 'Gold buy gold circle', char='•', color = colorOrange, location = location.absolute, size = size.small, offset = -2, transp = 15)
// } DRAW
// ALERTS {
// BUY
alertcondition(buySignal, 'Buy (Big green circle)', 'Green circle WaveTrend Oversold')
alertcondition(buySignalDiv, 'Buy (Big green circle + Div)', 'Buy & WT Bullish Divergence & WT Overbought')
alertcondition(wtGoldBuy, 'GOLD Buy (Big GOLDEN circle)', 'Green & GOLD circle WaveTrend Overbought')
alertcondition(sommiBullish or sommiBullishDiamond, 'Sommi bullish flag/diamond', 'Blue flag/diamond')
alertcondition(wtCross and wtCrossUp, 'Buy (Small green dot)', 'Buy small circle')
// SELL
alertcondition(sommiBearish or sommiBearishDiamond, 'Sommi bearish flag/diamond', 'Purple flag/diamond')
alertcondition(sellSignal, 'Sell (Big red circle)', 'Red Circle WaveTrend Overbought')
alertcondition(sellSignalDiv, 'Sell (Big red circle + Div)', 'Buy & WT Bearish Divergence & WT Overbought')
alertcondition(wtCross and wtCrossDown, 'Sell (Small red dot)', 'Sell small circle')
// } ALERTS