Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Algorithm.Framework.Selection;
namespace QuantConnect.Algorithm.CSharp
{
    public class SMAProblemFrameWork : QCAlgorithmFramework
    {
        public override void Initialize()
        {
            UniverseSettings.Resolution = Resolution.Daily;
            SetStartDate(2012, 04, 01);
            SetEndDate(2012, 06, 01);
            SetCash(2500);

            SetUniverseSelection(new ManualUniverseSelectionModel(QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA)));

            SetAlpha(new SMAProblemAlphaModel());
            SetPortfolioConstruction(new NullPortfolioConstructionModel());
            SetExecution(new ImmediateExecutionModel());
            SetRiskManagement(new NullRiskManagementModel());
        }

        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            if (orderEvent.Status.IsFill())
            {
                Debug($"Purchased: {orderEvent.Symbol}");
            }
        }
    }
}                        
// namespace QuantConnect {

    //
    //	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
    //	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
    //

    //public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
    //{
    //  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
    //}

    //public class Indicator 
    //{
    //  ...or you can define whole new classes independent of the QuantConnect Context
    //}
    
   
namespace QuantConnect.Algorithm.Framework.Alphas
{

    public class SMAProblemAlphaModel : AlphaModel
    {
        private readonly Dictionary<Symbol, SymbolData> _symbolDataBySymbol;

        private readonly int _period;
        private readonly Resolution _resolution;
        private readonly TimeSpan _consolidatedBarPeriod;

      
        public SMAProblemAlphaModel(
            int period = 4,
            Resolution resolution = Resolution.Daily
            )
        {
            _period = period;
            _resolution = resolution;
            _consolidatedBarPeriod = resolution.ToTimeSpan();
            _symbolDataBySymbol = new Dictionary<Symbol, SymbolData>();
            Name = $"{nameof(SMAProblemAlphaModel)}({_period},{_resolution})";
        }

        public override IEnumerable<Insight> Update(QCAlgorithmFramework algorithm, Slice data)
        {
            var insights = new List<Insight>();
            Console.WriteLine("insights = new List<Insight>();");
            Console.WriteLine("Slice data timestamp: " + string.Format("{0})", data.Time));
            foreach (var symbolData in _symbolDataBySymbol)
            {
                if (symbolData.Value.Security.Price == 0)
                { Console.WriteLine("symbolData.Value.Security.Price == 0"); continue; }

                if (!(symbolData.Value.RW_SMA.IsReady))
                { Console.WriteLine("RW of SMA not ready"); continue; }

                // print the RW of SMA time and value
                var rw_SMA = symbolData.Value.RW_SMA;
                Console.WriteLine("RW_SMA[0] " + string.Format("{0})", rw_SMA[0]));
                Console.WriteLine("RW_SMA[1] " + string.Format("{0})", rw_SMA[1]));



                // code below is redundant
                var symbol = symbolData.Key;
                var SMA = symbolData.Value.SMA;
                var previousState = symbolData.Value.State;
                var state = GetState(SMA, previousState);

                if (state != previousState && SMA.IsReady)
                {
                    var insightPeriod = _resolution.ToTimeSpan().Multiply(_period);

                    switch (state)
                    {
                        case State.TrippedLow:
                            insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Up));
                            break;

                        case State.TrippedHigh:
                            insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Down));
                            break;
                    }
                }

                symbolData.Value.State = state;
            }

            return insights;
        }


        public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
        {
            // initialize data for added securities
            var addedSymbols = new List<Symbol>();
            foreach (var added in changes.AddedSecurities)
            {
                SymbolData symbolData;
                if (!_symbolDataBySymbol.TryGetValue(added.Symbol, out symbolData))
                {
                    var constant1000 = new ConstantIndicator<IBaseData>("Constant1000", 1000);
                    var rw_SMA = new RollingWindow<IndicatorDataPoint>(6);

                    var consolidator = algorithm.ResolveConsolidator(added.Symbol, _consolidatedBarPeriod);

                    // I could do algorithm.SMA() here, but this mimics my implementation of the indicators
                    var sma = new SimpleMovingAverage("SMAProblemAlphaModel", _period).Of(constant1000);

                    algorithm.RegisterIndicator(added.Symbol, constant1000, consolidator);
                    algorithm.RegisterIndicator(added.Symbol, sma, consolidator);

                    sma.Updated += (sender, updated) => rw_SMA.Add(updated);


                    _symbolDataBySymbol[added.Symbol] = new SymbolData
                    {
                        Security = added,
                        Consolidator = consolidator,
                        SMA = sma,
                        RW_SMA = rw_SMA,

                    };
                }
            }

            // clean up data for removed securities
            if (changes.RemovedSecurities.Count > 0)
            {
                var removed = changes.RemovedSecurities.ToHashSet(x => x.Symbol);
                foreach (var subscription in algorithm.SubscriptionManager.Subscriptions)
                {
                    if (removed.Contains(subscription.Symbol))
                    {
                        _symbolDataBySymbol.Remove(subscription.Symbol);
                        subscription.Consolidators.Clear();
                    }
                }
            }


            if (addedSymbols.Count > 0)
            {
                // warmup our indicators by pushing history through the consolidators
                algorithm.History(addedSymbols, 6, _resolution)
                    .PushThrough(data =>
                    {
                        SymbolData symbolData;
                        if (_symbolDataBySymbol.TryGetValue(data.Symbol, out symbolData))
                        {
                            Console.WriteLine(string.Format("Adding History / {0}_({1} {2} {3} {4})", addedSymbols[0].Value, data.EndTime, _consolidatedBarPeriod, _resolution, data.Value));
                            symbolData.SMA.Update(data.EndTime, 1000);
                        }
                    });
            }
        }


        private State GetState(IndicatorBase<IndicatorDataPoint> sma, State previous)
        {
            if (sma > 70m)
            {
                return State.TrippedHigh;
            }

            if (sma < 30m)
            {
                return State.TrippedLow;
            }

            if (previous == State.TrippedLow)
            {
                if (sma > 35m)
                {
                    return State.Middle;
                }
            }

            if (previous == State.TrippedHigh)
            {
                if (sma < 65m)
                {
                    return State.Middle;
                }
            }

            return previous;
        }

        private class SymbolData
        {
            public Symbol Symbol => Security.Symbol;
            public Security Security { get; set; }
            public State State { get; set; }
            public IndicatorBase<IndicatorDataPoint> SMA { get; set; }
            public IDataConsolidator Consolidator { get; set; }
            public RollingWindow<IndicatorDataPoint> RW_SMA { get; set; }
        }


        private enum State
        {
            TrippedLow,
            Middle,
            TrippedHigh
        }
    }
}

//}