Overall Statistics
Total Trades
82
Average Win
1.67%
Average Loss
-2.46%
Compounding Annual Return
8.804%
Drawdown
10.200%
Expectancy
0.065
Net Profit
5.828%
Sharpe Ratio
0.465
Loss Rate
37%
Win Rate
63%
Profit-Loss Ratio
0.68
Alpha
0.07
Beta
0.002
Annual Standard Deviation
0.149
Annual Variance
0.022
Information Ratio
0.723
Tracking Error
0.563
Treynor Ratio
29.323
Total Fees
$16016.64
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;
using System.Drawing;
using QuantConnect.Statistics;
using System;
using System.Collections.Generic;
using System.Linq;

namespace QuantConnect.Algorithm.CSharp
{

    /// <summary>
    /// DeMark Strategy Algorithm.
    /// This class has the methods for working with DeMark Setup Indicator.
    /// </summary>
    /// <remarks>
    /// There is 3 timeframes supported by the strategy (H1, H4 and D1).
    /// </remarks>
    public class DeMarkAlgorithm : QCAlgorithm
    {
        enum Timeframe { H1, H4, D1 };

        // Input Parameters
        private bool OpenOnTrend = true;
        private bool OpenOnPerfect = true;
        private bool OpenOnCountdown = false;

        private const bool UseTrailingStop = false;

        private const Timeframe TimeFrame = Timeframe.H4;

        private const decimal StopLoss = 0.02m;
        private const decimal TakeProfit = 0.02m;

        private const decimal InitialBalance = 100000m;

        private Symbol _tradeSymbol;

        // Internal Variables
        private RollingWindow<TradeBar> _bars;

        private decimal _longStopLoss;
        private decimal _longTakeProfit;
        private decimal _shortStopLoss;
        private decimal _shortTakeProfit;

        private TradeBuilder _tradeBuilder;

        private DeMarkSetup _longSetup, _shortSetup;
        
        // Debugging
        private int _long_trailing_stop_counter;
        private int _short_trailing_stop_counter;
        
        private int _longTrendCount;
        private int _longPerfectCount;
        private int _longCountdownCount;
        private int _shortTrendCount;
        private int _shortPerfectCount;
        private int _shortCountdownCount;

        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        public override void Initialize()
        {
            // Backtest Parameters
            SetStartDate(2018, 4, 1);
            SetEndDate(2018, 12, 1);
            SetCash(InitialBalance);
            // Brokerage Model
            SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin);
            // Symbol and Market Parameters
            _tradeSymbol = QuantConnect.Symbol.Create("BTCUSD", SecurityType.Crypto, Market.Bitfinex);
            Security security;

            switch (TimeFrame)
            {
                case Timeframe.H1:

                    security = AddCrypto(_tradeSymbol, Resolution.Tick);
                    BrokerageModel.GetFeeModel(security);
                    // Consolidator
                    TickConsolidator consolidator = new TickConsolidator(TimeSpan.FromHours(1));
                    consolidator.DataConsolidated += BarHandler;
                    SubscriptionManager.AddConsolidator(_tradeSymbol, consolidator);
                    break;

                case (Timeframe.H4):

                    security = AddCrypto(_tradeSymbol, Resolution.Tick);
                    BrokerageModel.GetFeeModel(security);
                    // Consolidator
                    TickConsolidator fourHourConsolidator = new TickConsolidator(TimeSpan.FromHours(4));
                    fourHourConsolidator.DataConsolidated += BarHandler;
                    SubscriptionManager.AddConsolidator(_tradeSymbol, fourHourConsolidator);
                    break;

                case (Timeframe.D1):

                    security = AddCrypto(_tradeSymbol, Resolution.Tick);
                    BrokerageModel.GetFeeModel(security);
                    // Consolidator
                    TickConsolidator dailyconsolidator = new TickConsolidator(TimeSpan.FromDays(1));
                    dailyconsolidator.DataConsolidated += BarHandler;
                    SubscriptionManager.AddConsolidator(_tradeSymbol, dailyconsolidator);
                    break;

                default:

                    Quit("Timeframe not supported");
                    break;
            }
            SetBenchmark(_tradeSymbol);
            SetWarmup(1);

