TC2000.com• Download software • Tutorial videos • Subscription & data-feed pricing • Class schedule
TC2000Brokerage.com• New account application • Trading resources • Margin rates • Stock & option commissions
Worden Discussion Forum » General Discussions » RealCode for StockFinder 5.0 » harmonics
Here both the up and down indicators, and conditions.
ABCD up :
Name the indicator: AB=CD-up
Sub New AutoLoop = False '# RangePattern = UserInput.Integer = 200 '# NewLowPer = UserInput.Integer = 20 '# PullBackPercent = UserInput.Single = 38.2 '# EntryPercent = UserInput.Single = 23.6 '#RECALC_ON_ZOOM_SCROLL End Sub Public Overrides Function Plot() As System.Single Dim Range(1) As Integer 'Range(1) = price.Bar.count - 1 Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate) Range(0) = Range(1) + 1 - RangePattern Dim BarA As Integer = Range(0) If Range(0) >= 0 Then For i As Integer = Range(0) To Range(1) If Price.Bar.LowValue(i) <= Price.Bar.LowValue(BarA) Then BarA = i End If Next If BarA - Range(0) < NewLowPer AndAlso BarA > 0 Then Dim Count As Integer = 0 For i As Integer = BarA - 1 To 0 Step -1 Count += 1 If Price.Bar.LowValue(i) <= Price.Bar.LowValue(BarA) Then BarA = i Count = 0 End If If Count >= NewLowPer Then Range(0) = BarA Exit For End If Next End If If BarA < Range(1) - 1 Then Dim ABretr As Single = Single.NaN Dim BarB As Integer = BarA Dim BarBqualified(1) As Integer BarBqualified(0) = BarA BarBqualified(1) = BarA Dim BarC As Integer = BarA Dim BarCQualified As Integer = BarA Dim L1 As Integer L1 = BarA For i As Integer = BarA + 1 To Range(1) - 1 If Price.Bar.HighValue(i) > Price.Bar.HighValue(BarB) Then BarB = i BarC = BarB ABretr = PullBackPercent * (Price.Bar.HighValue(BarB) - Price.Bar.LowValue(BarA)) / 100 End If If Price.Bar.lowValue(i) < Price.Bar.highValue(BarB) - ABretr AndAlso i > BarB AndAlso _ price.Bar.lowvalue(i) < price.Bar.lowvalue(BarB) Then If BarC = BarB Then BarC = i Else If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarC) Then BarC = i End If BarBqualified(0) = BarB If BarC > BarCqualified Then For j As Integer = i To Range(1) - 1 If Price.Bar.lowValue(j) <= Price.Bar.lowValue(j - 1) AndAlso _ Price.Bar.lowValue(j) <= Price.Bar.lowValue(j + 1) Then L1 = j BarCqualified = BarC BarBqualified(1) = BarBqualified(0) Exit For End If Next End If End If Next If BarCqualified > BarA Then AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.LowValue(BarA), "A") AddToOutput(Price.Bar.DateValue(BarBqualified(1)), Price.Bar.HighValue(BarBqualified(1)), "B") AddToOutput(Price.Bar.DateValue(BarCqualified), Price.Bar.LowValue(BarCqualified), "C") Dim k As Integer = L1 + 1 If k <= Range(1) Then Dim entry As Single = Price.Bar.LowValue(BarCQualified) Dim B As Single Dim retr As Single Dim projection As Single Dim steptrgt As Single = EntryPercent * (Price.Bar.HighValue(BarBqualified(1)) - Price.Bar.LowValue(BarA)) / 100 Dim AB As Single = price.Bar.highvalue(barBqualified(1)) - price.Bar.lowvalue(BarA) Dim BC As Single = Price.Bar.HighValue(BarBqualified(1)) - price.Bar.lowvalue(BarCqualified) retr = 100 * BC / AB entry = entry + steptrgt B = entry + steptrgt AddToOutput(Price.Bar.DateValue(k), entry, "entry") k += 1 Do Until Price.Bar.Value(k) > entry OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), entry) k += 1 Loop If Price.Bar.Value(k) > entry AndAlso k <= Range(1) Then Dim PRZlow As Single Dim PRZlowtxt As String Dim PRZhigh As Single Dim PRZhightxt As String Select Case retr Case <= 38.2 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZhightxt = "261.8%BC" Case 38.2 To 50 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2 PRZlowtxt = "200%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZhightxt = "261.8%BC" Case 50 To 61.8 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.618 PRZlowtxt = "161.8%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2 PRZhightxt = "200%BC" Case 61.8 To 70.7 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.41 PRZlowtxt = "141%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.618 PRZhightxt = "161.8%BC" Case 70.7 To 78.6 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.27 PRZlowtxt = "127%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.41 PRZhightxt = "141%BC" Case 78.6 To 88.6 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.27 PRZhightxt = "127%BC" Case 88.6 To 100 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZhightxt = "113%BC" End Select AddToOutput(Price.Bar.DateValue(k), PRZlow, PRZlowtxt) k += 1 Do Until Price.Bar.Value(k) > PRZlow OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZlow) k += 1 Loop If Price.Bar.Value(k) > PRZlow AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), PRZhigh, PRZhightxt) k += 1 Do Until Price.Bar.Value(k) > PRZhigh OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZhigh) k += 1 Loop End If End If End If End If End If End If End Function End Class
condition:
'#cumulative '# ABCDup = chart.AB=CD-up
Static Av As Single Static Bv As Single Static ABCDBarCount As Integer If isFirstBar Then Av = Single.NaN Bv = Single.NaN ABCDBarCount = 0 End If If currentindex > price.count - 15 Then If Price.DateValue = ABCDup.DateValue Then ABCDBarCount += 1 If ABCDBarCount = 2 Then Av = ABCDup.Value ' Else If ABCDBarCount >= 6 AndAlso _ ' ABCDup.Value <> ABCDup.Value(1) Then ' Bv = ABCDup.Value End If End If If ABCDBarCount >= 2 Then If (Price.Value(1) < Av AndAlso Price.Value > Av) Then Pass End If End If Else SetIndexInvalid End If
ABCD down:
name the indicator : AB=CD-down
Inherits RealCodeIndicator_base ' Mod ; 3/2/2013 ' removed the level1 sequence. entry is plotted next bar after C is qualified, ' and being a high surrounded by 1 lower or equal high. ' added condition: Zhigh > Yhigh Sub New AutoLoop = False '# RangePattern = UserInput.Integer = 200 '# NewHighPer = UserInput.Integer = 20 '# PullbackPercent = UserInput.Single = 38.2 '# EntryPercent = UserInput.Single = 23.6 '#RECALC_ON_ZOOM_SCROLL End Sub Public Overrides Function Plot() As System.Single Dim Range(1) As Integer 'Range(1) = price.Bar.count - 1 Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate) Range(0) = Range(1) + 1 - RangePattern Dim BarA As Integer = Range(0) If Range(0) >= 0 Then For i As Integer = Range(0) To Range(1) If Price.Bar.HighValue(i) >= Price.Bar.HighValue(BarA) Then BarA = i End If Next If BarA - Range(0) < NewHighPer AndAlso BarA > 0 Then Dim Count As Integer = 0 For i As Integer = BarA - 1 To 0 Step -1 Count += 1 If Price.Bar.HighValue(i) >= Price.Bar.HighValue(BarA) Then BarA = i Count = 0 End If If Count >= NewHighPer Then Range(0) = BarA Exit For End If Next End If If BarA < Range(1) - 1 Then Dim ABretr As Single = Single.NaN Dim BarB As Integer = BarA Dim BarBqualified(1) As Integer BarBqualified(0) = BarA BarBqualified(1) = BarA Dim BarC As Integer = BarA Dim BarCQualified As Integer = BarA Dim L1 As Integer L1 = BarA For i As Integer = BarA + 1 To Range(1) - 1 If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then BarB = i BarC = BarB ABretr = PullbackPercent * (Price.Bar.HighValue(BarA) - Price.Bar.LowValue(BarB)) / 100 End If If Price.Bar.highValue(i) > Price.Bar.lowValue(BarB) + ABretr AndAlso i > BarB AndAlso _ price.Bar.highvalue(i) > price.Bar.highvalue(BarB) Then If BarC = BarB Then BarC = i Else If Price.Bar.HighValue(i) > Price.Bar.HighValue(BarC) Then BarC = i End If BarBqualified(0) = BarB If BarC > BarCqualified Then For j As Integer = i To Range(1) - 1 If Price.Bar.highValue(j) >= Price.Bar.highValue(j - 1) AndAlso _ Price.Bar.highValue(j) >= Price.Bar.highValue(j + 1) Then L1 = j BarCqualified = BarC BarBqualified(1) = BarBqualified(0) Exit For End If Next End If End If Next If BarCqualified > BarBqualified(1) Then AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.highValue(BarA), "A") AddToOutput(Price.Bar.DateValue(BarBqualified(1)), Price.Bar.lowValue(BarBqualified(1)), "B") AddToOutput(Price.Bar.DateValue(BarCqualified), Price.Bar.highValue(BarCqualified), "C") Dim k As Integer = L1 + 1 If k <= range(1) Then Dim entry As Single = Price.bar.highvalue(barCQualified) Dim B As Single Dim retr As Single Dim steptrgt As Single = EntryPercent * (Price.Bar.HighValue(BarA) - Price.Bar.LowValue(BarBqualified(1))) / 100 Dim AB As Single = price.Bar.highvalue(BarA) - price.Bar.lowvalue(BarBqualified(1)) Dim BC As Single = Price.Bar.HighValue(BarCqualified) - price.Bar.lowvalue(BarBqualified(1)) retr = 100 * BC / AB entry = entry - steptrgt B = entry - steptrgt AddToOutput(Price.Bar.DateValue(k), entry, "entry") k += 1 Do Until Price.Bar.Value(k) < entry OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), entry) k += 1 Loop If Price.Bar.Value(k) < entry AndAlso k <= Range(1) Then Dim PRZlow As Single Dim PRZlowtxt As String Dim PRZhigh As Single Dim PRZhightxt As String Select Case retr Case <= 38.2 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZhightxt = "261.8%BC" Case 38.2 To 50 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 2 PRZhightxt = "200%BC" Case 50 To 61.8 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2 PRZlowtxt = "200%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.618 PRZhightxt = "161.8%BC" Case 61.8 To 70.7 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.618 PRZlowtxt = "161.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.41 PRZhightxt = "141%BC" Case 70.7 To 78.6 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.41 PRZlowtxt = "141%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.27 PRZhightxt = "127%BC" Case 78.6 To 88.6 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.27 PRZlowtxt = "127%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZhightxt = "113%BC" Case 88.6 To 100 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZhightxt = "113%BC" End Select AddToOutput(Price.Bar.DateValue(k), PRZhigh, PRZhightxt) k += 1 Do Until Price.Bar.Value(k) < PRZhigh OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZhigh) k += 1 Loop If Price.Bar.Value(k) < PRZhigh AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), PRZlow, PRZlowtxt) k += 1 Do Until Price.Bar.Value(k) < PRZlow OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZlow) k += 1 Loop End If End If End If End If End If End If
End Function End Class
'#cumulative '# ABCDdown = chart.AB=CD-down
Static Av As Single Static Bv As Single Static ABCDBarCount As Integer If isFirstBar Then Av = Single.NaN Bv = Single.NaN ABCDBarCount = 0 End If If currentindex > price.count - 15 Then If Price.DateValue = ABCDdown.DateValue Then ABCDBarCount += 1 If ABCDBarCount = 2 Then Av = ABCDdown.Value 'Else If ABCDBarCount >= 6 AndAlso _ ' ABCDdown.Value <> ABCDdown.Value(1) Then ' Bv = ABCDdown.Value End If End If If ABCDBarCount >= 2 Then If (Price.Value(1) > Av AndAlso Price.Value < Av) Then Pass 'OrElse (Price.Value(1) < Bv AndAlso Price.Value > Bv) End If Else SetIndexInvalid End If
Notes:
to use the conditions, make the following change in the indicators:
'Range(1) = price.Bar.count - 1 Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
to :
Range(1) = price.Bar.count - 1 'Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
this turns of the "Zoom" capability, and will, regardless whether you slide your chart back and forth in time, only plot the most recent pattern.
the conditions return true, when either the "entry" level gets broken, or one of the targets, within the most recent 15 bars.
I made this limitation to reduce CPU load.
Before you use this indicator, make sure you fully understand how it works, and what it supposed to indicate.
I like to go long once the entry level gets broken on the ABCD-up indicator, or go long when price reverses out of the PRZ of a ABCD-down pattern, when larger timeframes are in an uptrend.
vice-versa for shorts.
The conditions seem to work well, although I suspect they're not 100%.
If you have any feedback, additions, modifications, please post.
That is some serious coding; no wonder my pathetic efforts fail so miserably. Thanks for sharing- I look forward to checking it out this weekend.
LoL feltburner, but I'm just leeching of Bruce's knowledge, and tireless support. He deserves most of the credit.
Hope to get some feedbacks/recommendations here.
One Idea I have is to include some options to increase probability for a trade at either the PRZ or between the C and entry point, bylooking for maybe some candlestick formations, in those areas. or some divergences from other indicators.
Getting quite a few compile errors in each and can't run them quite yet. I'm sure it'll get worked out, likely my oversight. Thank you for sharing.
create new realcode indicator
then select "class"
copy the code under "inherits realcodeIndicator_base"
should look like this :
http://screencast.com/t/rZflUlS51
pthegreat,
Also had trouble getting the indicators to run but after reading your instructions and viewing your image I have the indicators working. Is the code for the conditions entered into the "code" area or the "class" area? Still haven't got them working yet.
Thanks,
Bruce
code
Thanks again for sharing! I was never a fan of fib but i am now. There are compelling arguments for point C to be included as a condition, when use in conjunction with other indicators can confirm C. Also I believe there are trading opportunities between point C and entry point.
Agilisllc.
Thanks, it's all up and running now.
I've tried to alter above code to include 423.6% with no luck, what i'm i doing wrong?
Select Case retr
Case <= 26.4 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 4.236 PRZlowtxt = "423.6%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 4.236 PRZhightxt = "423.6%BC" Case 26.4 To 38.2 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 4.236 PRZhightxt = "423.6%BC"
looks fine to me.
click on the indicator and change "PullbackPercent" to 23.6, so it will find patterns that have a pullback less then the default 38.2%
http://screencast.com/t/cGC4XA26u7
AB=CD, stops dawing at random points 127%, 141% etc ... almost never draws 261.8%, is anyone else having this issue?
Agilisllc,
they are not random.
see page 41 "harmonic trading"
the drawn projections (PRZ) relate directly to the BC retrace of the AB leg.
I explained it in my 1st post in the other harmonic thread.
an example:
if BC is a retrace of AB between 61.8% and 70/7%, then I use the projection values 161.8 and 141% to determine the PRZ
If however, the retrace is between 38.2% and 50% then 200% and 261.8% will be used.
for example V on 15min chart
BC is between 38.2% and 50% retrace of AB, therefore the 1st PRZ target is 200%BC.
when price fell below this line, it drew the 261.8%, that's your PRZ!
note: my indicator is a slight variant of the AB=CD as described in the book. since they also use the exact range of AB, to set a PRZ target.
again, this indicator, follows the definitions of AB=CD patterns only.
If you delve into the various harmonic patterns, you'll see that depending on the pattern, the projections of the AB=CD in the harmonic pattern will use different projections then the reciprocal ratios used, when you use the AB=CD indicator stand alone.
another example:
GS 60min chart:
XABCD paints a "Crab" pattern.
although the BC is about 78.6% retrace of AB, and therefore it should use a 127% and 141% projection of AB, the fact that it is part of a Crab pattern, a projection of between 224% to 361.8% should be used.
here depicted using fibs in TC2000 :
As you see, so far it hit the 261.8% spot on, if fails we can look at 300%, up to 361.8%
However the Stockfinder AB=CD indicator only painted the PRZ relating to a 70.7% to 78.6% retrace, which are 127% and 141%
eventhough it is part of the crab pattern, and therefore larger projections should be used. the AB=CD's PRZ gave a good signal as well for a short bounce out of the PRZ.
Plan is to program the additional patterns, but just to busy with trading at the moment.
Just keep the forementioned in mind, hope it helps,
P.
sorry:
should read:
although the BC is about 78.6% retrace of AB, and therefore it should use a 127% and 141% projection of BC, the fact that it is part of a Crab pattern, a projection of between 224% to 361.8% should be used.
pthegreat
thanks for the clarification, I incorrectly assumed AB=CD would recalculate and project new fib levels as price history surpasses PRZ levels. It would be a great addition to the indicator, though i'm not sure its possible.
p.s AB=CD indicator has been spot on....
thx for the suggestion. I'm still breaking my head over how I will continue coding this out.
But adding the range of AB to predict CD is something I will add for sure.
SPY for example on 5min: 4/2 high to 4/3 low, subtract from 4/4 high, gave the exact low today, and eventhough after a big drop I did get some 154 weekly calls, which got a 150% return. stopped exactly at the 38.2% retrace of 4/4 high and 113% projection 4/3 low - 4/4high
the range AB, projected from point C always falls somewhere between the two fibs that calculate the PRZ.
in any case, hope to pick up with coding something soon.
take care.
update:
added "D" target as range A-high to B-low subtracted from C-high (in case of down pattern), or range A-low to B-high added to C-low (in case of up pattern).
and added text to Cpoint with the exact retrace%
If you have the previous indicator on your chart, simply rightclick it, "edit realcode" then select "class",
and replace everything below "inherits RealCodeIndicator_base" with the code below.
' Mod ; 3/2/2013 ' removed the level1 sequence. entry is plotted next bar after C is qualified, ' and being a high surrounded by 1 lower or equal high. ' added condition: Chigh > Bhigh ' Mod ; 4/1/2013 ' made "zooming" a userinput ' Mod ; 4/7/2013 ' add retrace% to pointC ' add D projection as AB=CD range Sub New AutoLoop = False '# RangePattern = UserInput.Integer = 200 '# NewHighPer = UserInput.Integer = 20 '# PullbackPercent = UserInput.Single = 38.2 '# EntryPercent = UserInput.Single = 23.6 '# Zoom = userinput.integer = 0 '#RECALC_ON_ZOOM_SCROLL End Sub Public Overrides Function Plot() As System.Single Dim Range(1) As Integer If Zoom = 0 Then Range(1) = price.Bar.count - 1 Else Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate) End If Range(0) = Range(1) + 1 - RangePattern Dim BarA As Integer = Range(0) If Range(0) >= 0 Then For i As Integer = Range(0) To Range(1) If Price.Bar.HighValue(i) >= Price.Bar.HighValue(BarA) Then BarA = i End If Next If BarA - Range(0) < NewHighPer AndAlso BarA > 0 Then Dim Count As Integer = 0 For i As Integer = BarA - 1 To 0 Step -1 Count += 1 If Price.Bar.HighValue(i) >= Price.Bar.HighValue(BarA) Then BarA = i Count = 0 End If If Count >= NewHighPer Then Range(0) = BarA Exit For End If Next End If If BarA < Range(1) - 1 Then Dim ABretr As Single = Single.NaN Dim ABpercentRetr As Single Dim BarB As Integer = BarA Dim BarBqualified(1) As Integer BarBqualified(0) = BarA BarBqualified(1) = BarA Dim BarC As Integer = BarA Dim BarCQualified As Integer = BarA Dim Ctxt As String Dim L1 As Integer L1 = BarA For i As Integer = BarA + 1 To Range(1) - 1 If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then BarB = i BarC = BarB ABretr = PullbackPercent * (Price.Bar.HighValue(BarA) - Price.Bar.LowValue(BarB)) / 100 End If If Price.Bar.highValue(i) > Price.Bar.lowValue(BarB) + ABretr AndAlso i > BarB AndAlso _ price.Bar.highvalue(i) > price.Bar.highvalue(BarB) Then If BarC = BarB Then BarC = i Else If Price.Bar.HighValue(i) > Price.Bar.HighValue(BarC) Then BarC = i End If BarBqualified(0) = BarB If BarC > BarCqualified Then For j As Integer = i To Range(1) - 1 If Price.Bar.highValue(j) >= Price.Bar.highValue(j - 1) AndAlso _ Price.Bar.highValue(j) >= Price.Bar.highValue(j + 1) Then L1 = j BarCqualified = BarC BarBqualified(1) = BarBqualified(0) ABpercentRetr = (price.Bar.highvalue(BarCqualified) - price.Bar.lowvalue(BarBqualified(1))) / _ (price.Bar.highvalue(BarA) - price.Bar.lowvalue(BarBqualified(1))) * 100 Ctxt = "C=" & ABpercentRetr.ToString("N2") & "%" Exit For End If Next End If End If Next If BarCqualified > BarBqualified(1) Then AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.highValue(BarA), "A") AddToOutput(Price.Bar.DateValue(BarBqualified(1)), Price.Bar.lowValue(BarBqualified(1)), "B") AddToOutput(Price.Bar.DateValue(BarCqualified), Price.Bar.highValue(BarCqualified), Ctxt) Dim k As Integer = L1 + 1 If k <= range(1) Then Dim entry As Single = Price.bar.highvalue(barCQualified) Dim B As Single Dim retr As Single Dim steptrgt As Single = EntryPercent * (Price.Bar.HighValue(BarA) - Price.Bar.LowValue(BarBqualified(1))) / 100 Dim AB As Single = price.Bar.highvalue(BarA) - price.Bar.lowvalue(BarBqualified(1)) Dim BC As Single = Price.Bar.HighValue(BarCqualified) - price.Bar.lowvalue(BarBqualified(1)) retr = 100 * BC / AB entry = entry - steptrgt AddToOutput(Price.Bar.DateValue(k), entry, "entry") k += 1 Do Until Price.Bar.Value(k) < entry OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), entry) k += 1 Loop If Price.Bar.Value(k) < entry AndAlso k <= Range(1) Then Dim PRZlow As Single Dim PRZlowtxt As String Dim PRZhigh As Single Dim PRZhightxt As String Dim D As Single D = price.Bar.Highvalue(BarCqualified) - (Price.Bar.HighValue(BarA) - Price.Bar.LowValue(BarBqualified(1))) Select Case retr Case <= 38.2 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZhightxt = "261.8%BC" Case 38.2 To 50 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 2 PRZhightxt = "200%BC" Case 50 To 61.8 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 2 PRZlowtxt = "200%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.618 PRZhightxt = "161.8%BC" Case 61.8 To 70.7 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.618 PRZlowtxt = "161.8%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.41 PRZhightxt = "141%BC" Case 70.7 To 78.6 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.41 PRZlowtxt = "141%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.27 PRZhightxt = "127%BC" Case 78.6 To 88.6 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.27 PRZlowtxt = "127%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZhightxt = "113%BC" Case 88.6 To 100 PRZlow = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.Highvalue(BarCqualified) - BC * 1.13 PRZhightxt = "113%BC" End Select AddToOutput(Price.Bar.DateValue(k), PRZhigh, PRZhightxt) k += 1 Do Until Price.Bar.Value(k) < PRZhigh OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZhigh) k += 1 Loop If Price.Bar.Value(k) < PRZhigh AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), D, "D") k += 1 Do Until Price.Bar.Value(k) < D OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), D) k += 1 Loop If Price.Bar.Value(k) < D AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), PRZlow, PRZlowtxt) k += 1 Do Until Price.Bar.Value(k) < PRZlow OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZlow) k += 1 Loop End If End If End If End If End If End If End If end function End Class
inherits RealCodeIndicator_base ' Mod ; 3/2/2013 ' removed the level1 sequence. entry is plotted next bar after C is qualified, ' and being a low surrounded by 1 higher or equal low. ' added condition: Clow > Blow ' Mod ; 4/1/2013 ' made "zooming" a userinput ' Mod ; 4/7/2013 ' add retrace% to pointC ' add D projection as AB=CD range Sub New AutoLoop = False '# RangePattern = UserInput.Integer = 200 '# NewLowPer = UserInput.Integer = 20 '# PullBackPercent = UserInput.Single = 38.2 '# EntryPercent = UserInput.Single = 23.6 '# Zoom = userinput.integer = 0 '#RECALC_ON_ZOOM_SCROLL End Sub Public Overrides Function Plot() As System.Single Dim Range(1) As Integer If Zoom = 0 Then Range(1) = price.Bar.count - 1 Else Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate) End If Range(0) = Range(1) + 1 - RangePattern Dim BarA As Integer = Range(0) If Range(0) >= 0 Then For i As Integer = Range(0) To Range(1) If Price.Bar.LowValue(i) <= Price.Bar.LowValue(BarA) Then BarA = i End If Next If BarA - Range(0) < NewLowPer AndAlso BarA > 0 Then Dim Count As Integer = 0 For i As Integer = BarA - 1 To 0 Step -1 Count += 1 If Price.Bar.LowValue(i) <= Price.Bar.LowValue(BarA) Then BarA = i Count = 0 End If If Count >= NewLowPer Then Range(0) = BarA Exit For End If Next End If If BarA < Range(1) - 1 Then Dim ABretr As Single = Single.NaN Dim ABpercentRetr As Single Dim BarB As Integer = BarA Dim BarBqualified(1) As Integer BarBqualified(0) = BarA BarBqualified(1) = BarA Dim BarC As Integer = BarA Dim BarCQualified As Integer = BarA Dim Ctxt As String Dim L1 As Integer L1 = BarA For i As Integer = BarA + 1 To Range(1) - 1 If Price.Bar.HighValue(i) > Price.Bar.HighValue(BarB) Then BarB = i BarC = BarB ABretr = PullBackPercent * (Price.Bar.HighValue(BarB) - Price.Bar.LowValue(BarA)) / 100 End If If Price.Bar.lowValue(i) < Price.Bar.highValue(BarB) - ABretr AndAlso i > BarB AndAlso _ price.Bar.lowvalue(i) < price.Bar.lowvalue(BarB) Then If BarC = BarB Then BarC = i Else If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarC) Then BarC = i End If BarBqualified(0) = BarB If BarC > BarCqualified Then For j As Integer = i To Range(1) - 1 If Price.Bar.lowValue(j) <= Price.Bar.lowValue(j - 1) AndAlso _ Price.Bar.lowValue(j) <= Price.Bar.lowValue(j + 1) Then L1 = j BarCqualified = BarC BarBqualified(1) = BarBqualified(0) ABpercentRetr = (price.Bar.highvalue(BarBqualified(1)) - price.Bar.lowvalue(BarCqualified)) / _ (price.Bar.highvalue(BarBqualified(1)) - price.Bar.lowvalue(BarA)) * 100 Ctxt = "C=" & ABpercentRetr.ToString("N2") & "%" Exit For End If Next End If End If Next If BarCqualified > BarBqualified(1) Then AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.LowValue(BarA), "A") AddToOutput(Price.Bar.DateValue(BarBqualified(1)), Price.Bar.HighValue(BarBqualified(1)), "B") AddToOutput(Price.Bar.DateValue(BarCqualified), Price.Bar.LowValue(BarCqualified), Ctxt) Dim k As Integer = L1 + 1 If k <= Range(1) Then Dim entry As Single = Price.Bar.LowValue(BarCQualified) Dim B As Single Dim retr As Single Dim projection As Single Dim steptrgt As Single = EntryPercent * (Price.Bar.HighValue(BarBqualified(1)) - Price.Bar.LowValue(BarA)) / 100 Dim AB As Single = price.Bar.highvalue(barBqualified(1)) - price.Bar.lowvalue(BarA) Dim BC As Single = Price.Bar.HighValue(BarBqualified(1)) - price.Bar.lowvalue(BarCqualified) retr = 100 * BC / AB entry = entry + steptrgt B = entry + steptrgt AddToOutput(Price.Bar.DateValue(k), entry, "entry") k += 1 Do Until Price.Bar.Value(k) > entry OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), entry) k += 1 Loop If Price.Bar.Value(k) > entry AndAlso k <= Range(1) Then Dim PRZlow As Single Dim PRZlowtxt As String Dim PRZhigh As Single Dim PRZhightxt As String Dim D As Single D = price.Bar.lowvalue(BarCqualified) + (Price.Bar.HighValue(BarBqualified(1)) - Price.Bar.LowValue(BarA)) Select Case retr Case <= 38.2 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZlowtxt = "261.8%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZhightxt = "261.8%BC" Case 38.2 To 50 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2 PRZlowtxt = "200%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618 PRZhightxt = "261.8%BC" Case 50 To 61.8 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.618 PRZlowtxt = "161.8%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2 PRZhightxt = "200%BC" Case 61.8 To 70.7 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.41 PRZlowtxt = "141%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.618 PRZhightxt = "161.8%BC" Case 70.7 To 78.6 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.27 PRZlowtxt = "127%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.41 PRZhightxt = "141%BC" Case 78.6 To 88.6 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.27 PRZhightxt = "127%BC" Case 88.6 To 100 PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZlowtxt = "113%BC" PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.13 PRZhightxt = "113%BC" End Select AddToOutput(Price.Bar.DateValue(k), PRZlow, PRZlowtxt) k += 1 Do Until Price.Bar.Value(k) > PRZlow OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZlow) k += 1 Loop If Price.Bar.Value(k) > PRZlow AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), D, "D") k += 1 Do Until Price.Bar.Value(k) > D OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), D) k += 1 Loop If Price.Bar.Value(k) > D AndAlso k <= Range(1) Then AddToOutput(Price.Bar.DateValue(k), PRZhigh, PRZhightxt) k += 1 Do Until Price.Bar.Value(k) > PRZhigh OrElse k > Range(1) AddToOutput(Price.Bar.DateValue(k), PRZhigh) k += 1 Loop End If End If End If End If End If End If End If end function End Class
quick example:
GLD reversed out of the down PRZ zone, defined by a 200% projection and D
a note on the condition that I'm using to sort a watchlist:
In case of a down pattern, it triggeres when price breaks a level to the DOWNside only.
This is correct, in case you use these patterns to take aggresive trades at the "entry" level.
However you can take trades when price reverse out of the PRZ zone, in which case price surpasses the PRZ level to the UPside. so I have to either rewrite the condition, or add another one to sort for reversals to the UPside.
Hope this makes sense.
Pthegreat
Ctxt = "C=" & ABpercentRetr.ToString("N2") & "%"
In reference to above line, can the high/low value of the bar be added?
we could probably plot a line at the high of point C of a ABCDup pattern and a line at the low of point C of a down pattern, like so:, and add txt to point C with the lowofbar (ABCDup), and highofbar on ABCDup
good idea, to get a very early entry on the pattern, right?
That is correct, my objective is to use the value at point C as a SellStop (low of bar).
Not sure if a condition can be created at that point also ?
New member here, and first a thank you to Pthegreat for posting all your work re:harmonics.
I was on your other thread and downloaded your excel sheet and have been playing around with that. I'm really impressed with how accurate it is.
That thread brought me here, and it looks like the formula above is an automated way to identify AB=CD patterns.
The Worden site is new to me and I've been testing a few indicators, trying to learn the system, but; I'm at a loss as to how to input your code.
I'm opening the indicator formula box, then pasting your formula. I end up with an error message.
I'm probably doing somthing really basic that is wrong - not sure where to look for answers.
Perhaps this is a question for Bruce L, don't know.
Any suggestions appreciated.
Thanks
welcome MCPP
did a quick video on how to add the indicators/conditions.
http://screencast.com/t/OYICHOXnHT
couple of notes:
once you have them working, rightclick the indicator, and select edit.
right top corner of the popupscreen you'll see the userinput variables for the indicator
although the PullbackPercent is set to 38.2 at default, I usually change it to 37, and sometimes, once you get some experience finding the patterns, you might want to experiment with the RangePattern setting. I use setting s between 150 and 300 or so. It simply limits the amount of bars within the indicator can qualify a pattern.
Hope this helps.
Great, thanks for the info pthegreat.. I will give it a try tomorrow.
Here is an another new member. I'm new to StockFinder as well as harmonics, but I learned harmonics had great potential for swing trades. I appreciate pthegreat (Peter?) for providing us a nice coding example.
While I was using and reading Peter's code from this thread, I thought I could improve the implementation;
Using ATR to remove *noise* from ZigZag
I sometimes got annoyed by the fact that a small spike/dip of price would trigger flipping AB=CD target. Since I'm a midium term swing trader, I wanted to ignore those small price movement, then I found someone wrote a code that uses ATR to determin the threshold of ZigZag. See http://forums.worden.com/default.aspx?g=posts&t=42846
Decoupling of model and view (aka "separation of concerns")
As a Python programmer, I would say most of those examples of RealCode are !#$@!#%*$. Many people are stuffing up monolithtic code into Plot() method. I still think Plot() is a good place to write a simple and small indicator, but I disagree to put everything inside Plot() when the indicator is complicated.
So.... I wrote my own version of AB=CD indicator. I would say this is an MVP (Minimum Viable Product). It only provides AB=CD target at this moment. I'll add more features day by day.
Public partial Class RealCodeIndicator Inherits RealCodeIndicator_base Public Overrides function Plot() as System.Single ' Original: http://forums.worden.com/default.aspx?g=posts&t=42846 '# Period = UserInput.Single = 14 '# Factor = UserInput.Single = 3 Static ZZ As MyZigZag Static ABCD As ABCD If isFirstBar Then ZZ = New MyZigZag(Price, Period, Factor) ABCD = New ABCD() Plot = Single.NaN Else ZZ.PrePlot(Price) If ZZ.IsExtreme(Price) Then ABCD.AddExtreme(ZZ.GetExtremePrice()) AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice()) End If ZZ.PostPlot(Price, Factor) End If If isLastBar Then AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice) Plot = Single.NaN end function End Class Class ABCD Private _Extremes(4) As Single Public Sub New() _Extremes(0) = Single.NaN _Extremes(1) = Single.NaN _Extremes(2) = Single.NaN _Extremes(3) = Single.NaN End Sub Public Sub AddExtreme(Value As Single) _Extremes(3) = _Extremes(2) _Extremes(2) = _Extremes(1) _Extremes(1) = _Extremes(0) _Extremes(0) = Value End Sub End Class Class MyZigZaG Private _TR As Single Private _TermRatio As Single Private _ATR As Single Private _SumWeight As Single Private _Weight As Single Private _ExtDate As Date Private _Extreme As Single Private _Tstop As Single Private _State As ZZState Public Sub New(Price, Period, Factor) _TR = Price.High - Price.Low _TermRatio = (Period - 1) / Period _ATR = _TR _SumWeight = _TermRatio + 1 _Weight = 1 / _SumWeight _ExtDate = Price.DateValue If _StartsFromExtremeLow(Price) Then _Extreme = Price.Low _Tstop = System.Math.Max(Price.High, _Extreme + Factor * _ATR) _State = ZZState.Down Else _Extreme = Price.High _Tstop = System.Math.Min(Price.Low, _Extreme - Factor * _ATR) _State = ZZState.Up End If End Sub Private Function _StartsFromExtremeLow(Price) As Boolean Return Price.High(-1) - System.Math.Min(Price.Low, Price.Low(-1)) < _ System.Math.Max(Price.High, Price.High(-1)) - Price.Low(-1) End Function Public Function GetExtremeDate() As Date Return _ExtDate End Function Public Function GetExtremePrice() As Single Return _Extreme End Function Private Sub _SetDownState() _State = ZZState.Down End Sub Private Sub _SetUpState() _State = ZZState.Up End Sub Public Sub PrePlot(Price) _TR = (Price.High - Price.Low + _ System.Math.Abs(Price.High - Price.Last(1)) + _ System.Math.Abs(Price.Last(1) - Price.Low)) / 2 _ATR = _ATR * (1 - _Weight) + _Weight * _TR _SumWeight = _SumWeight * _TermRatio + 1 _Weight = 1 / _SumWeight End Sub Private Function _IsUp() As Boolean Return _State = ZZState.Up End Function Private Function _IsDown() As Boolean Return _State = ZZState.Down End Function Private Sub _UpdateDirectionToDown(Price, Factor) _SetDownState() _Extreme = Price.Low _ExtDate = Price.DateValue _TStop = System.Math.Max(Price.High, GetExtremePrice() + factor * _ATR) End Sub Private Sub _UpdateDirectionToUp(Price, Factor) _SetUpState() _Extreme = Price.High _ExtDate = Price.DateValue _TStop = System.Math.Min(Price.Low, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateDirection(Price, Factor) If _IsUp() And (Price.Low < _TStop) Then _UpdateDirectionToDown(Price, Factor) ElseIf _IsDown() And (Price.High > _TStop) Then _UpdateDirectionToUp(Price, Factor) End If End Sub Private Sub _UpdateExtremeHigh(Price, Factor) If Price.High >= GetExtremePrice() Then _Extreme = Price.High _ExtDate = Price.DateValue End If _TStop = System.Math.Max(_TStop, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateExtremeLow(Price, Factor) If Price.Low <= GetExtremePrice Then _Extreme = Price.Low _ExtDate = Price.DateValue End If _TStop = System.Math.Min(_TStop, GetExtremePrice() + Factor * _ATR) End Sub Private Sub _UpdateExtreme(Price, Factor) If _IsUp() Then _UpdateExtremeHigh(Price, Factor) Else _UpdateExtremeLow(Price, Factor) End If End Sub Public Sub PostPlot(Price, Factor) _UpdateDirection(Price, Factor) _UpdateExtreme(Price, Factor) End Sub Public Function IsExtreme(Price) As Boolean If _state = ZZState.Up And Price.Low < _TStop Then Return True If _State = ZZState.Down And Price.High > _TStop Then Return True Return False End Function End Class Enum ZZState Up = 1 Down = 2 End Enum
Oops. Discard previous code as I pasted a wrong one. Here is the working version.
Public partial Class RealCodeIndicator Inherits RealCodeIndicator_base Public Overrides function Plot() as System.Single ' Original: http://forums.worden.com/default.aspx?g=posts&t=42846 '# Period = UserInput.Single = 14 '# Factor = UserInput.Single = 3 Static ZZ As MyZigZag Static ABCD As ABCD If isFirstBar Then ZZ = New MyZigZag(Price, Period, Factor) ABCD = New ABCD() Plot = Single.NaN Else ZZ.PrePlot(Price) If ZZ.IsExtreme(Price) Then ABCD.AddExtreme(ZZ.GetExtremePrice()) AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice()) End If ZZ.PostPlot(Price, Factor) End If If isLastBar Then ABCD.AddExtreme(ZZ.GetExtremePrice()) AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice, ABCD.Display()) End If Plot = Single.NaN End Function End Class Class ABCD Private _Extremes(4) As Single Private _Output As String Public Sub New() _Extremes(0) = Single.NaN _Extremes(1) = Single.NaN _Extremes(2) = Single.NaN _Extremes(3) = Single.NaN _Output = "" End Sub Public Sub AddExtreme(Value As Single) _Extremes(3) = _Extremes(2) _Extremes(2) = _Extremes(1) _Extremes(1) = _Extremes(0) _Extremes(0) = Value End Sub Private Sub _AddToOutput(Str As String) _Output = _Output & Str & System.Environment.NewLine End Sub Private Function _OutputAsC() Dim Out As String = "If this is C Then" & System.Environment.NewLine Dim AB As Single = _Extremes(1) - _Extremes(2) Return Out & " D would be " & AB + _Extremes(0) End Function Private Function _OutputAsD() Dim Out As String = "If this is D Then" & System.Environment.NewLine Dim AB As Single = _Extremes(2) - _Extremes(3) Return Out & " Target would be " & AB + _Extremes(1) End Function Public Function Display() As String _AddToOutput(_OutputAsC()) _AddToOutput(_OutputAsD()) Return _Output End Function End Class Class MyZigZaG Private _TR As Single Private _TermRatio As Single Private _ATR As Single Private _SumWeight As Single Private _Weight As Single Private _ExtDate As Date Private _Extreme As Single Private _Tstop As Single Private _State As ZZState Public Sub New(Price, Period, Factor) _TR = Price.High - Price.Low _TermRatio = (Period - 1) / Period _ATR = _TR _SumWeight = _TermRatio + 1 _Weight = 1 / _SumWeight _ExtDate = Price.DateValue If _StartsFromExtremeLow(Price) Then _Extreme = Price.Low _Tstop = System.Math.Max(Price.High, _Extreme + Factor * _ATR) _State = ZZState.Down Else _Extreme = Price.High _Tstop = System.Math.Min(Price.Low, _Extreme - Factor * _ATR) _State = ZZState.Up End If End Sub Private Function _StartsFromExtremeLow(Price) As Boolean Return Price.High(-1) - System.Math.Min(Price.Low, Price.Low(-1)) _TStop) Then _UpdateDirectionToUp(Price, Factor) End If End Sub Private Sub _UpdateExtremeHigh(Price, Factor) If Price.High >= GetExtremePrice() Then _Extreme = Price.High _ExtDate = Price.DateValue End If _TStop = System.Math.Max(_TStop, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateExtremeLow(Price, Factor) If Price.Low _TStop Then Return True Return False End Function End Class Enum ZZState Up = 1 Down = 2 End Enum
thanks for the sharing masayang, but the second code, has errors
Hmm. That code works on my environment, SF 5.0.39.17229 on Windows Server 2012. What kind of error did you get actually?
In your code where is
ZZ.PostPlot(Price, Factor)
Sorry folks. I confirmed that code didn't work.
Here is an updated version. Now it displays AB=CD target as well as BAT, Gartley, Crab, or Butterfly target when available.
Public Overrides function Plot() as System.Single ' Original: http://forums.worden.com/default.aspx?g=posts&t=42846 '# Period = UserInput.Single = 14 '# Factor = UserInput.Single = 3 Static ZZ As MyZigZag Static XABCD As XABCD If isFirstBar Then ZZ = New MyZigZag(Price, Period, Factor) XABCD = New XABCD() Plot = Single.NaN Else ZZ.PrePlot(Price) If ZZ.IsExtreme(Price) Then XABCD.AddExtreme(ZZ.GetExtremePrice()) AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice()) End If ZZ.PostPlot(Price, Factor) End If If isLastBar Then XABCD.AddExtreme(ZZ.GetExtremePrice()) AddToOutput(ZZ.GetExtremeDate(), ZZ.GetExtremePrice, XABCD.Display()) End If Plot = Single.NaN end function End Class Class XABCD Private _Extremes(5) As Single Private _Output As String Public Sub New() _Extremes(0) = Single.NaN 'D _Extremes(1) = Single.NaN 'C _Extremes(2) = Single.NaN 'B _Extremes(3) = Single.NaN 'A _Extremes(4) = Single.NaN 'X _Output = "" End Sub Public Sub AddExtreme(Value As Single) _Extremes(4) = _Extremes(3) _Extremes(3) = _Extremes(2) _Extremes(2) = _Extremes(1) _Extremes(1) = _Extremes(0) _Extremes(0) = Value End Sub Private Function XA() As Single Return _Extremes(3) - _Extremes(4) End Function Private Function AB() As Single Return _Extremes(3) - _Extremes(2) End Function Private Function BC() As Single Return _Extremes(1) - _Extremes(2) End Function Private Function CD() As Single Return _Extremes(1) - _Extremes(0) End Function Private Function isCrab() As Boolean 'AB >= 0.382XA and AB <=0.618XA If AB() < 0.352 * XA() Then Return False If AB() > 0.648 * XA() Then Return False 'BC >= 0.382AB and BC <= 0.886AB If BC() < 0.352 * AB() Then Return False If BC() > 0.916 * AB() Then Return False 'CD >= 2.618BC and CD <= 3.618CD 'If CD() < 2.588 * BC() Then Return False 'If CD() > 3.648 * BC() Then Return False Return True End Function Private Function isDeepCrab() As Boolean 'AB=0.886XA If AB() < 0.856 * XA() Then Return False If AB() > 0.916 * XA() Then Return False 'BC >= 0.382AB and BC < 0.886AB If BC() < 0.352 * AB() Then Return False If BC() > 0.916 * AB() Then Return False 'CD >= 2.24BC and CD <= 3.618BC 'If CD() < 2.21 * BC() Then Return False 'If CD() > 3.648 * BC() Then Return False Return True End Function Private Function isButterfly() As Boolean 'AB=0.786XA If AB() < 0.756 * XA() Then Return False If AB() > 0.816 * XA() Then Return False 'BC>=0.382AB and BC<=0.886AB If BC() < 0.352 * AB() Then Return False If BC() > 0.916 * AB() Then Return False 'CD>=1.618BC and CD<=2.24BC 'If CD() < 1.588 * BC() Then Return False 'If CD() > 2.27 * BC() Then Return False Return True End Function Private Function isGartley() As Boolean 'AB=0.618XA If AB() < 0.588 * XA() Then Return False If AB() > 0.648 * XA() Then Return False '=and(C7>=0.382, C7<=0.886) 'BC >= 0.382AB and BC <= 0.886AB If BC() < 0.352 * AB() Then Return False If BC() > 0.916 * AB() Then Return False 'CD >= 1.13BC and CD <= 1.618BC 'If CD() < 1.1 * BC() Then Return False 'If CD() > 0.916 * BC() Then Return False Return True End Function Private Function isBAT() As Boolean 'AB >= 0.382XA AND AB <= 0.5XA If AB() < 0.382 * XA() Then Return False If AB() > 0.5 * XA() Then Return False 'BC >= 0.382AB and BC <= 0.886AB If BC() < 0.382 * AB() Then Return False If BC() > 0.886 * AB() Then Return False '=and(C8>=1.618, C8<=2.618) 'CD >= 1.618BC and CD <= 2.618BC 'If CD() < 1.618 * BC() Then Return False 'If CD() > 2.618 * BC() Then Return False Return True End Function Private Sub _AddToOutput(Str As String) _Output = _Output & Str & System.Environment.NewLine End Sub Private Function BatTarget() As Single 'A - * 0.886XA Return _Extremes(3) - XA() * 0.886 End Function Private Function GartleyTarget() As Single 'A - 0.786XA return _Extremes(3)-0.786*XA() End Function Private Function CrabTarget() As Single 'A - 1.618*XA return _Extremes(3) - 1.618*XA() End Function Private Function DeepCrabTarget() As Single return CrabTarget() End Function Private Function ButterflyTarget() As Single 'A - 1.27XA() Return _Extremes(3) - 1.27 * XA() End Function Private Function ABCDTarget() As Single Return _Extremes(1) - AB() End Function Public Function Display() As String _AddToOutput("AB=CD Target=" & ABCDTarget()) If isBAT() Then _AddToOutput("BAT Target=" & BatTarget()) If isGartley() Then _AddToOutput("Gartley Target=" & GartleyTarget()) If isCrab() Then _AddToOutput("Crab Target=" & CrabTarget()) If isDeepCrab() Then _AddToOutput("Deep Crab Target=" & DeepCrabTarget()) If isButterfly() Then _AddToOutput("Butterfly Target=" & ButterflyTarget()) Return _Output End Function End Class Class MyZigZaG Private _TR As Single Private _TermRatio As Single Private _ATR As Single Private _SumWeight As Single Private _Weight As Single Private _ExtDate As Date Private _Extreme As Single Private _Tstop As Single Private _State As ZZState Public Sub New(Price, Period, Factor) _TR = Price.High - Price.Low _TermRatio = (Period - 1) / Period _ATR = _TR _SumWeight = _TermRatio + 1 _Weight = 1 / _SumWeight _ExtDate = Price.DateValue If _StartsFromExtremeLow(Price) Then _Extreme = Price.Low _Tstop = System.Math.Max(Price.High, _Extreme + Factor * _ATR) _State = ZZState.Down Else _Extreme = Price.High _Tstop = System.Math.Min(Price.Low, _Extreme - Factor * _ATR) _State = ZZState.Up End If End Sub Private Function _StartsFromExtremeLow(Price) As Boolean Return Price.High(-1) - System.Math.Min(Price.Low, Price.Low(-1)) < _ System.Math.Max(Price.High, Price.High(-1)) - Price.Low(-1) End Function Public Function GetExtremeDate() As Date Return _ExtDate End Function Public Function GetExtremePrice() As Single Return _Extreme End Function Private Sub _SetDownState() _State = ZZState.Down End Sub Private Sub _SetUpState() _State = ZZState.Up End Sub Public Sub PrePlot(Price) _TR = (Price.High - Price.Low + _ System.Math.Abs(Price.High - Price.Last(1)) + _ System.Math.Abs(Price.Last(1) - Price.Low)) / 2 _ATR = _ATR * (1 - _Weight) + _Weight * _TR _SumWeight = _SumWeight * _TermRatio + 1 _Weight = 1 / _SumWeight End Sub Private Function _IsUp() As Boolean Return _State = ZZState.Up End Function Private Function _IsDown() As Boolean Return _State = ZZState.Down End Function Private Sub _UpdateDirectionToDown(Price, Factor) _SetDownState() _Extreme = Price.Low _ExtDate = Price.DateValue _TStop = System.Math.Max(Price.High, GetExtremePrice() + factor * _ATR) End Sub Private Sub _UpdateDirectionToUp(Price, Factor) _SetUpState() _Extreme = Price.High _ExtDate = Price.DateValue _TStop = System.Math.Min(Price.Low, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateDirection(Price, Factor) If _IsUp() And (Price.Low < _TStop) Then _UpdateDirectionToDown(Price, Factor) ElseIf _IsDown() And (Price.High > _TStop) Then _UpdateDirectionToUp(Price, Factor) End If End Sub Private Sub _UpdateExtremeHigh(Price, Factor) If Price.High >= GetExtremePrice() Then _Extreme = Price.High _ExtDate = Price.DateValue End If _TStop = System.Math.Max(_TStop, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateExtremeLow(Price, Factor) If Price.Low <= GetExtremePrice Then _Extreme = Price.Low _ExtDate = Price.DateValue End If _TStop = System.Math.Min(_TStop, GetExtremePrice() + Factor * _ATR) End Sub Private Sub _UpdateExtreme(Price, Factor) If _IsUp() Then _UpdateExtremeHigh(Price, Factor) Else _UpdateExtremeLow(Price, Factor) End If End Sub Public Sub PostPlot(Price, Factor) _UpdateDirection(Price, Factor) _UpdateExtreme(Price, Factor) End Sub Public Function IsExtreme(Price) As Boolean If _state = ZZState.Up And Price.Low < _TStop Then Return True If _State = ZZState.Down And Price.High > _TStop Then Return True Return False End Function End Class Enum ZZState Up = 1 Down = 2 End Enum
Now I need to find how to create a condition from my indicator.
I've just implemented a new feature so that I can find Bat, Crab, Gartley, or Butterfly pattern in the chart. You can find the latest code from https://gist.github.com/masayang/215ca81f6e137857b160
Attached image is AKAM 15min chart. It's amazing the price reversed at $46.66, which is 1.618XA.
interesting.
Tried to get this to post a value so I could sort and search for, but it won't sort. Not sure why.
none = 0 Bat = 1 Gartley = 2 Crab = 4 Butterfly = 8 ABCD = 16
So, this creates a code i.e. 1 is a BAT
3 is BAT + Gartley
7 is Bat+GART+Crab
15 is bat +gart+crab+butterfly
31 is bat+gart+crab + butterfly+abcd
and any other combination creates a code which you can identify the patterns covered by the chart.
<WBIGuid("3b6b8e77-cbd1-4ca5-bfd4-5672750d6203"),FriendlyName("RealCodeIndicator"),BlockTemplateEmptyMethodOnly()> _ Public Partial Class RealCodeIndicator Inherits RealCodeIndicator_base Public Overrides Function Plot() As System.Single ' Original: http://forums.worden.com/default.aspx?g=posts&t=42846 '# Period = UserInput.Single = 14 '# Factor = UserInput.Single = 3 '# Delta = UserInput.Single = 3 Static ZZ As MyZigZag Static XABCD As XABCD If isFirstBar Then ZZ = New MyZigZag(Price, Period, Factor) XABCD = New XABCD(Delta) plot = Single.NaN Else ZZ.PrePlot(Price) If ZZ.IsExtreme(Price) Then XABCD.AddExtreme(ZZ.GetExtremePrice()) End If ZZ.PostPlot(Price, Factor) End If plot = XABCD.GetCode() end function End Class Class XABCD Private _X,_A, _B, _C, _D As Single Private _Output As String Private _Delta As Single Private code As XabcdCode Public Function GetCode() As Single code = XabcdCode.none CheckABCD(code) CheckBat(code) CheckGartley(code) CheckCrab(code) CheckButterfly(code) Return code End Function Public Sub New(Delta As Single) _Delta = Delta _A = Single.NaN _B = Single.NaN _C = Single.NaN _D = Single.NaN _Output = "" End Sub Public Sub AddExtreme(Value As Single) _X = _A _A = _B _B = _C _C = _D _D = Value End Sub Private Function _ABCDTarget() As Single 'BC=0.382AB If _BC() >= 0.382 * (1 - _delta / 100) * _AB() And _BC() <= 0.382 * (1 + _delta / 100) * _AB() Then Return _C - 2.24 * _BC() End If 'BC=0.5AB If _BC() >= 0.5 * (1 - _delta / 100) * _AB() And _BC() <= 0.5 * (1 + _delta / 100) * _AB() Then Return _C - 2 * _BC() End If 'BC=0.618AB If _BC() >= 0.618 * (1 - _delta / 100) * _AB() And _BC() <= 0.618 * (1 + _delta / 100) * _AB() Then Return _C - 1.618 * _BC() End If 'BC=0.707AB If _BC() >= 0.707 * (1 - _delta / 100) * _AB() And _BC() <= 0.707 * (1 + _delta / 100) * _AB() Then Return _C - 1.41 * _BC() End If 'BC=0.786AB If _BC() >= 0.786 * (1 - _delta / 100) * _AB() And _BC() <= 0.786 * (1 + _delta / 100) * _AB() Then Return _C - 1.27 * _BC() End If 'BC=0.886AB If _BC() >= 0.886 * (1 - _delta / 100) * _AB() And _BC() <= 0.886 * (1 + _delta / 100) * _AB() Then Return _C - 1.13 * _BC() End If return single.NaN End Function Private Function _BatTarget() As Single 'AB<0.618XA If _AB() > 0.618 * (1 + _delta / 100) * _XA() Then Return Single.NaN 'BC is 0.382AB~0.886AB If _BC() < 0.382 * (1 - _delta / 100) * _AB() Then Return Single.NaN If _BC() > 0.886 * (1 + _delta / 100) * _AB() Then Return Single.NaN Return _A - 0.886 * _XA() End Function Private Function _GartleyTarget() As Single 'AB=0.618XA If _AB() > 0.618 * (1 + _delta / 100) * _XA() Then Return Single.NaN If _AB() < 0.618 * (1 - _delta / 100) * _XA() Then Return Single.NaN 'BC is 0.382AB~0.886AB If _BC() < 0.382 * (1 - _delta / 100) * _AB() Then Return Single.NaN If _BC() > 0.886 * (1 + _delta / 100) * _AB() Then Return Single.NaN Return _A - 0.786 * _XA() End Function Private Function _CrabTarget() As Single 'AB=0.382~0.618XA If _AB() > 0.618 * (1 + _delta / 100) * _XA() Then Return Single.NaN If _AB() < 0.382 * (1 - _delta / 100) * _XA() Then Return Single.NaN 'BC is 0.382AB~0.886AB If _BC() < 0.382 * (1 - _delta / 100) * _AB() Then Return Single.NaN If _BC() > 0.886 * (1 + _delta / 100) * _AB() Then Return Single.NaN Return _A - 1.618 * _XA() End Function Private Function _ButterflyTarget() As Single 'AB=0.786 If _AB() > 0.786 * (1 + _delta / 100) * _XA() Then Return Single.NaN If _AB() < 0.786 * (1 - _delta / 100) * _XA() Then Return Single.NaN 'BC is 0.382AB~0.886AB If _BC() < 0.382 * (1 - _delta / 100) * _AB() Then Return Single.NaN If _BC() > 0.886 * (1 + _delta / 100) * _AB() Then Return Single.NaN Return _A - 1.27 * _XA() End Function Private Function _XA() As Single Return _A - _X End Function Private Function _AB() As Single Return _A - _B End Function Private Function _BC() As Single Return _C - _B End Function Private Function _CD() As Single Return _C - _D End Function Private Sub _AddToOutput(Str As String) _Output = _Output & Str & System.Environment.NewLine End Sub Private Function CheckBat(ByRef code As XabcdCode) As String Dim Target As Single Target = _BatTarget() If Not system.Single.isnan(target) Then code = (code Or XABCDCode.Bat) Return "BAT Target=" & Target Else Return "" End If End Function Private Function CheckGartley(ByRef code As XabcdCode) As String Dim Target As Single Target = _GartleyTarget() If Not system.Single.isnan(target) Then code = (code Or XABCDCode.Gartley) Return "Gartley Target=" & Target Else Return "" End If End Function Private Function CheckCrab(ByRef code As XabcdCode) As String Dim Target As Single Target = _CrabTarget() If Not system.Single.isnan(target) Then code = (code Or XABCDCode.Crab) Return "Crab Target=" & Target Else Return "" End If End Function Private Function CheckButterfly(ByRef code As XabcdCode) As String Dim Target As Single Target = _ButterflyTarget() If Not system.Single.isnan(target) Then code = (code Or XABCDCode.Butterfly) Return "Butterfly Target=" & Target Else Return "" End If End Function Private Function CheckABCD(ByRef code As XabcdCode) As String Dim Target As Single Target = _ABCDTarget() If Not system.Single.isnan(target) Then code = (code Or XABCDCode.ABCD) Return "ABCD Target=" & target Else Return "" End If End Function Public Function Display() As String code = XabcdCode.none _AddToOutput(CheckABCD(code)) _AddToOutput(CheckBat(code)) _AddToOutput(CheckGartley(code)) _AddToOutput(CheckCrab(code)) _AddToOutput(CheckButterfly(code)) Return _Output End Function End Class Class MyZigZaG Private _TR As Single Private _TermRatio As Single Private _ATR As Single Private _SumWeight As Single Private _Weight As Single Private _ExtDate As Date Private _Extreme As Single Private _Tstop As Single Private _State As ZZState Public Sub New(Price As Object, Period As Single, Factor As Single) _TR = Price.High - Price.Low _TermRatio = (Period - 1) / Period _ATR = _TR _SumWeight = _TermRatio + 1 _Weight = 1 / _SumWeight _ExtDate = Price.DateValue If _StartsFromExtremeLow(Price) Then _Extreme = Price.Low _Tstop = System.Math.Max(Price.High, _Extreme + Factor * _ATR) _State = ZZState.Down Else _Extreme = Price.High _Tstop = System.Math.Min(Price.Low, _Extreme - Factor * _ATR) _State = ZZState.Up End If End Sub Private Function _StartsFromExtremeLow(Price As Object) As Boolean Return Price.High(-1) - System.Math.Min(Price.Low, Price.Low(-1)) < _ System.Math.Max(Price.High, Price.High(-1)) - Price.Low(-1) End Function Public Function GetExtremeDate() As Date Return _ExtDate End Function Public Function GetExtremePrice() As Single Return _Extreme End Function Private Sub _SetDownState() _State = ZZState.Down End Sub Private Sub _SetUpState() _State = ZZState.Up End Sub Public Sub PrePlot(Price As Object) _TR = (Price.High - Price.Low + _ System.Math.Abs(Price.High - Price.Last(1)) + _ System.Math.Abs(Price.Last(1) - Price.Low)) / 2 _ATR = _ATR * (1 - _Weight) + _Weight * _TR _SumWeight = _SumWeight * _TermRatio + 1 _Weight = 1 / _SumWeight End Sub Private Function _IsUp() As Boolean Return _State = ZZState.Up End Function Private Function _IsDown() As Boolean Return _State = ZZState.Down End Function Private Sub _UpdateDirectionToDown(Price As Object, Factor As Single) _SetDownState() _Extreme = Price.Low _ExtDate = Price.DateValue _TStop = System.Math.Max(Price.High, GetExtremePrice() + factor * _ATR) End Sub Private Sub _UpdateDirectionToUp(Price As Object, Factor As Single) _SetUpState() _Extreme = Price.High _ExtDate = Price.DateValue _TStop = System.Math.Min(Price.Low, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateDirection(Price As Object, Factor As Single) If _IsUp() And (Price.Low < _TStop) Then _UpdateDirectionToDown(Price, Factor) ElseIf _IsDown() And (Price.High > _TStop) Then _UpdateDirectionToUp(Price, Factor) End If End Sub Private Sub _UpdateExtremeHigh(Price As Object, Factor As Single) If Price.High >= GetExtremePrice() Then _Extreme = Price.High _ExtDate = Price.DateValue End If _TStop = System.Math.Max(_TStop, GetExtremePrice() - factor * _ATR) End Sub Private Sub _UpdateExtremeLow(Price As Object, Factor As Single) If Price.Low <= GetExtremePrice Then _Extreme = Price.Low _ExtDate = Price.DateValue End If _TStop = System.Math.Min(_TStop, GetExtremePrice() + Factor * _ATR) End Sub Private Sub _UpdateExtreme(Price As Object, Factor As Single) If _IsUp() Then _UpdateExtremeHigh(Price, Factor) Else _UpdateExtremeLow(Price, Factor) End If End Sub Public Sub PostPlot(Price As Object, Factor As Single) _UpdateDirection(Price, Factor) _UpdateExtreme(Price, Factor) End Sub Public Function IsExtreme(Price As Object) As Boolean If _state = ZZState.Up And Price.Low < _TStop Then Return True If _State = ZZState.Down And Price.High > _TStop Then Return True Return False End Function End Class Enum ZZState Up = 1 Down = 2 End Enum Enum XabcdCode none = 0 Bat = 1 Gartley = 2 Crab = 4 Butterfly = 8 ABCD = 16 End Enum
Bruce,
In reference to pthegreat posting on Tuesday, April 09, 2013 8:50:42 PM , is it possible to create a condition for fib levels 23.6%,113%, 127%,141%,
161.8%, 200%, 261.8%, D ... 0.50 cents above/below.?
Yes, No, Maybe....
It is too involved for me to say yes or no yet, so I guess the answer is maybe.
It is possible that pthegreat, jas0501 or masayang might have a more definitive answer.
I'm currently working on creating RealCode in the context of a personal training session. As a PTS costs $95 per hour, it gets priority over free RealCode in the forums.
You can schedule a PTS with a TC2000 trainer as well if you would like. They can also build scans for you. Ask them anything related to TC2000 (or StockFinder with advance notice). Have them set up your layouts, customize your charts, teach you general functionality, etc. Such sessions can be conducted via remote assistance where the trainer can view your machine and save any changes they make and teach you some things along the way. These sessions are $95.00 an hour with a one hour minimum. Call the sales line at 1-800-776-4940 or email us at support@TC2000.com to arrange one of these sessions.
caution; I'm sorry but I recently entered into a professional partnership, and I can't share any code anymore.
Having said that, if you go through all my posts, I'm sure from what I have shared and from Bruce's invaluable input, you should be able to do what you're asking.
good luck,
Bruce, one suggestion;
I have noticed that a lot of old posts have dissapeared. I assume that the forum can hold only a certain amount of data, and then older posts get removed?
There was a lot of valuable info that I can't find anymore. Is it possible that Worden would make a downloadable archive available of all posts, since beginning of time?
Regards,
The main reason a post would disappear is because it is in a forum which has been removed the website.
These forums are removed for a variety of reasons, but the biggest is that the forum is for an outdated product which is no longer available or supported. When the information in the forums is about a more recent similar product which is still available, the information is frequently wrong or misleading.
If you have a particular topic you want to look at which is not available, you can make a request that it be moved into one of the currently available forums. We might be able to get a particular post moved, but the older removed forum as a whole in which the post is contained will not be re-added.