Description
In the April 2011 issue of TASC magazine, Dr. Siligardos presented an algorithm to detect cups (as in "cup and handle") early in their formation. As such he called the pattern a "semi-cup". As described in the
associated Traders' Tip, we modified the algorithm and added the classes below to the TASCIndicator library.
Note! Although Semi-Cup Pattern Detection is included in the
TASCIndicators component, it is not an indicator. You must employ the classes (as shown by the examples) by manual programming.
CupStatus
A Semicup object is created for each peak in the Peak.Series. The enumeration defines the status of a Semicup object, primarily during its formation.
public enum CupStatus { Search, SemiCupDetected, Duplicate, LevelExceeded, Failure, FormingCup }
Search | Semicup has not yet been detected for the associated peak. |
SemiCupDetected | A Semicup has been detected for the associated peak. |
Duplicate | Semicup is considered a duplicate of another detected Semicup. (Not currently used) |
LevelExceeded | The peak level has been exceeded, and therefore a Semicup will not be associated with this peak. |
Failure | The Semicup failed by closing lower than the previous lowest level of the cup. After a Failure, the Semicup goes back into Search mode, which most often results in a new cup being detected almost immediately. |
FormingCup | The Semicup is determined to be "successful" by closing higher than the L2 box level. No further updates occur after a FormingCup status. |
Semicups
Semicups is the container of all Semicups, each of which is associated with a peak in the PeakBar.Series. By instantiating SemiCups, all Semicup objects are created and these may then be accessed from the Cups Dictionary (see Cups member below).
public SemiCups(WealthScript ws, int minBars, DataSeries pkBarSer)
ws | An instance of the WealthScript object. Pass this. |
minBars | The minimum number of bars spanned by a Semicup. For example, if a peak occurs on bar number 100, and minBars is 20, an associated Semicup cannot be detected prior to bar 120. |
pkBarSer | Each Semicup is associated with a peak in the PeakBar.Series. Pass a PeakBar DataSeries. |
ActiveSemiCups(int bar)
For backtesting: returns a list of "active" SemiCups, which are SemiCups that have achieved CupStatus.SemiCupDetected as least once, but then can have any status including CupStatus.Search thereafter. SemiCups are returned in this list up to and including the bar declared Inactive or FormingCup. See SemiCup.Status for the CupStatus of a SemiCup at each bar.
public List<SemiCup> ActiveSemiCups(int bar)
Draw()
Member of SemiCups. Draw displays the detection grid, semi-cup curve, and failure/success arrows on the current chart.
public void Draw()
PkBarList
Member of SemiCups. PkBarList is simply a convenient integer list of peak bars for the PeakBar.Series passed to SemiCups. A Semicup is associated with each item in this list and can be used as the key to the Cups Dictionary (below).
public IList<int> PkBarList = new List<int>();
Cups()
Member of SemiCups. Cups is a Dictionary of SemiCups. Iterate through Cups using foreach (KeyValuePair
kvp in semiCups.Cups) or by identifying a particular peak from the PkBarList. Note: in the 2011.4.0.1 version of TASCIndicators, some peak bars are not added to the list if the chance of creating an essentially "duplicate" SemiCup is high. Use the .ContainsKey() method to determine if a peak bar exists in Cups.
public Dictionary<int, SemiCup> Cups
Semicup
Semicup is an object associated with each PeakBar. You are not required to instantiate Semicup objects - this is done by the Semicups class. Instead, you will be interested only the properties of a Semicup, as defined below.
public SemiCup(WealthScript ww, int B0, int B5, DataSeries lnClose, DataSeries momentum, IList<int> pbL)
SemiCupBars
Property of SemiCup. Contains a list of bar numbers on which this instance was detected as a Semicup. If the list is empty, a Semicup was never detected for the associated PeakBar. The first bar in the list is the first detection.
public List<int> SemiCupBars
FailureBars
Property of SemiCup. Contains a list of bar numbers on which this Semicup "failed" by creating a new low in the formation. On the following bar, this Semicup instance may or may not be "detected" again. If the list is empty, the Semicup never failed following the first detection.
public List<int> FailureBars
Status
For backtesting provides the ability to know the CupStatus for every bar between StartBar and BarInactive, inclusive.
public Dictionary<int, CupStatus> Status
Level()
For detection purposes, SemiCups are divided into 6 levels (5 equal boxes), 0 to 5, inclusive. Level 0 is the base and Level 5 is the top of the SemiCup. After a SemiCup is detected, if price crosses Level 2, it is assumed a Cup pattern is forming and the SemiCup is frozen.
For backtesting, the Level method provides the ability to return specific levels of a SemiCup formation as of a specified bar. Levels change after a SemiCup is detected and then fails. The bar passed to the method should be in the range StartBar, InactiveBar.
public double Level(int bar, int level)
Active
Property of SemiCup. The Active status is false if this SemiCup has a) achieved a CupStatus.FormingCup, or, b) has no possibility of achieving CupStatus.SemiCupDetected. Use this property for Scans to determine which SemiCup objects are still active. Do not use this property for backtesting and instead use the SemiCupBars and FailureBars to determine the status of the SemiCup on a given bar.
public bool Active
StartBar
Property of SemiCup. This is the starting peak bar (left-most bar) of the SemiCup formation.
public int StartBar
BarInactive
Property of SemiCup. This is the bar on which the Semicup has become inactive, i.e., Active = false.
public int BarInactive
Example
See TASCApr2011
Also see Semi-Cup Trading System