            _bars = new RollingWindow<TradeBar>(15);
            // Create charts for signals, stops and indicator
            CreateChart();

            _longSetup = new DeMarkSetup(Directions.Up);
            _shortSetup = new DeMarkSetup(Directions.Dw);
            // TradeBuilder for Balance Drawdown calculation
            _tradeBuilder = new TradeBuilder(FillGroupingMethod.FlatToFlat, FillMatchingMethod.FIFO);
            SetTradeBuilder(_tradeBuilder);
        }

        /// <summary>
        /// OnData event is the primary entry point for the algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice data)
        {
            if (CheckStops())
            {
                ClosePositions();
            }
        }

        /// <summary>
        /// Called every order event.
        /// </summary>
        /// <param name="orderEvent">Object with order data</param>
        /// <remarks>
        /// Calculate stops values after order is filled.
        /// </remarks>
        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            if (orderEvent.Status == OrderStatus.Filled)
            {
                if (orderEvent.Direction == OrderDirection.Buy)
                {
                    DefineTakeProfit(orderEvent.FillPrice, Directions.Up);
                    DefineStopLoss(orderEvent.FillPrice, Directions.Up);
                }

                else if (orderEvent.Direction == OrderDirection.Sell)
                {
                    DefineTakeProfit(orderEvent.FillPrice, Directions.Dw);
                    DefineStopLoss(orderEvent.FillPrice, Directions.Dw);
                }
            }

