Overall Statistics
Total Trades
30
Average Win
5.82%
Average Loss
-8.03%
Compounding Annual Return
-31.185%
Drawdown
42.200%
Expectancy
-0.195
Net Profit
-24.455%
Sharpe Ratio
-0.646
Loss Rate
53%
Win Rate
47%
Profit-Loss Ratio
0.72
Alpha
0.03
Beta
-0.076
Annual Standard Deviation
0.319
Annual Variance
0.102
Information Ratio
-2.239
Tracking Error
1.48
Treynor Ratio
2.712
Total Fees
$5442.08
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 const bool UseTrailingStop = false;

        private const Timeframe TimeFrame = Timeframe.H4;

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

        private const decimal InitialBalance = 100000m;

        private const int ATRPeriod = 100;

        private Symbol _tradeSymbol;

        // Internal Variables
        private RollingWindow<TradeBar> _bars;
        private AverageTrueRange _atr;

        private decimal _longStoploss;
        private decimal _longTakeprofit;
        private decimal _shortStoploss;
        private decimal _shortTakeprofit;

        private TradeBuilder _tradeBuilder;

        private DeMarkSetup _longSetup, _shortSetup;

        /// <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(2017, 1, 1);
            SetEndDate(2017, 10, 1);
            SetCash(InitialBalance);
            // Brokerage Model
            SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin);
            // Symbol and Market Parameters
            _tradeSymbol = QuantConnect.Symbol.Create("LTCUSD", SecurityType.Crypto, Market.Bitfinex);
            Security security;

            switch (TimeFrame)
            {
                case Timeframe.H1:

                    security = AddCrypto(_tradeSymbol, Resolution.Hour);
                    BrokerageModel.GetFeeModel(security);
                    // Consolidator
                    TradeBarConsolidator consolidator = new TradeBarConsolidator(1);
                    consolidator.DataConsolidated += BarHandler;
                    SubscriptionManager.AddConsolidator(_tradeSymbol, consolidator);
                    break;

                case (Timeframe.H4):

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

                case (Timeframe.D1):

                    security = AddCrypto(_tradeSymbol, Resolution.Daily);
                    BrokerageModel.GetFeeModel(security);
                    // Consolidator
                    TradeBarConsolidator dailyconsolidator = new TradeBarConsolidator(1);
                    dailyconsolidator.DataConsolidated += BarHandler;
                    SubscriptionManager.AddConsolidator(_tradeSymbol, dailyconsolidator);
                    break;

                default:

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

            _atr = new AverageTrueRange(_tradeSymbol, ATRPeriod, MovingAverageType.Simple);

            _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}%");
        }

        /// <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);
            _atr.Update(consolidated);
            PlotATRValue(_atr.Current.Value);

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

            if (UseTrailingStop)
                CheckTrailingStop();

            if (_bars.Count >= 15)
            {
                switch (_longSetup.StepForward(_bars))
                {
                    // Perfect Setup
                    case SignalStatus.Perfect:
                        PlotLongPerfectSignal();
                        break;
                    // Countdown
                    case SignalStatus.Countdown:
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Up);
                        }
                        PlotLongCountdownSignal();
                        break;
                    default:
                        break;
                }
                switch (_shortSetup.StepForward(_bars))
                {
                    // Perfect Setup
                    case SignalStatus.Perfect:
                        PlotShortPerfectSignal();
                        break;
                    // Countdown
                    case SignalStatus.Countdown:
                        if (!Portfolio[_tradeSymbol].Invested)
                        {
                            OpenPosition(Directions.Dw);
                        }
                        PlotShortCountdownSignal();
                        break;
                    default:
                        break;
                }
            }
        }

        /// <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)
            {
                if (Portfolio[_tradeSymbol].IsLong)
                {
                    decimal lowest = GetLowestLow();
                    if (_longStoploss < lowest
                    && lowest < Securities[_tradeSymbol].Price)
                    {
                        ModifyStopLoss(lowest, Directions.Up);
                    }
                }
                else if (Portfolio[_tradeSymbol].IsShort)
                {
                    decimal highest = GetHighestHigh();
                    if (_shortStoploss > highest
                    && highest > Securities[_tradeSymbol].Price)
                    {
                        ModifyStopLoss(highest, 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);
            QuantConnect.Chart chartAtr = new Chart("ChartATR", ChartType.Stacked);
            chartAtr.AddSeries(new Series("ATR", SeriesType.Line));
            AddChart(chartAtr);
        }

        /// <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 + (_atr.Current.Value * TakeProfit);
            }
            else
            {
                _shortTakeprofit = value - (_atr.Current.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 - (_atr.Current.Value * StopLoss);
            }
            else
            {
                _shortStoploss = value + (_atr.Current.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);
            }
            else
            {
                _shortStoploss = value;
                PlotStopLossChanged(_shortStoploss);
            }
        }

        /// <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 ATR value.
        /// </summary>
        /// <param name="value">ATR current value</param>
        /// <remarks>
        /// ATR is used for stops calculations.
        /// </remarks>
        private void PlotATRValue(decimal value)
        {
            Plot("ChartATR", "ATR", value);
        }

        /// <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 }

    public enum SignalStatus { None = 0, Trend = 1, Perfect = 2, Countdown = 3 }

    /// <summary>
    /// DeMark indicator algorithm.
    /// All methods follows DeMark setups rules.
    /// </summary>
    public class DeMarkSetup
    {
        // Long or Short
        private Directions Direction;
        // Every iteration returns a SignalStatus, which can be None
        private SignalStatus _status = SignalStatus.None;
        // 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 SignalStatus StepForward(RollingWindow<TradeBar> bar)
        {
            _bar = bar;
            _status = SignalStatus.None;

            if (_lookAgainForPerfection)
            {
                _lookAgainForPerfection = false;
                if (PerfectSetup)
                {
                    _status = SignalStatus.Perfect;
                }
            }

            if (!_checkCountdownInitialization)
            {
                if (TDSetup)
                {
                    _checkCountdownInitialization = true;
                    if (!PerfectSetup)
                    {
                        _lookAgainForPerfection = true;
                        _status = SignalStatus.Trend;
                    }
                    else
                    {
                        _status = SignalStatus.Perfect;
                    }
                }
            }
            else
            {
                if (UpdateCountdownAndLookForSignal())
                {
                    _status = SignalStatus.Countdown;
                    ResetCountdown();
                }
            }
            return (_status);
        }

        /// <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.Up)
                {
                    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.Up)
                {
                    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>
        /// </list>
        /// <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.Up)
            {
                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.Up)
                    {
                        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.Up)
            {
                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.Dw)
            {
                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();
        }
    }
}