Overall Statistics
Total Trades
10635
Average Win
0.03%
Average Loss
-0.06%
Compounding Annual Return
5.267%
Drawdown
5.700%
Expectancy
0.028
Net Profit
18.396%
Sharpe Ratio
1.202
Loss Rate
34%
Win Rate
66%
Profit-Loss Ratio
0.56
Alpha
0.056
Beta
-0.019
Annual Standard Deviation
0.044
Annual Variance
0.002
Information Ratio
-0.998
Tracking Error
0.128
Treynor Ratio
-2.806
Total Fees
$21294.00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuantConnect
{
    class BuyLowStrategy
    {
        // Fields
        //private int symbolsN;
        private int runsPerDay;
        private int previousDaysN;

        private Dictionary<string, bool> newDay = new Dictionary<string,bool>();
        private Dictionary<string, decimal> previousValue = new Dictionary<string, decimal>();
        private Dictionary<string, DateTime> previousValueDate = new Dictionary<string, DateTime>();

        private Dictionary<string, decimal> accumulatedRun = new Dictionary<string, decimal>();
        private Dictionary<string, decimal> valuePrevToRun = new Dictionary<string, decimal>();
        private Dictionary<string, List<decimal>> intraDayRuns = new Dictionary<string, List<decimal>>();

        private Dictionary<string, Queue<decimal>> dailyDownwardRuns = new Dictionary<string, Queue<decimal>>();
        private Dictionary<string, Queue<decimal>> dailyUpwardRuns = new Dictionary<string, Queue<decimal>>();

        private Dictionary<string, decimal> previousDaysDownwardRuns = new Dictionary<string, decimal>();
        private Dictionary<string, decimal> previousDaysUpwardRuns = new Dictionary<string, decimal>();

        private Dictionary<string, bool> isReady = new Dictionary<string, bool>();
        private Dictionary<string, bool> turnAround = new Dictionary<string, bool>();
        private Dictionary<string, int> orderSignal = new Dictionary<string, int>();

        public Dictionary<string, bool> IsReady
        {
            get { return isReady; }
        }

        public Dictionary<string, bool> TurnAround
        {
            get { return turnAround; }
        }

        public Dictionary<string, int> OrderSignal
        {
            get { return orderSignal; }
        }

        // Constructor
        public BuyLowStrategy(string[] symbols, int PreviousDaysN, int RunsPerDay)
        {
            //this.symbolsN = symbols.Length;
            this.previousDaysN = PreviousDaysN;
            this.runsPerDay = RunsPerDay;

            foreach (string symbol in symbols)
            {
                intraDayRuns.Add(symbol, new List<decimal>());
                dailyDownwardRuns.Add(symbol, new Queue<decimal>());
                dailyUpwardRuns.Add(symbol, new Queue<decimal>());

                previousValueDate.Add(symbol, new DateTime());
                valuePrevToRun.Add(symbol, new decimal());
                previousValue.Add(symbol, new decimal());

                accumulatedRun.Add(symbol, new decimal());

                isReady.Add(symbol, false);
                turnAround.Add(symbol, false);

                previousDaysDownwardRuns.Add(symbol, new decimal());
                previousDaysUpwardRuns.Add(symbol, new decimal());
                orderSignal.Add(symbol, 0);
                newDay[symbol] = true;
            }
        }

        // Add 
        public void AddSerieValue(string symbol, DateTime timeStamp, decimal serieValue)
        {
            bool sameDay;
            DateTime actualValueDate = timeStamp.Date;

            if (newDay[symbol])
            {
                // Day initialization
                previousValueDate[symbol] = actualValueDate;
                valuePrevToRun[symbol] = serieValue;
                previousValue[symbol] = serieValue;

                accumulatedRun[symbol] = 0;

                //isReady[symbol] = false;
                turnAround[symbol] = false;
                newDay[symbol] = false;
            }

            sameDay = actualValueDate == previousValueDate[symbol].Date;

            if (sameDay)
            {
                DayTripper(timeStamp, symbol, serieValue); // I quickly run out of ideas for good method's names.
            }
            else
            {
                DayEnd(symbol);
                newDay[symbol] = true;

            }
        }


        private void DayTripper(DateTime timeStamp, string symbol, decimal serieValue)
        {
            decimal valueDiff;
            decimal brokenRun;

            decimal previousAccum = accumulatedRun[symbol];

            valueDiff = serieValue - previousValue[symbol];

            if (valueDiff * previousAccum >= 0)
            {
                accumulatedRun[symbol] = previousAccum + valueDiff;
                turnAround[symbol] = false;
            }
            else
            {
                accumulatedRun[symbol] = valueDiff;
                turnAround[symbol] = true;

                brokenRun = previousAccum / valuePrevToRun[symbol];
                valuePrevToRun[symbol] = previousValue[symbol];

                intraDayRuns[symbol].Add(brokenRun);

                CheckOrders(symbol, brokenRun);
            }
            previousValue[symbol] = serieValue;
            previousValueDate[symbol] = timeStamp;
        }


        private void DayEnd(string symbol)
        {
            decimal dayMeanDownwardRun;
            decimal dayMeanUpwardRun;

            dayMeanDownwardRun = (from run in intraDayRuns[symbol]
                                  where run < 0
                                  orderby run ascending
                                  select run).Take(runsPerDay).DefaultIfEmpty().Average();

            dayMeanUpwardRun = (from run in intraDayRuns[symbol]
                                where run > 0
                                orderby run descending
                                select run).Take(runsPerDay).DefaultIfEmpty().Average();

            dailyDownwardRuns[symbol].Enqueue(dayMeanDownwardRun);
            dailyUpwardRuns[symbol].Enqueue(dayMeanUpwardRun);

            intraDayRuns[symbol].Clear();

            if (dailyDownwardRuns[symbol].Count == previousDaysN) isReady[symbol] = true;

            if (dailyDownwardRuns[symbol].Count > previousDaysN)
            {
                dailyDownwardRuns[symbol].Dequeue();
                dailyUpwardRuns[symbol].Dequeue();
            }
            previousDaysDownwardRuns[symbol] = dailyDownwardRuns[symbol].DefaultIfEmpty().Average();
            previousDaysUpwardRuns[symbol] = dailyUpwardRuns[symbol].DefaultIfEmpty().Average();
        }


        private void CheckOrders(string symbol, decimal brokenRun)
        {
            if (this.isReady[symbol])
            {
                orderSignal[symbol] = 0; // Do nothing

                if (brokenRun < 0 && brokenRun < previousDaysDownwardRuns[symbol])
                {
                    // Long order
                    orderSignal[symbol] = -1;
                }
                else if (brokenRun > 0 && brokenRun > previousDaysUpwardRuns[symbol])
                {
                    // Short order
                    orderSignal[symbol] = 1;
                }
            }
        }
    }
}
using System;
using System.Collections.Generic;
using QuantConnect.Indicators;
using QuantConnect.Data.Market;