            if (orderEvent.Status == OrderStatus.Canceled)
            {
                Log("Order Canceled");
            }
            else if (orderEvent.Status == OrderStatus.Invalid)
            {
                Log("Invalid Order");
            }
        }

        /// <summary>
        /// Called after strategy stop running.
        /// </summary>
        /// <remarks>
        /// Close current position and calculate balance drawdown.
        /// </remarks>
        public override void OnEndOfAlgorithm()
        {
            ClosePositions();
            decimal peak = InitialBalance;
            decimal balance = peak;
            decimal valley = 0m;
            decimal balanceDrawdown = 0m;

            foreach (var trade in _tradeBuilder.ClosedTrades)
            {
                balance += trade.ProfitLoss - trade.TotalFees;

                if (balance > peak)
                {
                    peak = balance;
                    valley = peak;
                }
                else
                {
                    valley = balance;
                }

                if ((peak - valley) / peak > balanceDrawdown)
                    balanceDrawdown = (peak - valley) / peak;
            }
            Console.WriteLine($"Balance Drawdown % (From Risk Framework): {balanceDrawdown * 100}%");
            Console.WriteLine($"Long: {_long_trailing_stop_counter}   Short: {_short_trailing_stop_counter}");
        }

        /// <summary>
        /// Handle bar information after bar consolidation.
        /// </summary>
        /// <param name="sender">The object calling <c>BarHandler</c></param>
        /// <param name="consolidated">The bar values consolidated</param>
        /// <remarks>
        /// After bar is formed, calculate DeMark indicator and call trailing stop method.
        /// </remarks>
        private void BarHandler(object sender, TradeBar consolidated)
        {
            if (IsWarmingUp)
                return;

            _bars.Add(consolidated);

            if (_bars.Count >= 1)
                Plot("ChartSignals", "BarSerie", _bars[0].Close);

            if (UseTrailingStop)
                CheckTrailingStop();

            if (_bars.Count >= 15)
            {
            	Signal LongSignals = _longSetup.StepForward(_bars);
            	Signal ShortSignals = _shortSetup.StepForward(_bars);
                if (OpenOnTrend) 
                { 
                	if(LongSignals.Trend)
                	{
	                    if (!Portfolio[_tradeSymbol].Invested)
	                    {
	                        OpenPosition(Directions.Up);
	                    }
	                    _longTrendCount += 1;
                	}
                    if(ShortSignals.Trend)
                    {
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Dw);
                        }
                        _shortTrendCount += 1;
                    }
                }
                if (OpenOnPerfect)
                {
                    if (LongSignals.Perfect)
                    {
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Up);
                        }
                        PlotLongPerfectSignal();
                        _longPerfectCount += 1;
                    }
                    if (ShortSignals.Perfect)
                    {
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Dw);
                        }
                        PlotShortPerfectSignal();
                        _shortPerfectCount += 1;
                    }
                }
                if (OpenOnCountdown)
                {
                    if (LongSignals.Countdown)
                    {
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Up);
                        }
                        PlotLongCountdownSignal();
                        _longCountdownCount += 1;
                    }
                    if (ShortSignals.Countdown)
                    {
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Dw);
                        }
                        PlotShortCountdownSignal();
                        _shortCountdownCount += 1;
                    }
                }
            }
        }

        /// <summary>
        /// Check if current price reached stop loss or take profit of the
        /// position openned (if any).
        /// </summary>
        /// <returns>If the position must be closed or not.</returns>
        private bool CheckStops()
        {
            // Nothing to do if none position is open
            if (!Portfolio[_tradeSymbol].Invested)
                return (false);

            if (Portfolio[_tradeSymbol].IsLong)
            {
                // Stop Loss
                if (Securities[_tradeSymbol].Price <= _longStopLoss)
                {
                    PlotStopLoss(_longStopLoss);
                    return (true);
                }
                // Take Profit
                if (Securities[_tradeSymbol].Price >= _longTakeProfit
                && _longTakeProfit != 0m)
                {
                    PlotTakeProfit(_longTakeProfit);
                    return (true);
                }
            }
            else if (Portfolio[_tradeSymbol].IsShort)
            {
                // Stop Loss
                if (Securities[_tradeSymbol].Price >= _shortStopLoss
                && _shortStopLoss != 0m)
                {
                    PlotStopLoss(_shortStopLoss);
                    return (true);
                }
                // Take Profit
                if (Securities[_tradeSymbol].Price <= _shortTakeProfit)
                {
                    PlotTakeProfit(_shortTakeProfit);
                    return (true);
                }
            }
            return (false);
        }

        /// <summary>
        /// Check rules for Trailing Stop Loss and call method for changing Stop Loss.
        /// </summary>
        private void CheckTrailingStop()
        {
            if (Portfolio[_tradeSymbol].Invested)
            {
            	decimal new_value = 0.0m;
                if (Portfolio[_tradeSymbol].IsLong)
                {
                	// Check if past bar is negative
                    if(_bars[1].Close - _bars[1].Open < 0)
                    {
                    	if(_bars[0].Close > _bars[1].Close &&
                    	_bars[0].Close < _bars[1].Open && 
                    	_bars[0].Open > _bars[1].Close &&
                    	_bars[0].Open < _bars[1].Open)
                    	{
                    		new_value = _bars[1].Close;
                    	}
                    } 
                    
                    if (_longStopLoss < new_value
                    && new_value < Securities[_tradeSymbol].Price)
                    {
                        ModifyStopLoss(new_value, Directions.Up);
                    }
                }
                else if (Portfolio[_tradeSymbol].IsShort)
                {
                	// Check if past bar is positive
                	if(_bars[1].Close - _bars[1].Open > 0)
                	{
                		if(_bars[0].Close < _bars[1].Close &&
                		_bars[0].Close > _bars[1].Open &&
                		_bars[0].Open < _bars[1].Close &&
                		_bars[0].Open > _bars[1].Open)
                		{
                			new_value = _bars[1].Open;
                		}
                	}
                    if (_shortStopLoss > new_value
                    && new_value > Securities[_tradeSymbol].Price)
                    {
                        ModifyStopLoss(new_value, Directions.Dw);
                    }
                }
            }
        }

        /// <summary>
        /// Close opened positions.
        /// </summary>
        /// <remarks>
        /// This function is called on stops and end of algorithm.
        /// </remarks>
        private void ClosePositions()
        {
            if (Portfolio[_tradeSymbol].Invested)
            {
                Liquidate(_tradeSymbol);
            }
        }

        /// <summary>
        /// Create chart for signals, stops and indicators.
        /// </summary>
        /// <remarks>
        /// Plot Long or Short Perfection Setups, Countdowns signals,
        /// Stop Loss, Take Profit, Stop Loss changed value by Trailing Stop.
        /// </remarks>
        private void CreateChart()
        {
            QuantConnect.Chart chart = new Chart("ChartSignals", ChartType.Stacked);
            chart.AddSeries(new Series("BarSerie", SeriesType.Line));
            chart.AddSeries(new Series("Long Perfect", SeriesType.Scatter,
                    "", Color.Blue, ScatterMarkerSymbol.Triangle));
            chart.AddSeries(new Series("Long Countdown", SeriesType.Scatter,
                    "", Color.Green, ScatterMarkerSymbol.Triangle));
            chart.AddSeries(new Series("Short Perfect", SeriesType.Scatter,
                    "", Color.Red, ScatterMarkerSymbol.TriangleDown));
            chart.AddSeries(new Series("Short Countdown", SeriesType.Scatter,
                    "", Color.Yellow, ScatterMarkerSymbol.TriangleDown));
            chart.AddSeries(new Series("TP", SeriesType.Scatter,
                    "", Color.Blue, ScatterMarkerSymbol.Circle));
            chart.AddSeries(new Series("SL", SeriesType.Scatter,
                    "", Color.Red, ScatterMarkerSymbol.Circle));
            chart.AddSeries(new Series("StopChanged", SeriesType.Scatter,
                    "", Color.Orange, ScatterMarkerSymbol.Circle));
            AddChart(chart);
        }

        /// <summary>
        /// Calculate Take Profit based on price and direction.
        /// </summary>
        /// <param name="value">The filled price must be passed as value</param>
        /// <param name="direction">Direction can be Long or Short (Direction.Up or Direction.Dw)</param>
        private void DefineTakeProfit(decimal value, Directions direction)
        {
            if (direction == Directions.Up)
            {
                _longTakeProfit = value + (value * TakeProfit);
            }
            else
            {
                _shortTakeProfit = value - (value * TakeProfit);
            }
        }

        /// <summary>
        /// Calculate Stop Loss based on price and direction
        /// </summary>
        /// <param name="value">The filled price must be passed as value</param>
        /// <param name="direction">Direction can be Long or Short (Direction.Up or Direction.Dw)</param>
        private void DefineStopLoss(decimal value, Directions direction)
        {
            if (direction == Directions.Up)
            {
                _longStopLoss = value - (value * StopLoss);
            }
            else
            {
                _shortStopLoss = value + (value * StopLoss);
            }
        }

        /// <summary>
        /// Compare two bars and get highest Bar High value.
        /// </summary>
        /// <returns>The highest High value of the two bars compared.</returns>
        private decimal GetHighestHigh()
        {
            decimal[] array = { _bars[1].High, _bars[2].High };
            return (array.Max());
        }

        /// <summary>
        /// Compare two bars and get lowest Low value.
        /// </summary>
        /// <returns>>The lowest Low value of the two bars compared.</returns>
        private decimal GetLowestLow()
        {
            decimal[] array = { _bars[1].Low, _bars[2].Low };
            return (array.Min());
        }

        /// <summary>
        /// Change value of Stop Loss and plot in the chart.
        /// </summary>
        /// <param name="value">Stop Loss new value</param>
        /// <param name="direction">Long or Short</param>
        /// <remarks>
        /// </remarks>
        private void ModifyStopLoss(decimal value, Directions direction)
        {
            if (direction == Directions.Up)
            {
                _longStopLoss = value;
                PlotStopLossChanged(_longStopLoss);
                _long_trailing_stop_counter++;
            }
            else
            {
                _shortStopLoss = value;
                PlotStopLossChanged(_shortStopLoss);
                _short_trailing_stop_counter++;
            }
        }

        /// <summary>
        /// Send market order based on parameter direction.
        /// </summary>
        /// <param name="direction">Long or Short</param>
        private void OpenPosition(Directions direction)
        {
            if (direction == Directions.Up)
            {
                SetHoldings(_tradeSymbol, 1m, true);
            }
            else
            {
                SetHoldings(_tradeSymbol, -1m, true);
            }
        }

        /// <summary>
        /// Plot the Countdown signal for Long direction.
        /// </summary>
        private void PlotLongCountdownSignal()
        {
            Plot("ChartSignals", "Long Countdown", _bars[0].Close);
        }

        /// <summary>
        /// Plot Perfect Setup signal for Long direction.
        /// </summary>
        private void PlotLongPerfectSignal()
        {
            Plot("ChartSignals", "Long Perfect", _bars[0].Close);
        }

        /// <summary>
        /// Pot Take Profit.
        /// </summary>
        /// <param name="value">Take Profit value</param>
        private void PlotTakeProfit(decimal value)
        {
            Plot("ChartSignals", "TP", value);
        }

        /// <summary>
        /// Plot Countdown signal for Short direction.
        /// </summary>
        private void PlotShortCountdownSignal()
        {
            Plot("ChartSignals", "Short Countdown", _bars[0].Close);
        }

        /// <summary>
        /// Plot Perfect Setup signal for Short direction.
        /// </summary>
        private void PlotShortPerfectSignal()
        {
            Plot("ChartSignals", "Short Perfect", _bars[0].Close);
        }

        /// <summary>
        /// Plot Stop Loss value.
        /// </summary>
        /// <param name="value">Stop Loss value</param>
        private void PlotStopLoss(decimal value)
        {
            Plot("ChartSignals", "SL", value);
        }

        /// <summary>
        /// Plot the new value of Stop Loss.
        /// </summary>
        /// <param name="value">The new Stop Loss value to be updated</param>
        /// <remarks>
        /// This function track Trailing Stop Loss working.
        /// </remarks>
        private void PlotStopLossChanged(decimal value)
        {
            Plot("ChartSignals", "StopChanged", value);
        }
    }
}
namespace QuantConnect
{

