Buenas.
Esto es lo máximo que he conseguido. Es dificil porque no tenemos las mismas funcionalidades en PRT que en TV.
//---------------------------------------------------------------//
//SuperTrend AI Clustering
//version = 0
//01.08.2024
//Iván González @ www.prorealcode.com
//Sharing ProRealTime knowledge
//---------------------------------------------------------------//
//-----Inputs----------------------------------------------------//
//---------------------------------------------------------------//
length=10 //ATR length
minMult=1
maxMult=5
step=0.5
perfAlpha=10 //Performance memory
fromCluster=1//1=best 2=average 3=worst
//---------------------------------------------------------------//
//-----Average True Range----------------------------------------//
//---------------------------------------------------------------//
atr=averagetruerange[length](close)
//---------------------------------------------------------------//
//-----Supertrend------------------------------------------------//
//---------------------------------------------------------------//
$holderUpper[0]=(high+low)/2
$holderLower[0]=(high+low)/2
$holderOutput[0]=0
$holderPerf[0]=0
$holderFactor[0]=0
$holderTrend[0]=0
$factors[0]=0
//---Populate Supertrend
if barindex=0 then
n=0
for i=0 to floor((maxMult-minMult)/step) do
$factors[n+1]=(minMult+i*step)
$holderUpper[n+1]=(high+low)/2
$holderLower[n+1]=(high+low)/2
$holderOutput[n+1]=0
$holderPerf[n+1]=0
$holderFactor[n+1]=0
$holderTrend[n+1]=0
n=n+1
next
endif
//---Compute Supertrend for multiple factors
k=0
for factor=0 to floor((maxMult-minMult)/step) do
up=(high+low)/2+atr*factor
dn=(high+low)/2-atr*factor
if close > $holderUpper[k] then
$holderTrend[k]=1
elsif close < $holderUpper[k] then
$holderTrend[k]=0
else
$holderTrend[k]=$holderTrend[k]
endif
if close[1]<$holderUpper[k] then
$holderUpper[k]=min(up,$holderUpper[k])
else
$holderUpper[k]=up
endif
if close[1]>$holderLower[k] then
$holderLower[k]=max(dn,$holderLower[k])
else
$holderLower[k]=dn
endif
if (close[1]-$holderOutput[k])>0 then
diff=1
elsif (close[1]-$holderOutput[k])<0 then
diff=-1
else
diff=0
endif
$holderPerf[k]=$holderPerf[max(0,k-1)]+2/(perfAlpha+1)*((close-close[1])*diff-$holderPerf[max(0,k-1)])
if $holderTrend[k]=1 then
$holderOutput[k]=$holderLower[k]
else
$holderOutput[k]=$holderUpper[k]
endif
$holderFactor[k]=factor
k=k+1
next
//---------------------------------------------------------------//
//-----K means Clustering----------------------------------------//
//---------------------------------------------------------------//
// Initialize centroids with approximate averages
centroid1 = 0
centroid2 = 0
centroid3 = 0
count = k
FOR i = 0 TO count - 1 DO
IF i < count / 3 THEN
centroid1 = centroid1 + $holderPerf[i]
ELSIF i < 2 * count / 3 THEN
centroid2 = centroid2 + $holderPerf[i]
ELSE
centroid3 = centroid3 + $holderPerf[i]
ENDIF
NEXT
centroid1 = centroid1 / (count / 3)
centroid2 = centroid2 / (count / 3)
centroid3 = centroid3 / (count / 3)
// Arrays to store the clusters
$cluster1Perf[0] = 0
$cluster2Perf[0] = 0
$cluster3Perf[0] = 0
$cluster1Factors[0] = 0
$cluster2Factors[0] = 0
$cluster3Factors[0] = 0
FOR i = 0 TO count - 1 DO
dist1 = abs($holderPerf[i] - centroid1)
dist2 = abs($holderPerf[i] - centroid2)
dist3 = abs($holderPerf[i] - centroid3)
IF dist1 <= dist2 AND dist1 <= dist3 THEN
$cluster1Perf[$cluster1Perf[0]+1] = $holderPerf[i]
$cluster1Factors[$cluster1Factors[0]+1] = $holderFactor[i]
$cluster1Perf[0] = $cluster1Perf[0] + 1
$cluster1Factors[0] = $cluster1Factors[0] + 1
ELSIF dist2 <= dist1 AND dist2 <= dist3 THEN
$cluster2Perf[$cluster2Perf[0]+1] = $holderPerf[i]
$cluster2Factors[$cluster2Factors[0]+1] = $holderFactor[i]
$cluster2Perf[0] = $cluster2Perf[0] + 1
$cluster2Factors[0] = $cluster2Factors[0] + 1
ELSE
$cluster3Perf[$cluster3Perf[0]+1] = $holderPerf[i]
$cluster3Factors[$cluster3Factors[0]+1] = $holderFactor[i]
$cluster3Perf[0] = $cluster3Perf[0] + 1
$cluster3Factors[0] = $cluster3Factors[0] + 1
ENDIF
NEXT
// Recalculate centroids
centroid1 = 0
centroid2 = 0
centroid3 = 0
FOR i = 1 TO $cluster1Perf[0] DO
centroid1 = centroid1 + $cluster1Perf[i]
NEXT
centroid1 = centroid1 / $cluster1Perf[0]
FOR i = 1 TO $cluster2Perf[0] DO
centroid2 = centroid2 + $cluster2Perf[i]
NEXT
centroid2 = centroid2 / $cluster2Perf[0]
FOR i = 1 TO $cluster3Perf[0] DO
centroid3 = centroid3 + $cluster3Perf[i]
NEXT
centroid3 = centroid3 / $cluster3Perf[0]
//---------------------------------------------------------------//
//-----Objective cluster selection-------------------------------//
//---------------------------------------------------------------//
finalFactor = 0
finalperf = 0
perf = 0
fact = 0
IF fromCluster = 1 THEN
// Best cluster (highest centroid value)
if centroid1 > max(centroid2, centroid3) then
for j = 1 to lastset($cluster1Perf) do
perf = perf + $cluster1Perf[j]
fact = fact + $cluster1Factors[j]
next
finalFactor = fact / lastset($cluster1Factors)
finalPerf = perf / lastset($cluster1Perf)
elsif centroid2 > max(centroid1, centroid3) then
for j = 1 to lastset($cluster2Perf) do
perf = perf + $cluster2Perf[j]
fact = fact + $cluster2Factors[j]
next
finalFactor = fact / lastset($cluster2Factors)
finalPerf = perf / lastset($cluster2Perf)
else
for j = 1 to lastset($cluster3Perf) do
perf = perf + $cluster3Perf[j]
fact = fact + $cluster3Factors[j]
next
finalFactor = fact / lastset($cluster3Factors)
finalPerf = perf / lastset($cluster3Perf)
ENDIF
ELSIF fromCluster = 2 THEN
// Average cluster (intermediate centroid value)
IF centroid1 > centroid2 and centroid1 < centroid3 THEN
for j = 1 to lastset($cluster1Perf) do
perf = perf + $cluster1Perf[j]
fact = fact + $cluster1Factors[j]
next
finalFactor = fact / lastset($cluster1Factors)
finalPerf = perf / lastset($cluster1Perf)
elsif centroid2 > centroid1 and centroid2 < centroid3 THEN
for j = 1 to lastset($cluster2Perf) do
perf = perf + $cluster2Perf[j]
fact = fact + $cluster2Factors[j]
next
finalFactor = fact / lastset($cluster2Factors)
finalPerf = perf / lastset($cluster2Perf)
else
for j = 1 to lastset($cluster3Perf) do
perf = perf + $cluster3Perf[j]
fact = fact + $cluster3Factors[j]
next
finalFactor = fact / lastset($cluster3Factors)
finalPerf = perf / lastset($cluster3Perf)
ENDIF
ELSIF fromCluster = 3 THEN
// Worst cluster (lowest centroid value)
IF centroid1 < min(centroid2, centroid3) THEN
for j = 1 to lastset($cluster1Perf) do
perf = perf + $cluster1Perf[j]
fact = fact + $cluster1Factors[j]
next
finalFactor = fact / lastset($cluster1Factors)
finalPerf = perf / lastset($cluster1Perf)
elsif centroid2 < min(centroid1, centroid3) THEN
for j = 1 to lastset($cluster2Perf) do
perf = perf + $cluster2Perf[j]
fact = fact + $cluster2Factors[j]
next
finalFactor = fact / lastset($cluster2Factors)
finalPerf = perf / lastset($cluster2Perf)
else
for j = 1 to lastset($cluster3Perf) do
perf = perf + $cluster3Perf[j]
fact = fact + $cluster3Factors[j]
next
finalFactor = fact / lastset($cluster3Factors)
finalPerf = perf / lastset($cluster3Perf)
ENDIF
ENDIF
//---------------------------------------------------------------//
//---------------------------------------------------------------//
newup = (high + low) / 2 + atr * finalfactor
newdown = (high + low) / 2 - atr * finalfactor
if close[1] < newupper then
newupper = min(newup, newupper)
else
newupper = newup
endif
if close[1] > newlower then
newlower = max(newdown, newlower)
else
newlower = newdown
endif
if close > newupper then
newOS = 1
elsif close < newlower then
newOS = 0
else
newOS = newOS
endif
if newOS then
newST = newlower
r = 0
g = 255
else
newST = newupper
r = 255
g = 0
endif
//---------------------------------------------------------------//
//---------------------------------------------------------------//
return newST style(point,2)coloured(r,g,0)