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