    enum Directions { Up, Dw }
    
    /// <summary>
    /// DeMark signals.
    /// Handle the signals catch in every iteration.
    /// </summary>
    public class Signal
    {
    	public bool Trend { get; set; }
    	public bool Perfect { get; set; }
    	public bool Countdown { get; set; }
    }

    /// <summary>
    /// DeMark indicator algorithm.
    /// All methods follows DeMark setups rules.
    /// </summary>
    public class DeMarkSetup
    {
        // Long or Short
        private Directions Direction;
        // Every iteration returns a Signal
        private Signal _signal;
        // The bar values is passed every iteration and used in internal functions
        private RollingWindow<TradeBar> _bar;
        // If TD Setup is not perfected, try again once more
        private bool _lookAgainForPerfection;
        private bool _checkCountdownInitialization;
        private bool _counterInitialized;
        // Store the countdown bars
        private List<TradeBar> _countdownBars = new List<TradeBar>();

        /// <summary>
        /// Constructor of DeMarkSetup class
        /// </summary>
        /// <param name="direction">Direction.Up or Direction.Dw</param>
        internal DeMarkSetup(Directions direction)
        {
            Direction = direction;
        }

        /// <summary>
        /// This function represents the iteration of DeMarkSetup.
        /// Must be called every new bar.
        /// </summary>
        /// <param name="bar"> Store the bar values for use in internal functions </param>
        /// <remarks>
        /// Reset the signal to None,
        /// check if TD Setup conditions are met,
        /// check if TD Perfect Setup conditions are met, if not, try again
        /// once more.
        /// After TD Setup, check conditions to Countdown begins,
        /// increment Countdown, if already initialized.
        /// If variable Counter is higher than 12, check if Countdown signal happened.
        /// </remarks>
        public Signal StepForward(RollingWindow<TradeBar> bar)
        {
            _bar = bar;
            _signal = new Signal();

            if (_lookAgainForPerfection)
            {
                _lookAgainForPerfection = false;
                if (PerfectSetup)
                {
                    _signal.Perfect = true;
                }
            }
            
            if (_checkCountdownInitialization)
            {
                if (UpdateCountdownAndLookForSignal())
                {
                    _signal.Countdown = true;
                    ResetCountdown();
                }
            }

            if (TDSetup)
            {
            	_signal.Trend = true;
                _checkCountdownInitialization = true;
                if (!PerfectSetup)
                {
                    _lookAgainForPerfection = true;
                }
                else
                {
                    _signal.Perfect = true;
                }
            }
            return (_signal);
        }

