Welcome Guest, please sign in to participate in a discussion. Search | Active Topics |

Help with formula Rate this Topic:
Previous Topic · Next Topic Watch this topic · Print this topic ·
kostas_gr
Posted : Wednesday, May 11, 2011 5:41:30 PM
Registered User
Joined: 2/26/2005
Posts: 115

 

Hi I need a trainer's help to codify the following formula in the SF version 4 I am still working in:

1. There are two symbols involved: the main symbol (S1) and a secondary symbol (S2), with the secondary symbol being selectable/changeable.
2. Sum of returns for S2 during those days when its own returns are ABOVE their average/ median (selectable) over a certain period (selectable)
3. Sum of returns for S2 during those days when its own returns are BELOW their average/ median (selectable) over a certain period (selectable)
4. Sum of returns for S1 during those days when S2 returns are above their average/median (selectable) over a certain period (selectable)
5. Sum of returns for S1 during those days when S2 returns are below their average/ median (selectable) over a certain period (selectable)
6. Ratio #4/#2
7. Ratio #5/#3

8. Calculate the expression: ((((#6-#7)^2*2)^0.5)*0.5)*((#6-#7)/abs(#6-#7))

I appreciate the help!

K

 
Bruce_L
Posted : Thursday, May 12, 2011 1:03:08 PM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
By "returns" do you mean the Price Percent Change over some Period of time or something else?

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Thursday, May 19, 2011 12:38:12 AM
Registered User
Joined: 2/26/2005
Posts: 115
Sorry for the delay, Bruce--yes, Returns=price percent change 
Bruce_L
Posted : Thursday, May 19, 2011 8:35:53 AM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
I can do the mean, but the median is beyond my ability to provide assistance. You would need to Drag and Drop a Price for Symbol Indicator into the Code tab of the RealCode Editor to create the first line of the following RealCode Indicator:

'# PfS = indicator.PriceforSymbol.2
'# Period = UserInput.Integer = 20
Static Tot As Single
Static PeriodPlus As Integer
Static PeriodMinus As Integer
If CurrentIndex > Period Then
    Tot += (PfS.Last / PfS.Last(1) - _
        PfS.Last(Period) / PfS.Last(PeriodPlus))
Else If isFirstBar Then
    Tot = 0
    PeriodPlus = Period + 1
    PeriodMinus = Period - 1
Else
    Tot += PfS.Last / PfS.Last(1)
End If
If CurrentIndex >= Period Then
    Dim Sum(3) As Single
    Dim Avg As Single = Tot / Period
    For i As Integer = 0 To PeriodMinus
        If PfS.Last(i) / PfS.Last(i + 1) > Avg Then
            Sum(0) += 100 * (PfS.Last(i) / PfS.Last(i + 1) - 1)
            Sum(2) += 100 * (Price.Last(i) / Price.Last(i + 1) - 1)
        Else If PfS.Last(i) / PfS.Last(i + 1) < Avg Then
            Sum(1) += 100 * (PfS.Last(i) / PfS.Last(i + 1) - 1)
            Sum(3) += 100 * (Price.Last(i) / Price.Last(i + 1) - 1)
        End If
    Next
    Dim Ratio(1) As Single
    Ratio(0) = Sum(2) / Sum(0)
    Ratio(1) = Sum(3) / Sum(1)
    Plot = ((((Ratio(0) - Ratio(1)) ^ 2 * 2) ^ .5) * .5) * _
        ((Ratio(0) - Ratio(1)) / System.Math.Abs(Ratio(0) - Ratio(1)))
Else
    Plot = Single.NaN
End If

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Friday, May 20, 2011 1:55:33 PM
Registered User
Joined: 2/26/2005
Posts: 115
Super Thanks!, Bruce. 
I loaded and it seems to work, but I tested it on a couple of symbols and I am worried that it comes up with different results than I got on excel calculations. If you do not mind, I will forward you via Support an elementary excel spreadsheet that step by step shows all the calculations for you to check the code--it would be much easier for you to see what is involved. It's a simple example with just two symbols, SPY for S2 and IF for S1 (as they are referred to in my description). When I run IF through the code it gives me a -0.43 value while my spreadsheet indicates it should be +13.74, which is a big difference in both size and sign (which is very important for what I am computing). 

Looking forward to your input and Many Thanks in Advance!
Bruce_L
Posted : Friday, May 20, 2011 2:40:00 PM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
I'm sure I'm just misunderstanding part of your description. Looking at a spreadsheet should be quite helpful.

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
Bruce_L
Posted : Friday, May 20, 2011 4:36:03 PM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
The formulas in the 510 row (G510, H510, I510 & J510) in the code section of the spreadsheet actually seems to be adding up 380 lines instead of 126 (129 through 508).

That said, I think the primary reason it doesn't match is the RealCode compares each Percent Change during the Period to Average Percent Change during the same Period. This means a 126-Period version starts returning Values at 127-Bars and can make comparisons at the the second Bar (the first Bar with a Percent Change). This requires looping at each Bar to make the comparisons.

The spreadsheet compares the Percent Change at any given point to the Average Percent Change at that same point. This means the 127th Bar is the first Bar to get added to the sum and you need 126 more Bars to get to your first Sum (or whatever this is set to if there are different Periods for the Moving Average and the Sum). On the plus side, this eliminates looping back at each Bar. Since the Average doesn't change after the comparisons are made, you only need to compare the Average to the actual value once.

Changing to your method should probably create quicker RealCode, but the RealCode will also be more complicated and require more variables. I'm working on it, but probably won't get it done before Monday at the earliest.

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
Bruce_L
Posted : Tuesday, May 24, 2011 10:35:02 AM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
You would need to Drag and Drop a Price for Symbol Indicator into the Code tab of the RealCode Editor to create the first line of the following RealCode Indicator:

'# PfS = indicator.PriceforSymbol.2
'# AvgPeriod = UserInput.Integer = 126
'# SumPeriod = UserInput.Integer = 126
Static Percent As New System.Collections.Generic.List(Of Single)
Static Average As New System.Collections.Generic.List(Of Single)
Static S2Above As New System.Collections.Generic.List(Of Single)
Static S2Below As New System.Collections.Generic.List(Of Single)
Static S1Above As New System.Collections.Generic.List(Of Single)
Static S1Below As New System.Collections.Generic.List(Of Single)
Static Sum(3) As Single
If isFirstBar Then
    Percent.Clear
    Average.Clear
    Average.Add(0)
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
    For i As Integer = 0 To 3
        Sum(i) = 0
    Next
    Plot = Single.NaN
Else
    Percent.Add(100 * (PfS.Last / PfS.Last(1) - 1))
    Average(Average.Count - 1) += Percent(Percent.Count - 1) / AvgPeriod
    If Percent.Count >= AvgPeriod Then
        If Percent(Percent.Count - 1) >= Average(Average.Count - 1) Then
            S2Above.Add(Percent(Percent.Count - 1))
            S1Above.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(0) += S2Above(S2Above.Count - 1)
            Sum(2) += S1Above(S1Above.Count - 1)
        Else
            S2Below.Add(Percent(Percent.Count - 1))
            S1Below.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(1) += S2Below(S2Below.Count - 1)
            Sum(3) += S1Below(S1Below.Count - 1)
        End If
        If Average.Count >= SumPeriod Then
            Dim RatioUp As Single = Sum(2) / Sum(0)
            Dim RatioDn As Single = Sum(3) / Sum(1)
            Plot = ((((RatioUp - RatioDn) ^ 2 * 2) ^ .5) * .5) * _
                ((RatioUp - RatioDn) / System.Math.Abs(RatioUp - RatioDn))
            If Percent(0) >= Average(0) Then
                Sum(0) -= S2Above(0)
                Sum(2) -= S1Above(0)
                S2Above.RemoveAt(0)
                S1Above.RemoveAt(0)
            Else
                Sum(1) -= S2Below(0)
                Sum(3) -= S1Below(0)
                S2Below.RemoveAt(0)
                S1Below.RemoveAt(0)
            End If
            Average.RemoveAt(0)
        Else
            Plot = Single.NaN
        End If
        Average.Add(Average(Average.Count - 1) - Percent(0) / AvgPeriod)
        Percent.RemoveAt(0)
    Else
        Average(0) += Percent(Percent.Count - 1) / AvgPeriod
        Plot = Single.NaN
    End If
End If
If isLastBar Then
    Percent.Clear
    Average.Clear
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
End If

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Thursday, May 26, 2011 9:43:19 AM
Registered User
Joined: 2/26/2005
Posts: 115

Hey Bruce, great work--many thanks! You are right that my spreadsheet formulas in the 510 row (G510, H510, I510 & J510) say that I am using averages over 126 days, but in reality they calculate 380 days. My mistake. I am not sure if in your code you ended up doing a 126 or a 380 average... I cannot tell... but instead I wanted to ask you to make this value a selectable parameter. In fact there should be two parameters that one can specify when bringing up the indicator:

the number of days in the average of the closes of S2 against which each daily close of S2 is compared to decide if it is above or below (NAME THIS "LOOKBACK")

and the number of days in the average of the sums (in rows 510) (NAME THIS "SPAN")

Can you make this modification in the code? And how would the final code look like?

Thanks!

Bruce_L
Posted : Thursday, May 26, 2011 9:51:49 AM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
There already are two userinputs. The one you call LOOKBACK is called AvgPeriod and the one you call SPAN is called SumPeriod. Here is a version using your variable names instead:

'# PfS = indicator.PriceforSymbol.2
'# LOOKBACK = UserInput.Integer = 126
'# SPAN = UserInput.Integer = 126
Static Percent As New System.Collections.Generic.List(Of Single)
Static Average As New System.Collections.Generic.List(Of Single)
Static S2Above As New System.Collections.Generic.List(Of Single)
Static S2Below As New System.Collections.Generic.List(Of Single)
Static S1Above As New System.Collections.Generic.List(Of Single)
Static S1Below As New System.Collections.Generic.List(Of Single)
Static Sum(3) As Single
If isFirstBar Then
    Percent.Clear
    Average.Clear
    Average.Add(0)
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
    For i As Integer = 0 To 3
        Sum(i) = 0
    Next
    Plot = Single.NaN
Else
    Percent.Add(100 * (PfS.Last / PfS.Last(1) - 1))
    Average(Average.Count - 1) += Percent(Percent.Count - 1) / LOOKBACK
    If Percent.Count >= LOOKBACK Then
        If Percent(Percent.Count - 1) >= Average(Average.Count - 1) Then
            S2Above.Add(Percent(Percent.Count - 1))
            S1Above.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(0) += S2Above(S2Above.Count - 1)
            Sum(2) += S1Above(S1Above.Count - 1)
        Else
            S2Below.Add(Percent(Percent.Count - 1))
            S1Below.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(1) += S2Below(S2Below.Count - 1)
            Sum(3) += S1Below(S1Below.Count - 1)
        End If
        If Average.Count >= SPAN Then
            Dim RatioUp As Single = Sum(2) / Sum(0)
            Dim RatioDn As Single = Sum(3) / Sum(1)
            Plot = ((((RatioUp - RatioDn) ^ 2 * 2) ^ .5) * .5) * _
                ((RatioUp - RatioDn) / System.Math.Abs(RatioUp - RatioDn))
            If Percent(0) >= Average(0) Then
                Sum(0) -= S2Above(0)
                Sum(2) -= S1Above(0)
                S2Above.RemoveAt(0)
                S1Above.RemoveAt(0)
            Else
                Sum(1) -= S2Below(0)
                Sum(3) -= S1Below(0)
                S2Below.RemoveAt(0)
                S1Below.RemoveAt(0)
            End If
            Average.RemoveAt(0)
        Else
            Plot = Single.NaN
        End If
        Average.Add(Average(Average.Count - 1) - Percent(0) / LOOKBACK)
        Percent.RemoveAt(0)
    Else
        Average(0) += Percent(Percent.Count - 1) / LOOKBACK
        Plot = Single.NaN
    End If
End If
If isLastBar Then
    Percent.Clear
    Average.Clear
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
End If

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Thursday, June 9, 2011 1:07:27 AM
Registered User
Joined: 2/26/2005
Posts: 115

Bruce, I have had the time to play around with the indicator you coded above and it looks like it has some weird behavior--can you please recheck the coding?! I would appreciate it. 

Here it is:
The LOOKBACK annd the SPAN periods should be independent, but I noticed that when the Lookback is set at 126, then the SPAN cannot be set at much smaller values, like 9 (try that on the XME--it does not plot any recent values)... Why?!

Bruce_L
Posted : Thursday, June 9, 2011 2:29:02 PM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
The issue appears to be that when the SPAN is smaller than LOOKBACK by a significant margin, it is possible for every Bar during the SPAN to either be Above or Below the Average. I've added checks for this to avoid the errors that would cause. It should not Plot anything when a division by zero would have otherwise occurred.

'# PfS = indicator.PriceforSymbol.2
'# LOOKBACK = UserInput.Integer = 126
'# SPAN = UserInput.Integer = 126
Static Percent As New System.Collections.Generic.List(Of Single)
Static Average As New System.Collections.Generic.List(Of Single)
Static S2Above As New System.Collections.Generic.List(Of Single)
Static S2Below As New System.Collections.Generic.List(Of Single)
Static S1Above As New System.Collections.Generic.List(Of Single)
Static S1Below As New System.Collections.Generic.List(Of Single)
Static Sum(3) As Single
If isFirstBar Then
    Percent.Clear
    Average.Clear
    Average.Add(0)
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
    For i As Integer = 0 To 3
        Sum(i) = 0
    Next
    Plot = Single.NaN
Else
    Percent.Add(100 * (PfS.Last / PfS.Last(1) - 1))
    Average(Average.Count - 1) += Percent(Percent.Count - 1) / LOOKBACK
    If Percent.Count >= LOOKBACK Then
        If Percent(Percent.Count - 1) >= Average(Average.Count - 1) Then
            S2Above.Add(Percent(Percent.Count - 1))
            S1Above.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(0) += S2Above(S2Above.Count - 1)
            Sum(2) += S1Above(S1Above.Count - 1)
        Else
            S2Below.Add(Percent(Percent.Count - 1))
            S1Below.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(1) += S2Below(S2Below.Count - 1)
            Sum(3) += S1Below(S1Below.Count - 1)
        End If
        If Average.Count >= SPAN Then
            If Sum(0) <> 0 AndAlso Sum(1) <> 0 Then
                Dim RatioUp As Single = Sum(2) / Sum(0)
                Dim RatioDn As Single = Sum(3) / Sum(1)
                If RatioUp <> RatioDn Then
                    Plot = ((((RatioUp - RatioDn) ^ 2 * 2) ^ .5) * .5) * _
                        ((RatioUp - RatioDn) / System.Math.Abs(RatioUp - RatioDn))
                Else
                    Plot = Single.NaN
                End If
            Else
                Plot = Single.NaN
            End If
            If Percent(0) >= Average(0) Then
                If S2Above.Count >= 1 Then
                    Sum(0) -= S2Above(0)
                    Sum(2) -= S1Above(0)
                    S2Above.RemoveAt(0)
                    S1Above.RemoveAt(0)
                End If
            Else
                If S2Below.Count >= 1 Then
                    Sum(1) -= S2Below(0)
                    Sum(3) -= S1Below(0)
                    S2Below.RemoveAt(0)
                    S1Below.RemoveAt(0)
                End If
            End If
            Average.RemoveAt(0)
        Else
            Plot = Single.NaN
        End If
        Average.Add(Average(Average.Count - 1) - Percent(0) / LOOKBACK)
        Percent.RemoveAt(0)
    Else
        Average(0) += Percent(Percent.Count - 1) / LOOKBACK
        Plot = Single.NaN
    End If
End If
If isLastBar Then
    Percent.Clear
    Average.Clear
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
End If

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Sunday, June 12, 2011 6:26:25 PM
Registered User
Joined: 2/26/2005
Posts: 115
I appreciate the rework! Outside some weird numbers I have little ability to verify if we are hitting the target, but let me ask you about a discrepancy: In the spreadsheet I sent you the IF symbol produces a value of 13.74 for a LOOKBACK = 126 and SPAN = 380 on 5/19/2011 and that number is nowhere near to the numbers that either your previous formula (-49.45) or the current re-worked formula (0.01) produce. Why can't we replicate the excel values?
Bruce_L
Posted : Wednesday, June 15, 2011 1:33:49 PM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
I've noticed at least two differences between the RealCode and the spreadsheet. The spreadsheet multiplies the ratios by 100 and the ratios in the RealCode are reversed. I adjust the RealCode to match the spreadsheet in both regards below, but it still won't match.

The older adjusted prices from Yahoo for both SPY and IF in the spreadsheet do not match the prices in StockFinder. In some cases the adjusted prices are significantly different. That said, my attempts to plug StockFinder's prices into your spreadsheet didn't produce a match either (even after I figured out that the spreadsheet's setting were such that it required a manual update). I have no idea what the differences might be at this point. Creating an exact match appears to be beyond my abilities to help you.

'# PfS = indicator.PriceforSymbol.2
'# LOOKBACK = UserInput.Integer = 126
'# SPAN = UserInput.Integer = 380
Static Percent As New System.Collections.Generic.List(Of Single)
Static Average As New System.Collections.Generic.List(Of Single)
Static S2Above As New System.Collections.Generic.List(Of Single)
Static S2Below As New System.Collections.Generic.List(Of Single)
Static S1Above As New System.Collections.Generic.List(Of Single)
Static S1Below As New System.Collections.Generic.List(Of Single)
Static Sum(3) As Single
If isFirstBar Then
    Percent.Clear
    Average.Clear
    Average.Add(0)
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
    For i As Integer = 0 To 3
        Sum(i) = 0
    Next
    Plot = Single.NaN
Else
    Percent.Add(100 * (PfS.Last / PfS.Last(1) - 1))
    If Percent.Count >= LOOKBACK Then
        Average(Average.Count - 1) += Percent(Percent.Count - 1) / LOOKBACK
        If Percent(Percent.Count - 1) >= Average(Average.Count - 1) Then
            S2Above.Add(Percent(Percent.Count - 1))
            S1Above.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(0) += S2Above(S2Above.Count - 1)
            Sum(2) += S1Above(S1Above.Count - 1)
        Else
            S2Below.Add(Percent(Percent.Count - 1))
            S1Below.Add(100 * (Price.Last / Price.Last(1) - 1))
            Sum(1) += S2Below(S2Below.Count - 1)
            Sum(3) += S1Below(S1Below.Count - 1)
        End If
        If Average.Count >= SPAN Then
            If Sum(0) <> 0 AndAlso Sum(1) <> 0 Then
                Dim RatioUp As Single = 100 * Sum(2) / Sum(0)
                Dim RatioDn As Single = 100 * Sum(3) / Sum(1)
                If RatioUp <> RatioDn Then
                    Plot = ((((RatioUp - RatioDn) ^ 2 * 2) ^ .5) * .5) _
                        * ((RatioUp - RatioDn) / System.Math.Abs(RatioUp - RatioDn))
                Else
                    Plot = Single.NaN
                End If
            Else
                Plot = Single.NaN
            End If
            If Percent(0) >= Average(0) Then
                If S2Below.Count >= 1 Then
                    Sum(0) -= S2Above(0)
                    Sum(2) -= S1Above(0)
                    S2Above.RemoveAt(0)
                    S1Above.RemoveAt(0)
                End If
            Else
                If S2Below.Count >= 1 Then
                    Sum(1) -= S2Below(0)
                    Sum(3) -= S1Below(0)
                    S2Below.RemoveAt(0)
                    S1Below.RemoveAt(0)
                End If
            End If
            Average.RemoveAt(0)
        Else
            Plot = Single.NaN
        End If
        Average.Add(Average(Average.Count - 1) - Percent(0) / LOOKBACK)
        Percent.RemoveAt(0)
    Else
        Average(0) += Percent(Percent.Count - 1) / LOOKBACK
        Plot = Single.NaN
    End If
End If
If isLastBar Then
    Percent.Clear
    Average.Clear
    S2Above.Clear
    S2Below.Clear
    S1Above.Clear
    S1Below.Clear
End If

-Bruce
Personal Criteria Formulas
TC2000 Support Articles
kostas_gr
Posted : Thursday, June 16, 2011 1:42:13 AM
Registered User
Joined: 2/26/2005
Posts: 115
Super thanks, Bruce, for your hard work in coding the spreadsheet--I am very thankful. In case this is of broader value, could you plug in the K or anybody from the developement team to help? I may reveal some problems/limitations with the program language... The type of relationships in the spreadsheet are central to many good tools and they should be within SF/TCD2000's capability rangerange.
Bruce_L
Posted : Thursday, June 16, 2011 7:32:33 AM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138
No. While they might help with StockFinder 5 RealCode under certain circumstances, they aren't going to help with a StockFinder 4 RealCode Indicator. We don't offer a programming service. Any RealCode provided is for educational purposes only.

The only reason the RealCode is so complicated is because we are doing it in StockFinder 4. The language has expanded significantly in StockFinder 5 and I would probably write much different RealCode which takes advantage of the changes. I'm doing something wrong when I'm manually creating functions which already exist as part of the RealCode in StockFinder 5, I just can't figure out what.

I have created a block diagram based version which work in StockFinder 4 and matches the results of the spreadsheet when it is using StockFinder's data. You should be able to Open an attached Indicator directly into a running copy of StockFinder (and save it from within StockFinder if desired).

Attachments:
kostas_gr52197.sfInd - 10 KB, downloaded 522 time(s).



-Bruce
Personal Criteria Formulas
TC2000 Support Articles
Users browsing this topic
Guest-1

Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.