Overall Statistics |
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return -8.312% Drawdown 0.200% Expectancy 0 Net Profit 0% Sharpe Ratio -4.315 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.012 Beta 0.096 Annual Standard Deviation 0.012 Annual Variance 0 Information Ratio 3.807 Tracking Error 0.093 Treynor Ratio -0.523 Total Fees $1.00 |
namespace QuantConnect { /// <summary> /// Represents the LogReturn indicator (LOGR) /// - log returns are useful for identifying price convergence/divergence in a given period /// - logr = log (current price / last price in period) /// </summary> public class LogReturn : WindowIndicator<IndicatorDataPoint> { /// <summary> /// Initializes a new instance of the LogReturn class with the specified name and period /// </summary> /// <param name="name">The name of this indicator</param> /// <param name="period">The period of the LOGR</param> public LogReturn(string name, int period) : base(name, period) { } /// <summary> /// Initializes a new instance of the LogReturn class with the default name and period /// </summary> /// <param name="period">The period of the SMA</param> public LogReturn(int period) : base("LOGR" + period, period) { } /// <summary> /// Computes the next value for this indicator from the given state. /// - logr = log (current price / last price in period) /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input value to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input) { decimal valuef = input; decimal value0 = !window.IsReady ? window[window.Count - 1] : window.MostRecentlyRemoved; decimal logr = (decimal)Math.Log((double)(valuef / value0)); return logr; } } }
using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Market; using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data.UniverseSelection; using QuantConnect.Orders; using QuantConnect.Indicators; using QuantConnect.Securities; using QuantConnect.Brokerages; using System.Globalization; using System.Text; using System.Threading.Tasks; using System.Collections.Concurrent; namespace QuantConnect { public class BasicTemplateAlgorithm : QCAlgorithm { //string symbol = "AAPL"; //private LogReturn logr14; //private LogReturn logr30; private LogReturn lastLogr; private DateTime previous; Security _security; //RegisterIndicator(symbol, logr, null); SecurityChanges _changes = SecurityChanges.None; private readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>(); private class SelectionData { public LogReturn logr14; public LogReturn logr30; public SelectionData() { logr14 = new LogReturn(1); logr30 = new LogReturn(2); } public decimal ScaledDelta { get { return (logr14); } } // updates the EMA50 and EMA100 indicators, returning true when they're both ready public bool Update(DateTime time, decimal value) { return logr14.Update(time, value) && logr30.Update(time, value); } } //Initialize the data and resolution you require for your strategy: public override void Initialize() { //Start and End Date range for the backtest: UniverseSettings.Resolution = Resolution.Daily; SetStartDate(2016, 2, 23); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(5000); AddUniverse(coarse => { return (from stock in coarse // grab th SelectionData instance for this let avg = _averages.GetOrAdd(stock.Symbol, sym => new SelectionData()) // Update returns true when the indicators are ready, so don't accept until they are //where avg.Update(stock.EndTime, stock.Price) // only pick symbols who have their 50 day ema over their 100 day ema where stock.Price < 5 && stock.Price > 2 //where stock.Price > stock.Value // prefer symbols with a larger delta by percentage between the two averages // prefer symbols with a larger delta by percentage between the two averages //orderby avg.ScaledDelta // we only need to return the symbol and return 'Count' symbols // we only need to return the symbol and return 'Count' symbols select stock.Symbol).Take(10); }); } //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol. // "TradeBars" object holds many "TradeBar" objects: it is a dictionary indexed by the symbol: // // e.g. data["MSFT"] data["GOOG"] public void OnData(TradeBars data) { foreach (var stock in _changes.AddedSecurities) { _security = stock; //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Equity, _security.Symbol, Resolution.Daily); //logr14 = new LogReturn(1); //logr30 = new LogReturn(2); //lastLogr = logr14; } if (!Portfolio.HoldStock) { int quantity = (int)Math.Floor(Portfolio.Cash / data[_security.Symbol].Close); Order(_security.Symbol, 100); } // update Indicators /*decimal price = data[_security.Symbol].Close; IndicatorDataPoint datum = new IndicatorDataPoint(data[_security.Symbol].Time, price); Log("datum" + datum); logr14.Update(datum); logr30.Update(datum); Log("log14" + logr14); Log("log30" + logr30); // wait for the indicators to fully initialize if (!logr30.IsReady) return; // stock is moving in an upwards trend if (logr14.Current.Value > logr30.Current.Value) { if (!Portfolio.HoldStock) { int quantity = (int)Math.Floor(Portfolio.Cash / data[symbol].Close); Order(symbol, quantity); } } // stock is moving in a downwards trend else if (logr30.Current.Value > logr14.Current.Value) { Liquidate(symbol); } Plot(symbol, logr14); Plot(symbol, logr30);*/ } public override void OnSecuritiesChanged(SecurityChanges changes) { _changes = changes; } } }