Be careful with indicators programmed by AI – such as ChatGPT[Free]

I was hoping to create a short cut by using AI generated code, but…

I asked ChatGPT[FREE] to provide source in Python for Wilder’s Directional Movement Index.  Here is what it generated.

def calculate_dmi(highs, lows, closes, period=14):
tr_list = [max(high - low, abs(high - prev_close), abs(low - prev_close)) for high, low, prev_close in zip(highs[1:], lows[1:], closes[:-1])]
atr_list = [sum(tr_list[:period]) / period]
pdm_list = [0]
mdm_list = [0]
pdi_list = [0]
mdi_list = [0]
adx_list = [0]

for i in range(1, len(highs)):
tr = max(highs[i] - lows[i], abs(highs[i] - closes[i - 1]), abs(lows[i] - closes[i - 1]))
atr = ((period - 1) * atr_list[-1] + tr) / period
pdm = max(highs[i] - highs[i - 1], 0)
mdm = max(lows[i - 1] - lows[i], 0)

if highs[i] - highs[i - 1] < lows[i - 1] - lows[i]:
pdm = 0
elif highs[i] - highs[i - 1] > lows[i - 1] - lows[i]:
mdm = 0

pdi = ((period - 1) * pdi_list[-1] + pdm / atr) / period
mdi = ((period - 1) * mdi_list[-1] + mdm / atr) / period

pdm_list.append(pdm)
mdm_list.append(mdm)
pdi_list.append(pdi * 100)
mdi_list.append(mdi * 100)

if pdi_list[-1] + mdi_list[-1] == 0:
adx = 0
else:
adx = (abs(pdi_list[-1] - mdi_list[-1]) / (pdi_list[-1] + mdi_list[-1])) * 100
adx_list.append(((period - 1) * adx_list[-1] + adx) / period)

return pdi_list, mdi_list, adx_list

# Example usage:
highs = [26.37, 26.75, 26.92, 26.77, 26.70, 26.65, 26.68, 26.79, 26.71, 26.66]
lows = [25.67, 26.20, 26.37, 26.55, 26.48, 26.27, 26.41, 26.52, 26.54, 26.38]
closes = [26.31, 26.72, 26.87, 26.78, 26.50, 26.54, 26.60, 26.76, 26.65, 26.52]

pdi_result, mdi_result, adx_result = calculate_dmi(highs, lows, closes)
print("Plus Directional Indicator (PDI):", pdi_result)
print("Minus Directional Indicator (MDI):", mdi_result)
print("Average Directional Index (ADX):", adx_result)
Wilders's DMI

Notice where the Positive Directional Movement pdm and Negative Directional Movement mdm are calculated.  This calculation is correct, and it needs to be carried forward and used in the pdi and mdi calculations.  Once calculated, they are stored in lists.  PDI and mdi are then calculated using the pdm and mdm values.  This code looked reasonable, but once they were calculated they were multiplied by 100 and then stored in their own lists.   Increasing the pdi and mdi here by 100-fold is a glaring mistake, and this code was created by the fourth request (free version of ChatGPT).

ADX:  7.142857142857143  plusDMI:  2.4377176533618226  minusDMI:  0.0
ADX: 13.775510204081632 plusDMI: 232.93535359355562 minusDMI: 0.0
ADX: 19.933206552950452 plusDMI: 21629.71140511588 minusDMI: 1.8106570098294317
ADX: 25.65106744865798 plusDMI: 2008473.7551175265 minusDMI: 168.13243662701865
ADX: 30.960509708979348 plusDMI: 186501137.76019013 minusDMI: 15612.297686794587
ADX: 35.89070609356354 plusDMI: 17317962792.96054 minusDMI: 1449713.356630926
Watch dmiPlus and dmiMinus grow

If you allow this to run, you will eventually reach numeric overflow and ADX reaches nearly 100 on every calculation.  The first iteration was closer, but still did not calculate the pdi and mdi (PlusDMI and MinusDMI) correctly – they weren’t smoothed properly.  This in turn led to an incorrect ADX calculation.  I fixed the code and made it work, but it took almost as much time as I spent creating the DMI from scratch.  It would probably be better to ask ChatGPT or any other AI BOT to provide the pseudocode.  Or perhaps spend the extra $20 and get access to ChatGPT-4.  I will do that and revisit this a littler later.