namespace QuantConnect
{
    /// <summary>
    /// Basic template algorithm simply initializes the date range and cash
    /// </summary>
    public class IntradayBuyLow : QCAlgorithm
    {
        static string[] symbols = { "AAPL", "GOOGL", "IBM", "MSFT"};
        BuyLowStrategy Strategy = new BuyLowStrategy(symbols, 5, 4);
        Dictionary<string, ExponentialMovingAverage> ema = new Dictionary<string, ExponentialMovingAverage>();
        
        /// <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()
        {
            SetStartDate(2012, 1, 1);  //Set Start Date
            SetEndDate(2015, 4, 15);    //Set End Date
            SetCash(100000);             //Set Strategy Cash
            // Find more symbols here: http://quantconnect.com/data


            foreach (string symbol in symbols) 
            {
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
                 //tradier does 1 dollar equity trades
                Securities[symbol].TransactionModel = new ConstantFeeTransactionModel(1.00m);
                ema.Add(symbol, EMA(symbol, 5, Resolution.Minute));
            }
            
            
        }

        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            foreach (string symbol in symbols)
            {
                // write more comments! you'll thank yourself later when
                // you forget why you did something :)
                if (!ema[symbol].IsReady) return;
                
                Strategy.AddSerieValue(symbol, Time, ema[symbol]);
                    
                if (Strategy.IsReady[symbol])
                {
                    if (Portfolio[symbol].HoldStock)
                    {
                        if (Strategy.TurnAround[symbol])
                        {
                            Liquidate(symbol);
                        }
                    }
                    else
                    {
                        if (Strategy.OrderSignal[symbol] != 0)
                        {
                            EntryAndSetStopLoss(symbol, Strategy.OrderSignal[symbol]);
                        }
                    }
                }
            }
        }

        
        private void EntryAndSetStopLoss(string symbol, int signal)
        {
            decimal stopLossPrice;
            int orderSize = SetOrderSize(signal);
            
            SetHoldings(symbol, 0.25*signal);
            
            //MarketOrder(symbol, orderSize);
            //Debug((signal > 0) ? "Buy " : "Sell " + orderSize.ToString() + " "
            //    + symbol + " shares @ $" + Portfolio[symbol].HoldingsCost);

            //stopLossPrice = Portfolio[symbol].HoldingsCost * SetStopLossCoef();

            //StopMarketOrder(symbol, -orderSize, stopLossPrice);
            //Debug("Stop loss order @ $" + stopLossPrice.ToString());
        }

        
        private int SetOrderSize(int signal)
        {
            // TO DO: Sizing model
            return 100 * signal;
        }

        private decimal SetStopLossCoef()
        {
            return 0.95m;
        }
    }
}