masayang |
Member, Platinum User, TeleChart
|
Registered User |
|
|
|
|
Gender: |
|
Friday, May 10, 2013 |
Friday, August 28, 2015 7:59:20 PM |
7 [0.00% of all post / 0.00 posts per day] |
|
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.
|
Now I need to find how to create a condition from my indicator.
|
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
|
Sorry folks. I confirmed that code didn't work.
|
Hmm. That code works on my environment, SF 5.0.39.17229 on Windows Server 2012. What kind of error did you get actually?
|
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
|
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
|
|