For each time period i from 1 to N:
TR[i] = Max(High[i] - Low[i], |High[i] - Close[i-1]|, |Low[i] - Close[i-1]|)

For each time period i from 1 to N-1:
+DM[i] = High[i] - High[i-1] (if High[i] > High[i-1] and High[i] - Low[i] > Low[i-1] - Close[i-1])
-DM[i] = Low[i-1] - Low[i] (if Low[i-1] - Low[i] > High[i] - Low[i] and Low[i-1] - Close[i-1] > High[i] - Low[i])

Smoothed +DM (S+DM) for a given time period (default period is 14):
+DM14 = (Sum of the last 14 +DM values) / 14

Smoothed -DM (S-DM) for a given time period (default period is 14):
-DM14 = (Sum of the last 14 -DM values) / 14

Smoothed True Range (S_TR) for a given time period (default period is 14):
TR14 = (Sum of the last 14 TR values) / 14

Smoothed Positive Directional Index (PDI) for a given time period (default period is 14):
PDI14 = (+DM14 / TR14) * 100

Smoothed Negative Directional Index (NDI) for a given time period (default period is 14):
NDI14 = (-DM14 / TR14) * 100

Directional Movement Index (DX):
DX = |(PDI14 - NDI14)| / (PDI14 + NDI14) * 100

Average Directional Index (ADX) for a given time period (default period is 14):
ADX = (Sum of the last 14 DX values) / 14
PseudoCode

This looks accurate using Wilder’s short cut for smoothing.  If you want to program your own indicators, it is probably best to find the pseudocode and program it from scratch.  Not only are making sure it is correct, but you are learning the indicator inside out.  Also, if you have access to any free charting software that you feel is super reliable, then you can compare your results to see if your indicator is producing similar results.

Why create your own code

If you are like me, I don’t like building with blocks.  Unless I know with 100% accuracy those blocks are right.  Procedural/Functional programming versus OOP.  I am not saying one paradigm is better than another.  OOP was not an easy concept for program as needed type programmers. In the late 60s and throughout most of the 80s, mathematicians and scientists cobbled code together from BASIC and Fortran to accomplish what they simply needed at the time.  They didn’t work within a team and the code was there for their personal use.  Functional programming is gaining favor once again.  I have a physics friend that worked at Bell Labs finally adopt Python in favor of an old, but still reliable 64-BIT version of BASIC.  It is amazing to see the continued love for BASIC – and yes, it is still viable.  He discovered that you did not need to reinvent the wheel when it came to his research – he read about all the scientific libraries available to him for free.  Python was easy enough for him to pick up, but Pip Installing the libraries was another story. He started with a monolithic install of Python and all of the commercially available IDEs and libraries.  Which is great but it most cases it is overkill.  So, I had him remove it and install basic Python 3.10 with IDLE.  Then I suggested a straightforward IDE such as Pyscripter – an IDE that looks a lot like the older Turbo and Think IDEs that I grew up with.  It was a marriage made in heaven.  Once you get the Python set in your PATH, PIP Install is easy-peasy.

Also, you may not like the existing TA libraries because they are too restraining or too difficult to implement.  Finally, if you program something you will have a deeper understanding of what the code is doing.  I am old school; I like bare bones code.  I don’t want to have to implement one library after another.  The embedded interfaces move you further away from the meat of the code.  Now in some cases, a typical programmer will not have the scientific or practical or interface knowledge to implement his/her code.  Then you must rely on libraries.  Don’t get me wrong I use Python libraries whenever I absolutely need to.  I love openPYXL. This library converts the output of my research directly into easy to open spreadsheets.   There is no way I would want to delve into that type of programming.  However, why not program indicators yourself, if the pseudocode just requires a little data and some loops and some if-thens.  Most of you Quants out there are more than capable of programming even the most complicated indicators.

 

classic

yes

About This Site

This site is home to George’s Excellent Adventure into TradingSimula_18 and Python.  George grew tired of the old and expensive back testing software so he created his own and now is able to test and develop  Trend Following Systems utilizing EOD data and EOD intra-testing portfolio management.  This software, TradingSimula_18 can be found in his Trend Following Systems: A DIY Project – Batteries Included book – now in its 2nd edition.

December 2024
M T W T F S S
 1
2345678
9101112131415
16171819202122
23242526272829
3031