Tillson's T3?
Author: fritz
Creation Date: 3/1/2010 6:42 PM
profile picture

fritz

#1
Has anyone implemented Tim Tillson's T3 average? I have the Tradestation code (below) but I'm unsure how to convert it into usable single & series functions. I tried modifying TEMA but some of the steps in there are not clear to me.

Thanks!
Gary

CODE:
Please log in to see this code.
profile picture

fritz

#2
I've made an attempt at it, but it's not working (the series is all 0's) and I have no idea what's wrong. I think the T3 calculations are right but the various pieces fitting it into WL are a mystery to me. Can someone take a look at this and see what I did wrong?

Thanks!
Gary

CODE:
Please log in to see this code.
profile picture

Eugene

#3
QUOTE:
Can someone take a look at this and see what I did wrong?

One thing that looks obvious is that the variables e1 ... e6 are defined as "(Price)" in the original EasyLanguage code, in other words - a DataSeries like Bars.Close. However, in your translation, they're fixed uninitialized double values (always equal to 0), not DataSeries how they should be.

e1*XBeta and the rest are always 0.
profile picture

fritz

#4
No, in TradeStation EasyLanguage all vars are float unless explicitly specified otherwise. EL doesn't have a DataSeries type like WL. (At least not explicitly. All variables actually have implicit history in them, and so in that respect you could say they're series. But the code is using single floats.) EL has an implicit loop in it, so the code (other than the variable initializations) is executed on each bar.

Defining "var: e1(Price)" means e1 is initialized to the first value of Price, which is an input parameter. It's generally set to Close but could be set to any expression. So e.g. you could pass T3 a Price parameter of (H+L)/2 or Date+Open or any random calculation.

Since the eN variables are initialized to Price, i.e. the first value passed in the Price parameter, I wanted to initialize my eN vars the same way -- I wanted to initialize them to the initial value of the dataseries, using "e1 = e2 = e3 = e4 = e5 = e6 = ds[FirstValidValue];". If e1*XBeta &etc are zero, then that initialization must not have worked right. Does it look right to you?

I gotta get a debugging project set up so I can run this stuff through the Visual Studio debugger... (The web pages describing how to do that are not exactly clear, but a friend has sent me a copy of his project so I should be able to get it figured out.)

Once we have the code working right, how do I place the functions in a namespace? library? so I can reference it from other strategies?
profile picture

Eugene

#5
QUOTE:
(The web pages describing how to do that are not exactly clear, but a friend has sent me a copy of his project so I should be able to get it figured out.)

So far it's all public documentation we have got from Fidelity on the API. For debugging, download the TASC/Community.Indicators projects. The details will vary depending on the flavor of your IDE (SharpDevelop, VS, VS Express), but in general, you should attach to the WealthLab's process, drag & drop your indicator on a chart (or define the series in a Strategy), and debug it like you usually do with other .NET DLLs.
QUOTE:
Once we have the code working right, how do I place the functions in a namespace? library? so I can reference it from other strategies?

Since your code template originates from TASCIndicators, and you must have obtained it from the Wiki, I don't quite understand the question. Yes, you can reference them - the WL5 Wiki has a great deal of examples of calling and using custom indicators (which don't differ from the built-in ones in this aspect). Perhaps the best is to download TASCIndicators or Community.Indicators and see how they're organized, considering that the API doc on creating indicator libraries is still not released. :( Let us know if something is not clear.

1. "EMACalculation.Modern" is excessive in _paramDefaults and should be removed.
2. Instead, add a new RangeBoundDouble for "damp" and define it in _paramNames as well.
3. Instead of T3vals, assign the result to base[bar].

Your code should start working then, producing a moving avereage sort of line on the PricePane, although I probably have no idea how should real T3 look like.
profile picture

fritz

#6
Yes, I started with TEMA in TASCIndicators, but that doesn't mean I know how to use it. :) I'll see what I can find on the wiki.

I can find no documentation for RangeBoundDouble but I figured it out from some examples in TASCIndicators. (BTW in case you're wondering, yes T3 accepts non-integral "period" values and does sensible things with them.)

Assigning result to base[bar]: here?
CODE:
Please log in to see this code.

I was following the TEMA model, which stored its intermediate values in ema1/2/3. Should I get rid of T3vals entirely?

If I do that, what about returning partials? (I don't even know what that is!) Change that to base too?
CODE:
Please log in to see this code.


I made those changes and it appears to work properly now! Thanks for the help!

T3 is a nice smooth and fairly low-lag average:

profile picture

Eugene

#7
Glad you got it sorted out.
QUOTE:
Assigning result to base[bar]: here?

Right.
QUOTE:
I can find no documentation for RangeBoundDouble

It appears to be a Wealth-Lab class, I could find a mention of it in the API documentation. Just in case you wonder, BarsDataType.Bars is used when one of your default parameters return a Bars object, CoreDataSeries... is for the basic DataSeries (OHLCV), RangeBoundDouble/RangeBoundInt32 are self-descriptive.
QUOTE:
If I do that, what about returning partials? (I don't even know what that is!)

See the QuickRef on PartialValue. Basically, it means accessing the "ghost bar" in your Strategy and/or drag-n-dropped indicators. Robert should have more experience with building indicators returning partial values.

btw, would you mind if we add the T3 to Community.Indicators?
profile picture

fritz

#8
That's fine. T3.Series works, but do you want a function that returns a single value? Or do you just use T3.Series(x,y,z)[bar] for that?

Here's the code I've got now:

CODE:
Please log in to see this code.
profile picture

Carova

#9
Is there a problem with this indicator? I dropped this indicator with 2 different damping factors (0.10 and 0.90) and the curves are on top of one another. Also, the descriptions in the top left corner do not show the damping factors.

Vince
profile picture

Eugene

#10
Yes, it's a bug. The missing damping factor is a good clue and the culprit. Thanks for the heads-up. Look for a fix in the upcoming release 2015.06 of Community Indicators.
profile picture

Carova

#11
I am surprised that no one noticed it during the past 5 years! ;)

Vince
profile picture

Eugene

#12
profile picture

Carova

#13
SO TRUE!