        /// <summary>
        /// Method <c>TDSetup</c> check if the bar values return a complete TD Setup.
        /// </summary>
        /// <remarks>
        /// The prerequisite for a TD Buy Setup is a Bearish TD
        /// Price Flip, which indicates a switch from positive to
        /// negative momentum.
        ///
        /// The prerequisite for a TD Sell Setup is a Bullish TD
        /// Price Flip, which indicates a switch from negative to
        /// positive momentum.
        ///
        /// TD Setup is an indicator that determines whether a
        /// market is likely to be confined to a trading range or
        /// starting a directional trend.
        ///
        /// TD Setup is to be followed by TD Countdown.
        ///
        /// A TD Buy Setup is that, after a bearish TD Price Flip,
        /// there must be 9 consecutive closes, each one less than
        /// the corresponding close four bars earlier.
        ///
        /// If, at any point, the sequence of 9 consecutive closing
        /// prices less than the closing price 4 bars earlier (up to
        /// and including the close of TD Buy Setup Bar 9) is
        /// interrupted, the developing TD Buy Setup must be
        /// cancelled and must begin anew.
        /// </remarks>
        public bool TDSetup
        {
            get
            {
                if (Direction == Directions.Dw)
                {
                    return (_bar[0].Close < _bar[0 + 4].Close
                    && _bar[1].Close < _bar[1 + 4].Close
                    && _bar[2].Close < _bar[2 + 4].Close
                    && _bar[3].Close < _bar[3 + 4].Close
                    && _bar[4].Close < _bar[4 + 4].Close
                    && _bar[5].Close < _bar[5 + 4].Close
                    && _bar[6].Close < _bar[6 + 4].Close
                    && _bar[7].Close < _bar[7 + 4].Close
                    && _bar[8].Close < _bar[8 + 4].Close
                    && _bar[9].Close > _bar[9 + 4].Close);
                }
                else
                {
                    return (_bar[0].Close > _bar[0 + 4].Close
                    && _bar[1].Close > _bar[1 + 4].Close
                    && _bar[2].Close > _bar[2 + 4].Close
                    && _bar[3].Close > _bar[3 + 4].Close
                    && _bar[4].Close > _bar[4 + 4].Close
                    && _bar[5].Close > _bar[5 + 4].Close
                    && _bar[6].Close > _bar[6 + 4].Close
                    && _bar[7].Close > _bar[7 + 4].Close
                    && _bar[8].Close > _bar[8 + 4].Close
                    && _bar[9].Close < _bar[9 + 4].Close);
                }
            }
        }

