Educational: The truth about backtestingI recently started to read a number of finance books and watching a lot of YouTube channels specifically on the topic of chaos theory and backtesting. I am going to start a series here where I share what I am learning and today we are going to delve into the world of backtesting.
"Those who fail to learn history are condemned to repeat it" - George Santayana
Many would agree that the above statement is truth. However one of the first thing you learn in trading/finance is that "Past performance does not predict future results". This statement is on every website, every video and every article. Everyone arms themselves with this statement and then proceeds to base the information they provide on past performance/data.
Well if this statement is truth, what is the alternative to using past performance/data? Financial reports, economic forecast, technical analysis, price action, footprint chart are all based on past performance/data. The truth is that the statement is made primarily as a legal protection against mislead investors who may believe that because something happened in the past it is guaranteed to happen again. But does that mean that there is no truth to the statement ? Well not exactly.
"Hindsight is 20/20" When looking at market data of the past it is very easy to see clear patterns in market behavior that seemingly repeat over and over again, creating the illusion that if you map an investing/trading strategy on this data it is very likely to performance well in the future. But this is not truth at all. In order to understand why it is not true please try to imagine the activity below.
Imagine you are a racecar driver, and you're brought to a new racing track that no one has every driven on . You are task with setting the best time record on the track. You got in your car, did your best and set a record of 10 minutes to complete the track. After the race you now have a map of the track and know what turns to expect and all the details of the road. Lets say you share this information to the next driver. He now attempts to set a record on the track and he beats your record by 2 minutes and the new record is now 8 minutes. The second driver now shares what he has learnt about the track to the third driver. The third driver takes the information from driver 1 and driver 2 and modifies his car to have the right tire's, right suspension, right aerodynamics etc. in order to have to best performance on the track. The third driver goes on the track and sets a record of 5 minutes. Completely outperforming driver 1 and driver 2. Driver 3 is now the champion of the track.
Below is a simple visualization of what is happening in terms of information that each driver had on their first run of the track.
Driver 3 is now dominating on the track and thinks he is unbeatable. Some time has past and driver 3 is brought to a new track that no one has raced on with his modified car from the first track. He attempts to race the track and sets a record of 12 minutes. He thinks he has done well. But driver 2 attempts the track and sets a record of 7 minutes out performing driver 3
Why didn't driver 3 outperform the other two drivers on the new track with his modified car? Well, what has happened here is that driver 3 has modified his car to the specifics of the first track as best as he can but when he went on another track that has different variables his car was not able to perform as well as it did before. Maybe the terrain was too rough or maybe the corners were too tight on this new track. Regardless of the reason, the modifications made to the car ended up working against him. In backtesting this is called "overfitting".
Overfitting in backtesting is when a strategy has been developed too precisely on past data causing the strategy to "fit to the curve" and there is now a risk of it not performing in the future once the market behavior changes.
Above we have a demonstration of how overfitting works. Where we looked at some data in the past and then we created a strategy that would have performance well on that data. Based on this information it now seems like we have a very profitable system but lets see what happens when me use this strategy on future data without adjusting our strategy.
In the image above we can see that the same strategy is no longer working in the new market environment. There are periods where it does perform but overall it is far worst. Now you might wonder, why is this? If the strategy worked on the market in the past why wont it work in the future. This is because the market is unpredictable. People often say the market is random, it is not random, what it is, is unpredictable and that is very different from being random. I will be doing another publication on chaos theory in the markets which will go into this topic much deeper, but for now, know that the reason it doesn't work is because the market is unpredictable.
When looking at past data if you take a bunch of variables and brute force your way into finding a strategy you will eventually find a strategy that "fits to the curve". You should not be using backtesting as a way to necessarily find a edge but it should be used as a way to validate your edge.
So with knowing this information how do we combat overfitting of data and how to properly backtest a system. When backtesting you need to deploy your backtesting using out of sample and in sample data. And what that means is that you will break apart your data into clusters. Where your "in sample" data is where you design your strategy and parameters and your "out of sample" data is where you will apply your strategy to see if it works. For example lets say you are looking at 10 years of data that you want to backtest. Take 3 years of that 10 and develop your strategy. Then with the strategy you developed which performs well on your "in sample" data you will now use it to test the other 7 years, of your "out of sample" data. What this does is prevent you from overfitting to the curve by basing your strategy on the entire data set.
Below is a visualization of this
What this does allow you to create a robust strategy that can be forward tested on future data.
Once again this is me sharing some of the knowledge I have attained. I am sure there are programmers here on tradingview that could possible explain this better or in more details. I welcome discussion and any criticism regarding my publication. Thank you for taking the time to read and I will update this publication in the future if needed.
Programming
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 :
Trusted Pine Programmers For HireTraders requiring the services of professional programmers to write indicators or strategies in TradingView's Pine programming language can now find a list of Trusted Pine Programmers For Hire in the Help Center.
Users of their services are welcome to post their impressions in the "Comments" section below.