Registered User Joined: 6/15/2008 Posts: 1,356
|
Bruce,
for the sake of experimenting with addtooutput, I wrote a fib retrace indicator in realcode:
Sub New
AutoLoop = False
'# retr1 = userinput.single = 23.2
'# retr2 = userinput.single = 38.2
'# retr3 = userinput.single = 50
'# retr4 = userinput.single = 61.8
'# retr5 = userinput.single = 78.6
'# retr6 = userinput.single = 100
'# retr7 = userinput.single = 161.8
'# RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
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
End If
If BarA < Range(1) - 1 Then
Dim BarB As Integer = BarA
Dim BarBqualified As Integer = BarA
For i As Integer = BarA + 1 To Range(1) - 1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then
BarB = i
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
BarBqualified = BarB
end if
Exit For
Next
end if
next
If BarBqualified > BarA Then
AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.highValue(BarA), "A")
AddToOutput(Price.Bar.DateValue(BarBqualified), Price.Bar.lowValue(BarBqualified), "B")
Dim leg As Single = price.bar.highvalue(BarA) - price.bar.lowvalue(BarBqualified)
Dim k As Integer = BarBQualified + 1
If price.bar.value(k) > price.Bar.lowvalue(BarBQualified) AndAlso k <= range(1) Then
Dim retrlvl1 As Single = price.bar.lowvalue(BarBQualified) + retr1 / 100 * leg
Dim lvl1 As String = retr1 & "%= " & retrlvl1.ToString("N2")
addtooutput(price.Bar.datevalue(k), retrlvl1, lvl1)
k += 1
Do Until Price.bar.value(k) > retrlvl1 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl1)
k += 1
Loop
If price.bar.value(k) > retrlvl1 AndAlso k < range(1) Then
Dim retrlvl2 As Single = price.bar.lowvalue(BarBQualified) + retr2 / 100 * leg
Dim lvl2 As String = retr2 & "%= " & retrlvl2.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl2, lvl2)
k += 1
Do Until price.bar.value(k) > retrlvl2 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl2)
k += 1
Loop
If price.bar.value(k) > retrlvl2 AndAlso k < range(1) Then
Dim retrlvl3 As Single = price.bar.lowvalue(BarBQualified) + retr3 / 100 * leg
Dim lvl3 As String = retr3 & "%= " & retrlvl3.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl3, lvl3)
k += 1
Do Until price.bar.value(k) > retrlvl3 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl3)
k += 1
Loop
If price.bar.value(k) > retrlvl3 AndAlso k < range(1) Then
Dim retrlvl4 As Single = price.bar.lowvalue(BarBQualified) + retr4 / 100 * leg
Dim lvl4 As String = retr4 & "%= " & retrlvl4.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl4, lvl4)
k += 1
Do Until price.bar.value(k) > retrlvl4 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl4)
k += 1
Loop
If price.bar.value(k) > retrlvl4 AndAlso k < range(1) Then
Dim retrlvl5 As Single = price.bar.lowvalue(BarBQualified) + retr5 / 100 * leg
Dim lvl5 As String = retr5 & "%= " & retrlvl5.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl5, lvl5)
k += 1
Do Until price.bar.value(k) > retrlvl5 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl5)
k += 1
Loop
If price.bar.value(k) > retrlvl5 AndAlso k < range(1) Then
Dim retrlvl6 As Single = price.bar.lowvalue(BarBQualified) + retr6 / 100 * leg
Dim lvl6 As String = retr6 & "%= " & retrlvl6.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl6, lvl6)
k += 1
Do Until price.bar.value(k) > retrlvl6 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl6)
k += 1
Loop
End If
End If
End If
End If
End If
End If
End If
End If
End Function
End Class
It works pretty good. However would you have any idea on how to plot all the fib levels at once, instead of looping till a level breaks and then being able to plot the next one?
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
something weird:
the code from the indicator following below, allows to recalculate the indicator when you scroll through the time-axis. Last night when I finished the indicator it worked instantaneously, scroll, and immediately it drew the new high/low on the chart with the corresponding fib levels.
Now this morning I opened up SF, with same layout, haven't changed anything in the code, and now it takes a minute to recalculate, or do a refresh chart to recalculate.
why?
'# RECALC_ON_ZOOM_SCROLL
.
.
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
during the 1 minute delay to recalculate, all my processor cores are virtually at 0%, so doesn't look like it's due to "cpu intensive" calculations. and also as I mentioned, when you do a "refresh chart" it recalcs immediately. so why the delay? bug with the '# RECALC_ON_ZOOM_SCROLL function?
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
"update freq" set to 5sec.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Just loaded my layout with the fib retrace indicator, to see what it does during market hours. still the same, takes a long time to recalculate.
Then I added the AB=CD indicator, mentioned in the "market/stocks" forum. and used it the same way with both
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.indexfordate(activechart.zoomstartdate)
enabled. and this indicator recalculates immediately on zoom-scroll through charts!!
what gives?
Sub New
AutoLoop = False
'# RecLowPer = 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) = Price.indexfordate(activechart.zoomstartdate)
'Range(0) = Range(1) + 1 - RecLowPer
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(1) As Integer
L1(0) = BarA
L1(1) = 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.Value(i) < Price.Bar.highValue(BarB) - ABretr AndAlso _
i > 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
Dim Level1 As Single = Single.MaxValue
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
Level1 = System.Math.Min(Level1, Price.Bar.HighValue(j))
L1(0) = j
End If
If Price.Bar.Value(j) > Level1 Then
BarCqualified = BarC
BarBqualified(1) = BarBqualified(0)
L1(1) = L1(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")
AddToOutput(Price.Bar.DateValue(L1(1)), Price.Bar.HighValue(L1(1)), "1")
Dim k As Integer = L1(1) + 1
Do Until Price.Bar.Value(k) > Price.Bar.HighValue(L1(1)) OrElse k > Range(1)
AddToOutput(Price.Bar.DateValue(k), Price.Bar.HighValue(L1(1)))
k += 1
Loop
If Price.Bar.Value(k) > Price.Bar.HighValue(L1(1)) AndAlso 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 PRZhigh As Single
Select Case retr
Case <= 38.2
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2.618
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618
Case 38.2 To 50
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 2
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2.618
Case 50 To 61.8
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.618
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 2
Case 61.8 To 70.7
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.41
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.618
Case 70.7 To 78.6
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.27
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.41
Case 78.6 To 88.6
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.27
Case 88.6 To 100
PRZlow = price.Bar.lowvalue(BarCqualified) + BC * 1.13
PRZhigh = price.Bar.lowvalue(BarCqualified) + BC * 1.13
End Select
AddToOutput(Price.Bar.DateValue(k), PRZlow, "PRZlow")
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, "PRZhigh")
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
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I do not know of a way to plot all of the values at once other than to create a different indicator for each level. To clarify further, you could output up to four values at once by outputting bar data instead of line data, but you would then need to extract the values somehow (probably by adding 1-Period Simple Moving Average of OHLC indicators).
The recalculation issue would appear to be your use of:
'# RECALC_ON_ZOOM_SCROLL
Instead of:
'#RECALC_ON_ZOOM_SCROLL
When I take out the space it seems to recalculate just fine.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
ah, of course. thanks!
just out of curiosity, the drawing tools in SF, such as the fib retracement tool, aren't they written in VB.net ?
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I would guess so, but they aren't externally accessible. There is no way for you or I to create a RealCode Drawing Tool for example.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
understood, but if in case it is vb.net, then the fib tool must be using some other way of outputting lines, since it does draw multiple lines at once. In any case, something to consider maybe, when (if) any further SF development might happen.
thx Bruce.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
Visual basic itself would have no problem having something besides 1 or 4 values at each bar, that limitation is part of the structure of RealCode Indicators.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Bruce I have been fighting with getting a condition to work, so that I can scan my watchlist on a break on any of the levels.
I know you have touched on this before, but I just don't quite understand it.
1st of all, correct me if I'm wrong, but a condition will only work by avoiding the RECALC_ON_ZOOM_SCROLL
so therefore the indicator has to work with a manual set range. (which is not a problem)
could you try and create a condition for me that would pass if price breaks one of the levels? it would be great if you could speifically determine which level, but again, I think you mentioned it before that it's not possible.
I believe we have to use the structure
If Price.DateValue = Prop.DateValue Then...
I'd appreciate it if you could explain the reasoning.
thanks
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
Let's reimagine your RealCode Indicator somewhat so it meets the requirements of not using RECALC_ON_ZOOM_SCROLL.
Sub New
AutoLoop = False
End Sub
Public Overrides Function Plot() As System.Single
'# Retrace = userinput.single = 23.2
'# BarsAgo = UserInput.Integer = 0
'# Period = UserInput.Integer = 500
Dim Range(1) As Integer
Range(1) = Price.Bar.Count - 1 - BarsAgo
Range(0) = Range(1) - Period + 1
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
End If
If BarA < Range(1) - 1 Then
Dim BarB As Integer = BarA
Dim BarBqualified As Integer = BarA
For i As Integer = BarA + 1 To Range(1) - 1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then
BarB = i
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
BarBqualified = BarB
end if
Exit For
Next
end if
next
If BarBqualified > BarA Then
Dim level As Single = price.bar.lowvalue(BarBqualified) + Retrace / 100 * _
(price.bar.highvalue(BarA) - price.bar.lowvalue(BarBqualified))
For i As Integer = BarBqualified To Range(1)
AddToOutput(Price.Bar.DateValue(i), level)
Next
End If
End If
End Function
End Class
Doing so creates an an indicator for which we can just drag and drop Price History onto the indicator to create a condition for price being above or crossing up through the retrace value. We can this condition as a WatchList Column and it should use the most recent price in its calculations.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Bruce,
the way I have been using these various fib related indicators, is the way you wrote the very 1st request for me, quite some time ago (not longer on the forum). and that is by plotting one level, then looping until price breaks that level, and then plot the next level, and so on.
I have used this principal to write several other fib related indicators, like the one posted on top of this thread . This works great, but doesn't work very well for trying to create conditions for scanning.
creating a condition by drag/drop price onto the indicator, and select crossup through, will run extremely slow in the watch list and seems to give random results.
Your solution, as per previous post, which plots only one level, works fine.
I have used a realcode that works, but i have a feeling that it not always catches all occurrences.
'#cumulative
'# rlvl = chart.retr-lvls-up
Static retr As Single
Static rBarCount As Integer
If isFirstBar Then
retr = Single.NaN
rBarCount = 0
End If
If currentindex > price.count - 15 Then
If Price.DateValue = rlvl.DateValue Then
rBarCount += 1
If rBarCount = 2 Then
retr = rlvl.Value
End If
End If
If rBarCount >= 2 Then
If (Price.Value(1) < retr AndAlso Price.Value > retr) Then
Pass
End If
End If
Else
SetIndexInvalid
End If
So, in order to get reliable sorting results I would have to use as many indicators as I have levels that I want to sort by. Each indicator with the same logic , the only difference being is the fib% level.
It's been a while (over 25years) that I attended some programming classes (Pascal) in school, but I remember that my teacher would have a fit, if you suggested to write any part of code more then once. :-) that's what object oriented languages are all about, right?
So... I assume there should be a way that we have one "main" indicator (or a class, or subroutine) that calculates the A-high, B-low, and then hands of this data, and index position of point B to several indicators (or classes) that have but one function, and that is to plot the individual levels as of index position of point B.
so in pseudo code:
sub main
find barA.highvalue
find barB.lowvalue
for i as integer = 1 to 3
do sub(i)
next
end sub main
sub 1
retrlvl1 = price.bar.lowvalue(BarB) + 23.6% * (price.bar.highvalue(BarA) - price.bar.lowvalue(BarB))
addtooutput(price.bar.datevalue(BarB), retrlvl1)
end sub 1
sub 2
retrlvl2 = price.bar.lowvalue(BarB) + 38.2% * (price.bar.highvalue(BarA) - price.bar.lowvalue(BarB))
addtooutput(price.bar.datevalue(BarB), retrlvl2)
end sub 2
sub 3
retrlvl3 = price.bar.lowvalue(BarB) + 50% * (price.bar.highvalue(BarA) - price.bar.lowvalue(BarB))
addtooutput(price.bar.datevalue(BarB), retrlvl3)
end sub 3
For the sake of argument I used "sub" in the above pseudo code. I have no idea if this can be done with subs, classes, or by using individual indicators, But I would think this would be the proper way of doing it.
any ideas?
and thanks for the help as always.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
thinking it over a bit more, the "sub1", "sub2", etc.. would have to be individual indicators, in order to be able to create conditions for each level. so therefore the data from the "main" routine, would have to be parsed to individual indicators.
Since my goal is to write some indicators that are a lot more complex then the above described "fib retrace indicator", but that will create several levels as well, I think it will be much more efficient to be able to parse data from a main "routine" or indicator into several indicators that just plot the levels. Isn't that what the "sharedhashvalue" object is for?
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I'm not a programmer and I have never used this feature, but I suspect it is not going to do what you want. From Kuf's Friday, January 29, 2010 4:20:09 PM ET post in the New SharedHash object topic:
QUOTE (Kuf) The code will only work on a chart. I didn't qualify this but the shared object is shared with the chart. If you want to run your calculation on a list of symbols, run it as a market indicator.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I did get your layout, but it pretty much locks up my computer (which is a three year old laptop). The WatchList Column takes several minutes to calculate a symbol before starting to calculate the next symbol.
I'm not a programmer and I'm not sure I could tell you how it worked if my computer was up to running it, but I definitely can't figure it out without being able to even use it.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 5/11/2009 Posts: 120
|
QUOTE (Bruce_L)
I did get your layout, but it pretty much locks up my computer (which is a three year old laptop). The WatchList Column takes several minutes to calculate a symbol before starting to calculate the next symbol.
I'm not programmer and I'm not sure I could tell you how it worked if my computer was up to running it, but I definitely can't figure it out without being able to even use it.
And this my friends is the reason that Worden did the right thing by pulling the plug on future development of Stockfinder.
If you spend a lot of money on a powerful computer like pthegreat did you might get by with fancy programs. Otherwise stick with something simple. It would probably be better to spend time with TC2000 ver 12. Hands down the best stock program on the market today.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Thx for the suggestion Tomson, but not until TC will have the same functionality (realcode, multi-screen, etc..) as SF, will I spend more time with TC. Not having to invest in a decent PC, to me, is nothing more then a selling point to the statistically +80% beginnin traders that will blow up their accounts., been there, done that. Yes SF has the power to outperform your PC, that's exactley why I like it. Trading is a business. starting a business right is investing in the tools that work for you, and spending the time to learn. SF is an indispensable tool for me.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Bruce, modified the code, so it will look for the low first, then from that point counting down the index find the high, that way i can do projections over 100% of the High-Low.
However when I have this running on my layout, after an hour or two I get a memory exception error, and SF freezes.
can you quickly double check if I do something wrong with this code?
thx.
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'# retr1 = userinput.single = 23.2
'# retr2 = userinput.single = 38.2
'# retr3 = userinput.single = 50
'# retr4 = userinput.single = 61.8
'# retr5 = userinput.single = 78.6
'# retr6 = userinput.single = 100
'# retr7 = userinput.single = 161.8
'#RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim BarB As Integer = Range(1)
Dim BarA As Integer
For i As Integer = Range(1) - 1 To Range(0) Step -1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then
BarB = i
End If
Next
If BarB > Range(0) + 1 Then
BarA = BarB
For i As Integer = BarB - 1 To Range(0) Step -1
If Price.Bar.HighValue(i) >= Price.Bar.HighValue(BarA) Then
BarA = i
End If
Next
End If
If BarB > BarA Then
AddToOutput(Price.Bar.DateValue(BarA), Price.Bar.highValue(BarA), "High")
AddToOutput(Price.Bar.DateValue(BarB), Price.Bar.lowValue(BarB), "Low")
Dim leg As Single = price.bar.highvalue(BarA) - price.bar.lowvalue(BarB)
Dim k As Integer = BarB + 1
If price.bar.value(k) > price.Bar.lowvalue(BarB) AndAlso k <= range(1) Then
Dim retrlvl1 As Single = price.bar.lowvalue(BarB) + retr1 / 100 * leg
Dim lvl1 As String = retr1 & "%= " & retrlvl1.ToString("N2")
addtooutput(price.Bar.datevalue(k), retrlvl1, lvl1)
k += 1
Do Until Price.bar.value(k) > retrlvl1 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl1)
k += 1
Loop
If price.bar.value(k) > retrlvl1 AndAlso k < range(1) Then
Dim retrlvl2 As Single = price.bar.lowvalue(BarB) + retr2 / 100 * leg
Dim lvl2 As String = retr2 & "%= " & retrlvl2.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl2, lvl2)
k += 1
Do Until price.bar.value(k) > retrlvl2 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl2)
k += 1
Loop
If price.bar.value(k) > retrlvl2 AndAlso k < range(1) Then
Dim retrlvl3 As Single = price.bar.lowvalue(BarB) + retr3 / 100 * leg
Dim lvl3 As String = retr3 & "%= " & retrlvl3.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl3, lvl3)
k += 1
Do Until price.bar.value(k) > retrlvl3 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl3)
k += 1
Loop
If price.bar.value(k) > retrlvl3 AndAlso k < range(1) Then
Dim retrlvl4 As Single = price.bar.lowvalue(BarB) + retr4 / 100 * leg
Dim lvl4 As String = retr4 & "%= " & retrlvl4.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl4, lvl4)
k += 1
Do Until price.bar.value(k) > retrlvl4 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl4)
k += 1
Loop
If price.bar.value(k) > retrlvl4 AndAlso k < range(1) Then
Dim retrlvl5 As Single = price.bar.lowvalue(BarB) + retr5 / 100 * leg
Dim lvl5 As String = retr5 & "%= " & retrlvl5.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl5, lvl5)
k += 1
Do Until price.bar.value(k) > retrlvl5 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl5)
k += 1
Loop
If price.bar.value(k) > retrlvl5 AndAlso k < range(1) Then
Dim retrlvl6 As Single = price.bar.lowvalue(BarB) + retr6 / 100 * leg
Dim lvl6 As String = retr6 & "%= " & retrlvl6.ToString("N2")
addtooutput(price.bar.datevalue(k), retrlvl6, lvl6)
k += 1
Do Until price.bar.value(k) > retrlvl6 OrElse k = range(1)
addtooutput(price.bar.datevalue(k), retrlvl6)
k += 1
Loop
End If
End If
End If
End If
End If
End If
End If
end function
End Class
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I've gone through the RealCode line by line and I don't see anything obviously wrong. I have also been running all three of your RealCode indicators from this topic in my copy of StockFinder 5 continuously for about two hours without generating any error messages or having StockFinder crash.
That said, I'm not a programmer, and even if I were, there could be a bug in the RealCode (or in RealCode itself) causing a memory leak of some sort (or some other bug) and I would not necessarily find it.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 3/6/2009 Posts: 78
|
WOW... runing for more than 2 hours and still not done. The trade would have been missed by the time you get an answer. Now I see why Worden dropped Stockfinder.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
TC2000 version 12.3 is generally quite a bit faster than StockFinder 5, but you appear to have significantly misread my recent post (and keep in mind that you can speed up StockFinder 5 significantly by reducing its bar limit from 5000 to the same 500 bar limit enforced in TC2000 version 12.3). I wasn't able to get pthegreat's code to crash while running it over the course of two hours.
The RealCode posted by pthegreat actually seemed to run quite efficiently without generating any issues at all on my computer. All three indicators plotted nearly instantly both when switching symbols and changing zooms. They are designed to completely recalculate when scrolling or zooming as they plot differently depending on the time span being viewed.
That I was not able to get the indicators to crash is not necessarily a good thing as I was attempting to replicate an error message which pthegreat gets when running his newest indicator for an extended period of time to try and figure out what might be causing the issue.
The slow RealCode that would not run on my computer earlier in the thread was in a layout containing an incredibly complicated RealCode Indicator that pthegreat picked up from a third party and sent to me via email.
All of these indicators are the sorts of things that you can't do at all in TC2000. They are possible in StockFinder because of the versatility of RealCode compared to the relatively simple Personal Criteria Formula Language used in TC2000.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
dryfess, what's running for 2hours? it's virtually instantaneous on my chart! either describe the problem you are experiencing, and I would be more then happy to try and help, or stay in your TC2000 threads. I think its a bit rude to barge in on someones topic, and start dissing the application. I prefer SF, by far, over TC, that doesn't mean I would come over and barge into someones TC thread and start dissing TC2000. TC IMO has many many shortcomings, compared to SF.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
back to the subject at hand;
figured out what the problem was:
if the first bar on the chart is the lowest low, then BarA wouldn't get a value.
therefore:
at initialisation of the parameters, instead of:
Dim BarB As Integer = Range(1)
Dim BarA As Integer
should use :
Dim BarB As Integer = Range(1)
Dim BarA As Integer = Range(1)
working fine
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Now my second objective is:
have one indicator calculate the high/low on the chart, and corresponding fib levels, and then via sharedhasvalue share these values with individual indicators that will plot each level as of the BarLow.
I simplified the indicator, so I can build it up step by step:
starting with an indicator(class) that calculates only a 23.6% level and than shares it:
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'# retr1 = 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.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim BarLow As Integer = Range(1)
Dim BarHigh As Integer = Range(1)
For i As Integer = Range(1) - 1 To Range(0) Step -1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarLow) Then
BarLow = i
End If
Next
If BarLow > Range(0) Then
BarHigh = BarLow
For i As Integer = BarLow - 1 To Range(0) Step -1
If Price.Bar.HighValue(i) > Price.Bar.highValue(BarHigh) Then
BarHigh = i
End If
Next
End If
If BarLow > BarHigh Then
AddToOutput(Price.Bar.DateValue(BarHigh), Price.Bar.highValue(BarHigh), "High")
AddToOutput(Price.Bar.DateValue(BarLow), Price.Bar.lowValue(BarLow), "Low")
Dim leg As Single = price.bar.highvalue(BarHigh) - price.bar.lowvalue(BarLow)
Dim fib As Single = price.bar.lowvalue(BarLow) + retr1 / 100 * leg
Me.setSharedHashValue("key", fib)
Me.NotifyDataReady("key")
End If
end function
End Class
then I wrote a simple indicator(code) catching the value and plot it:
Static sharedData As Single
If isFirstBar Then
sharedData = 0
If Me.WaitForDataReady("key", 1000) Then
shareddata = Me.getSharedHashValue("key")
End If
End If
plot = sharedData
this works.
next step will be to plot the level, starting at BarLow. From the sharedhash post by Kuf, I see an example of sharing a set of parameters. But one step at a time. So I tried to change the 2nd indicator into a class:
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'#RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim test As Single
test = 0
test = Me.getSharedHashValue("key")
If Me.WaitForDataReady("key", 1000) Then
For i As Integer = range(0) To Range(1)
addtooutput(price.Bar.datevalue(i), test)
Next
End If
End Function
End Class
Does Not Work.
any ideas?
thx.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
If we get the class to work, then the next step would be to create a System.Collections.Generic.List which holds all the calculated fib levels, and index of BarLow. and store that in the sharedhashvalue
then we could use indicators to plot each individual fib level as of index BarLow.
I have no experience with this, and info is very limited.
so please correct if my thinking is wrong, or if you have a better approach:
main indicator: finding BarHigh and BarLow, then calculate all fib levels, store them in System.Collections.Generic.List, and store in sharedhashvalue :
I have limited here to only store the fib236 in the collection. but once we get this working, we can add all of them.
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'# retr1 = userinput.single = 23.6
'# retr2 = userinput.single = 38.2
'# retr3 = userinput.single = 50
'# retr4 = userinput.single = 61.8
'# retr5 = userinput.single = 78.6
'# retr6 = userinput.single = 88.6
'# retr7 = userinput.single = 100
'# retr8 = userinput.single = 127
'# retr9 = userinput.single = 161.8
'# retr10 = userinput.single = 200
'# retr11 = userinput.single = 224
'# retr12 = userinput.single = 261.8
'#RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim BarLow As Integer = Range(1)
Dim BarHigh As Integer = Range(1)
Dim RetrCollection As System.Collections.Generic.List(Of fibinfo)
For i As Integer = Range(1) - 1 To Range(0) Step -1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarLow) Then
BarLow = i
End If
Next
If BarLow > Range(0) Then
BarHigh = BarLow
For i As Integer = BarLow - 1 To Range(0) Step -1
If Price.Bar.HighValue(i) > Price.Bar.highValue(BarHigh) Then
BarHigh = i
End If
Next
End If
If BarLow > BarHigh Then
AddToOutput(Price.Bar.DateValue(BarHigh), Price.Bar.highValue(BarHigh), "High")
AddToOutput(Price.Bar.DateValue(BarLow), Price.Bar.lowValue(BarLow), "Low")
Dim leg As Single = price.bar.highvalue(BarHigh) - price.bar.lowvalue(BarLow)
Dim item As New fibinfo()
item.fiblow = BarLow
item.fib236 = price.bar.lowvalue(BarLow) + retr1 / 100 * leg
RetrCollection.Add(item)
Me.setSharedHashValue("fib", RetrCollection)
Me.NotifyDataReady("fib")
End If
end function
Public Structure fibinfo
Public fiblow As Integer
Public fib236 As Single
End Structure
End Class
then the "plot" indicator would look like this, (I assume)
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'#RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim RetrCollection As System.Collections.Generic.List(Of FibInfo)
Dim item As New FibInfo()
Dim test As Single
If Me.WaitForDataReady("fib", 1000) Then
RetrCollection = Me.getSharedHashValue("fib")
For i As Integer = item.FibLow To Range(1)
addtooutput(price.Bar.datevalue(i), item.Fib236)
Next
End If
end function
Public Structure FibInfo
Public FibLow As Integer
Public Fib236 As Single
End Structure
End Class
just like the previous class code to plot the level, it's not working.
I'd appreciate it if you could go over this.
thx,
P.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I'm not a programmer, but my guess as to the issue is that you are attempting to getSharedHashValue before using WaitForDataReady to make sure there is actually data available.
I think you want the following instead:
Sub New
AutoLoop = False
'# RecLowPer = UserInput.Integer = 500
'#RECALC_ON_ZOOM_SCROLL
End Sub
Public Overrides Function Plot() As System.Single
Dim Range(1) As Integer
Range(1) = Price.IndexForDate(ActiveChart.ZoomEndDate)
Range(0) = Price.IndexForDate(ActiveChart.ZoomStartDate)
'Range(1) = price.Bar.count - 1
'Range(0) = Range(1) + 1 - RecLowPer
Dim test As Single
test = 0
If Me.WaitForDataReady("key", 1000) Then
test = Me.getSharedHashValue("key")
For i As Integer = range(0) To Range(1)
addtooutput(price.Bar.datevalue(i), test)
Next
End If
End Function
End Class
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
yes makes sense. will try AH today. thx.
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Made the change, just did a quick test, it works the 1st time you open the layout, then either changing timeframe, or ticker, will not work.
the main indicator, redraws the high to low, but the fib236 indicator, just keeps calculating, and no plot.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I don't know why it doesn't work. I'm not a programmer and I've never used this particular feature of RealCode. I don't think you need to use this feature to do what you want however.
For example, the first line of the following RealCode Indicator was created by dragging and dropping your simplified indicator that "calculates only a 23.6% level and than shares it" into the Code tab of the RealCode. You are probably using a different name and will need to adjust that line and any references to the variable name created appropriately. It takes advantage of the fact that your indicator actually also plots the high and low used to calculate the 23.6% level to work.
'# HtL = chart.HightoLow
'# Level = UserInput.Single = 0
Static Top As Single
Static Bot As Single
If isFirstBar Then
Top = Single.NaN
Bot = Single.NaN
End If
If Single.IsNaN(Top) Then
If Price.DateValue = HtL.DateValue Then
Top = HtL.Value
End If
Else If Single.IsNaN(Bot) Then
If Price.DateValue = HtL.DateValue Then
Bot = HtL.Value
End If
End If
Plot = Bot + Level * (Top - Bot) / 100
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Platinum Customer
Joined: 3/19/2008 Posts: 64
|
Thank you guys for this thread, it has been really informative.
And to the other poster, there are many people (myself included) who find great use out of TC, but LOVE stockfinder due to the huge functionality if offers
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
Hi Bruce,
I'm doing some more experimenting.
I'd like to know how to use class, autoloop = false and addtooutput in a condition.
Modified your previous posted indicator code, to work as a condition:
inherits RealCodeCondition_base
Sub New
autoloop = False
End Sub
Public Overrides Sub CallUserCode()
'# Retrace = userinput.single = 23.2
'# BarsAgo = UserInput.Integer = 0
'# Period = UserInput.Integer = 500
Dim Range(1) As Integer
Range(1) = Price.Bar.Count - 1 - BarsAgo
Range(0) = Range(1) - Period + 1
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
End If
If BarA < Range(1) - 1 Then
Dim BarB As Integer = BarA
Dim BarBqualified As Integer = BarA
For i As Integer = BarA + 1 To Range(1) - 1
If Price.Bar.LowValue(i) < Price.Bar.LowValue(BarB) Then
BarB = i
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
BarBqualified = BarB
end if
Exit For
Next
end if
next
If BarBqualified > BarA Then
Dim level As Single = price.bar.lowvalue(BarBqualified) + Retrace / 100 * _
(price.bar.highvalue(BarA) - price.bar.lowvalue(BarBqualified))
For i As Integer = BarBqualified To Range(1)
If price.Bar.lastvalue(i) > level Then
pass
MyBase.addtoOutput(price.bar.datevalue(i), True)
End If
Next
End If
End If
End Sub
End Class
When I add the condition to a watchlist column "bars since true" , it either shows 0 or 50.
I suspect that the addtoouput statement's function in a condition is; only to be able to show a "True Marker" on the chart ?
How would you be able to use this in a watchlist?
maybe instead of writing it all in a class, maybe you should in the "code" tab check if the "class" is true and then "pass" ?
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
You are going to mostly have to figure this out by yourself. I am not a programmer. What you are attempting to do is not like a typical condition.
That said, don't use the pass line. You also need to do more than just return true.
When the result is false, use AddToOutput to return false.
The only time you shouldn't return true or false is when there isn't enough data to do the calculations. But keep in mind that if you are passing through the data more than once or not in chronological order, you should only do a maximum of one AddToOutput for each bar and these AddToOutput results should be outputted in chronological order from oldest to newest.
Also note that the "indicator" upon which the condition is based isn't a typical indicator. It does its calculations only once for a range of bars. It does not calculate a new value for each bar. So you won't have a situation where a different condition is being calculated for every bar (at least in that the indicator is a different indicator at each bar). No test is done to see if it might have been true 10-bars ago to generate anything besides a 0 "since true" type result.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 6/15/2008 Posts: 1,356
|
ok, understanding the concept now.
rewrote the last part, and works fine.
If BarBqualified > BarA Then
Dim level As Single = price.bar.lowvalue(BarBqualified) + Retrace / 100 * _
(price.bar.highvalue(BarA) - price.bar.lowvalue(BarBqualified))
Dim brklevel As Integer = 0
For i As Integer = BarBqualified To Range(1)
If price.Bar.lastvalue(i) > level AndAlso price.Bar.lastvalue(i - 1) < level Then
brklevel = i
End If
Next
For j As Integer = 0 To price.Bar.count - 1
If j = brklevel Then
MyBase.addtoOutput(price.bar.datevalue(j), True)
Else
MyBase.addtoOutput(price.bar.datevalue(j), False)
End If
Next
End If
so basically just made another run through the whole price data range.
I should be able to rewrite and optimize it. but it was just a learning experiment.
Thanks !!!
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
You're welcome.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Guest-1 |