        /// <summary>
        /// Method <c>PerfectSetup</c> check if bar values match
        /// with Perfect Setup conditions.
        /// </summary>
        /// <remakrs>
        /// <para>
        /// TD Buy Setup “perfection” is the prerequisite for
        /// entering a long position based on a completed TD Buy
        /// Setup.
        /// </para>
        /// <para>
        /// The low of Bar 8 or Bar 9 of the TD Buy Setup must be
        /// less than, or equal to, the lows of Bar 6 and Bar 7 of the
        /// TD Buy Setup.
        /// </para>
        /// </remakrs>
        public bool PerfectSetup
        {
            get
            {
                if (Direction == Directions.Dw)
                {
                    return ((_bar[0].Low <= _bar[2].Low
                    && _bar[0].Low <= _bar[3].Low)
                    || (_bar[1].Low <= _bar[2].Low
                    && _bar[1].Low <= _bar[3].Low));
                }
                else
                {
                    return ((_bar[0].High >= _bar[2].High
                    && _bar[0].High >= _bar[3].High)
                    || (_bar[1].High >= _bar[2].High
                    && _bar[1].High >= _bar[3].High));
                }
            }
        }

        /// <summary>
        /// Check Countdown initialization conditions.
        /// </summary>
        /// <remarks>
        /// To Initiate TD Sequential Buy Countdown:
        /// <list type="bullet">
        /// <item>
        /// <description>
        ///	If Bar 9 of a TD Buy Setup also has a close less than, or
        /// equal to, the low two bars earlier, then Bar 9 of a 
        /// TD Buy Setup becomes Bar 1 of a TD Buy Countdown.
        /// </description>
        /// </item>
        /// <item>
        /// <description>
        /// If That condition is not met, then TD Buy Countdown Bar 1 
        /// is postponed until it does, and the TD Buy Countdown 
        /// continues until there are a total of 13 closes, each being 
        /// less than, or equal to, the low 2 bars earlier.
        /// </description>
        /// </item>
        /// </list>
        /// </remarks>
        private bool CheckCountdownInitConditions()
        {
            if (Direction == Directions.Dw)
            {
                return (_bar[0].Close <= _bar[2].Low);
            }
            else
            {
                return (_bar[0].Close >= _bar[2].High);
            }
        }

        /// <summary>
        /// This method handle Countdown rules.
        /// </summary>
        /// <remarks>
        /// This function check for Countdown initialization
        /// conditions. If Countdown have been initialized, than
        /// increment counter.
        /// If number of elements in CountdownBars is higher than 12, 
        /// check if the conditions of Countdown signal have been met.
        /// </remarks>
        private bool UpdateCountdownAndLookForSignal()
        {
            if (!_counterInitialized)
            {
                if (CheckCountdownInitConditions())
                {
                    _counterInitialized = true;
                    _countdownBars.Add(_bar[0]);
                }
            }
            else
            {
                // If Countdown Bar than increment Countdown
                if (_countdownBars.Count <= 12)
                {
                    if (Direction == Directions.Dw)
                    {
                        if (_bar[0].Close <= _bar[2].Low)
                        {
                            _countdownBars.Insert(0, _bar[0]);
                        }
                    }
                    else
                    {
                        if (_bar[0].Close >= _bar[2].High)
                        {
                            _countdownBars.Insert(0, _bar[0]);
                        }
                    }
                }
                else
                {
                    // Check Countdown signal
                    return (CheckCountdownSignal());
                }
            }
            return (false);
        }

        /// <summary>
        /// Method <c>CheckCountdownSignal</c> is only checked when the variable Counter is
        /// higher than 12 and return true if conditions of countdown signal are met.
        /// </summary>
        /// <remarks>
        /// To Complete a TD Sequential Buy Countdown two conditions must be met.
        /// <list type="bullet">
        /// <item>
        /// <description>
        /// The low of TD Buy Countdown Bar 13 must be less
        /// than, or equal to, the close of TD Buy Countdown Bar 8.
        /// </description>
        /// </item>
        /// <item>
        /// <description>
        /// The close of TD Buy Countdown Bar 13 must be less
        /// than, or equal to, the low 2 bars earlier.
        /// </description>
        /// </item>
        /// </list>
        /// </remarks>
        private bool CheckCountdownSignal()
        {
            if (Direction == Directions.Dw)
            {
                return (
                // check requirements for countdown signal
                _bar[0].Low <= _countdownBars[5].Close &&
                // check if it is a valid countdown bar
                _bar[0].Close <= _bar[2].Low);
            }
            else if (Direction == Directions.Up)
            {
                return (
                // check requirements for countdown signal
                _bar[0].High >= _countdownBars[5].Close &&
                // check if it is a valid countdown bar
                _bar[0].Close >= _bar[2].High);
            }
            return (false);
        }

        /// <summary>
        /// Method <c>ResetCountdown</c> clear countdown bars list and 
        /// reset variables related with countdown.
        /// </summary>
        /// <remarks>
        /// This function is called after a Countdown signal.
        /// </remarks>
        private void ResetCountdown()
        {
            _counterInitialized = false;
            _checkCountdownInitialization = false;
            _countdownBars.Clear();
        }
    }
}