// TODO: check volatilitymodel https://github.com/QuantConnect/Lean/blob/master/Common/Securities/RelativeStandardDeviationVolatilityModel.cs public override void Initialize() { SetStartDate(2016, 1, 1); SetEndDate(2016, 4, 1); SetCash(3000); SetBrokerageMessageHandler(new CustomBrokerageMessageHandler(this)); var allInputs = new List <double[]>(); var allOutputs = new List <int>(); var allWeights = new List <double>(); foreach (var symbol in Symbols) { AddForex(symbol, _dataResolution, Market.Oanda, false, 1m); Securities[symbol].TransactionModel = new OandaTransactionModel(); //Securities[symbol].SlippageModel = new ConstantSlippageModel(0m); SetBrokerageModel(BrokerageName.OandaBrokerage); /************ TRAINING ************/ var trainingResolution = Resolution.Minute; /*var slowT = HMA(symbol, 28, trainingResolution, Field.Close); * var slowSlopeT = new InstantTrend(symbol, 5).Of(slowT); * var returnT = LOGR(symbol, 3, trainingResolution, Field.Close); * var returnSlopeT = LSMA(symbol, 5, trainingResolution).Of(returnT);*/ var consolidatorT = new QuoteBarConsolidator(TimeSpan.FromMinutes(15)); var stochT = new Stochastic(symbol, 14, 3, 3); var stochTMA = new HullMovingAverage(symbol, 3).Of(stochT); var emaT = new ExponentialMovingAverage(symbol, 40); RegisterIndicator(symbol, stochT, consolidatorT); RegisterIndicator(symbol, emaT, consolidatorT); SubscriptionManager.AddConsolidator(symbol, consolidatorT); var historyT = History <QuoteBar>(symbol, TimeSpan.FromDays(500), trainingResolution); var quoteBars = new List <QuoteBar>(); var stochs = new List <double>(); var rollingStochs = new RollingWindow <double>(1000); var stochsMA = new List <double>(); var emas = new List <double>(); var stochCount = new List <double>(); var stochAverage = new List <double>(); //consolidatorT.DataConsolidated += (sender, args) => quoteBars.Add(args); stochTMA.Updated += (sender, args) => { if (!stochTMA.IsReady || !emaT.IsReady) { return; } quoteBars.Add((QuoteBar)consolidatorT.Consolidated); stochs.Add((double)stochT.Current.Value); rollingStochs.Add((double)args.Value); stochsMA.Add((double)args.Value); emas.Add((double)emaT.Current.Value); var filtered = rollingStochs.TakeWhile((s) => args.Value > 50 ? s > 50 : args.Value < 50 ? s < 50 : false); stochCount.Add(filtered.Count()); try { stochAverage.Add(filtered.Average()); } catch (Exception ex) { stochAverage.Add(0); } }; foreach (var bar in historyT) { consolidatorT.Update(bar); } Console.WriteLine("{0} {1} {2} {3} {4}", quoteBars.Count, stochs.Count, stochCount.Count, stochAverage.Count, emas.Count); var inputs = new List <double[]>(); var outputs = new List <int>(); var weights = new List <double>(); for (var i = 1; i < quoteBars.Count; i++) { var longTarget = quoteBars[i].Close + (30m / 10000m); var longStop = quoteBars[i].Close - (10m / 10000m); var shortTarget = quoteBars[i].Close - (30m / 10000m); var shortStop = quoteBars[i].Close + (10m / 10000m); var longSetup = stochs[i] >= 35 && stochsMA[i] > stochsMA[i - 1] && (double)quoteBars[i].Close > emas[i]; var shortSetup = stochs[i] <= 65 && stochs[i] > 0 && stochsMA[i] < stochsMA[i - 1] && (double)quoteBars[i].Close < emas[i]; if (!longSetup && !shortSetup) { continue; } for (var j = i + 1; j < quoteBars.Count; j++) { var current = quoteBars[j]; if (current.High >= longTarget && current.Low > longStop && longSetup) { inputs.Add(new double[] { stochAverage[i], stochCount[i], (double)quoteBars[i].Close / emas[i] }); outputs.Add(1); var profit = current.High - quoteBars[i].Close; /*for (var k = j + 1; k < quoteBars.Count; k++) * { * * }*/ weights.Add((double)(1m - (50m / 10000m) / profit)); //i = j; break; } else if (current.Low <= shortTarget && current.High < shortStop && shortSetup) { inputs.Add(new double[] { stochAverage[i], stochCount[i], (double)quoteBars[i].Close / emas[i] }); outputs.Add(0); var profit = quoteBars[i].Close - current.Low; /*for (var k = j + 1; k < quoteBars.Count; k++) * { * * }*/ weights.Add((double)(1m - (50m / 10000m) / profit)); //i = j; break; } else if ((current.Low <= longStop && longSetup) || (current.High >= shortStop && shortSetup)) { //inputs.Add(new double[] { stochAverage[i] / stochs[i], stochCount[i], stochAverage[i] }); //outputs.Add(2); //i = j; break; } /*else if (j - i > 4 * 8) * { * inputs.Add(new double[] { stochs[i], stochCount[i], stochAverage[i] }); * outputs.Add(0); * //i = j; * break; * }*/ } } allInputs.AddRange(inputs); allOutputs.AddRange(outputs); allWeights.AddRange(weights); for (var i = 0; i < inputs.Count; i++) { //Console.WriteLine("Input: " + inputs[i][0] + " " + inputs[i][1] + " " + inputs[i][2] + " Output: " + outputs[i]); } var none = outputs.Where((o) => o == 2).Count(); var sell = outputs.Where((o) => o == 0).Count(); var buy = outputs.Where((o) => o == 1).Count(); Console.WriteLine("Total: {0} None: {1} Short: {2} Long: {3}", outputs.Count, none, sell, buy); /************ HMA ************/ /*var slow = HMA(symbol, 28, trainingResolution, Field.Close); * var slowSlope = new InstantTrend(symbol, 5).Of(slow); * var logReturns = LOGR(symbol, 3, trainingResolution, Field.Close); * var returnSlope = LSMA(symbol, 5, trainingResolution).Of(logReturns);*/ var consolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(15)); var stoch = new Stochastic(symbol, 14, 3, 3); var stochMA = new HullMovingAverage(symbol, 2).Of(stoch); var ema = new ExponentialMovingAverage(symbol, 40); var rolling = new RollingWindow <double>(1000); RegisterIndicator(symbol, stoch, consolidator); RegisterIndicator(symbol, ema, consolidator); SubscriptionManager.AddConsolidator(symbol, consolidator); _stoch[symbol] = stoch; _ema[symbol] = ema; stochMA.Updated += (sender, args) => { rolling.Add((double)args.Value); if (Securities[symbol].Price > 0) { //Plot("Plotter", "Price", Securities["EURUSD"].Price); Plot("Indicator", "STO", rolling[0]); } }; var std = ATR(symbol, 100, MovingAverageType.DoubleExponential, _dataResolution); var history = History <QuoteBar>(symbol, TimeSpan.FromDays(20), trainingResolution); foreach (var bar in history) { //slow.Update(bar.EndTime, bar.Close); //logReturns.Update(bar.EndTime, bar.Close); std.Update(bar); consolidator.Update(bar); } var signal = new SVMSignal(consolidator, stoch, stochMA, rolling, ema, Portfolio[symbol], this); signal.TrainSVM(inputs, outputs, weights); //signal.TrainNN(inputs, outputs, weights); Securities[symbol].VolatilityModel = new AverageTrueRangeVolatilityModel(std); _tradingAssets.Add(symbol, new TradingAsset(Securities[symbol], new OneShotTrigger(signal), new ProfitTargetSignalExit(null, _targetProfitLoss), _maximumTradeRisk, _maximumTradeSize, this )); } foreach (var symbol in Symbols) { //_tradingAssets[symbol].Retrain(allInputs, allOutputs, allWeights); } //AddData<DailyFx>("DFX", Resolution.Second, TimeZones.Utc); Schedule.On(DateRules.Every(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday), TimeRules.At(7, 0, TimeZones.London), () => { var tradeableDay = TradingCalendar.GetTradingDay().BusinessDay; if (tradeableDay) { foreach (var s in Symbols) { _tradingAssets[s].IsTradable = true; } } }); Schedule.On(DateRules.Every(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday), TimeRules.At(18, 0, TimeZones.London), () => { foreach (var s in Symbols) { _tradingAssets[s].IsTradable = false; } }); Schedule.On(DateRules.Every(DayOfWeek.Friday), TimeRules.BeforeMarketClose(Symbols.First(), 60), () => { foreach (var s in Symbols) { _tradingAssets[s].Liquidate(); } }); Chart plotter = new Chart("Plotter"); plotter.AddSeries(new Series("Price", SeriesType.Line, 0)); plotter.AddSeries(new Series("EMA", SeriesType.Line, 0)); plotter.AddSeries(new Series("Buy", SeriesType.Scatter, "", Color.Green, ScatterMarkerSymbol.Triangle)); plotter.AddSeries(new Series("Sell", SeriesType.Scatter, "", Color.Red, ScatterMarkerSymbol.TriangleDown)); plotter.AddSeries(new Series("Stopped", SeriesType.Scatter, "", Color.Yellow, ScatterMarkerSymbol.Diamond)); plotter.AddSeries(new Series("Prediction", SeriesType.Bar, 1)); plotter.AddSeries(new Series("Probability", SeriesType.Bar, 2)); AddChart(plotter); Chart indicator = new Chart("Indicator"); indicator.AddSeries(new Series("STO", SeriesType.Line, 0)); AddChart(indicator); Chart prediction = new Chart("Prediction"); prediction.AddSeries(new Series("Pred", SeriesType.Bar, 0)); AddChart(prediction); Chart probability = new Chart("Probability"); probability.AddSeries(new Series("Prob", SeriesType.Bar, 0)); AddChart(probability); }
public SVMSignal(QuoteBarConsolidator consolidator, Stochastic stoch, HullMovingAverage stochMA, RollingWindow <double> rolling, ExponentialMovingAverage ema, SecurityHolding securityHolding, SVMStrategy qcAlgorithm) { _consolidator = consolidator; _stoch = stoch; _StochMA = stochMA; _rolling = rolling; _ema = ema; _securityHolding = securityHolding; _qcAlgorithm = qcAlgorithm; stochMA.Updated += (sender, args) => { try { var filtered = _rolling.TakeWhile((s) => args.Value > 50 ? s > 50 : args.Value < 50 ? s < 50 : false); var currentQuote = (QuoteBar)_consolidator.Consolidated; //Console.WriteLine("{0}, {1}, {2}", filtered.Count(), _rolling.Count(), _stoch.Current.Value); var inputs = new double[] { filtered.Average(), filtered.Count(), (double)(currentQuote.Close / _ema.Current.Value) }; _inputs.Add(inputs); inputs = Accord.Statistics.Tools.ZScores(_inputs.ToArray()).Last(); _inputs.RemoveAt(_inputs.Count - 1); if (_pcaTransform) { inputs = _pca.Transform(inputs); } var prediction = _svm.Decide(inputs); var probability = _svm.Probability(inputs); var logLikelihood = _svm.LogLikelihood(inputs); _qcAlgorithm.PlotSignal((QuoteBar)_consolidator.Consolidated, prediction == 0 ? -1 : prediction, logLikelihood); /*var dbnPredictions = _dbn.Compute(inputs); * var shortPrediction = dbnPredictions.First(); * var longPrediction = dbnPredictions.Last();*/ if (_securityHolding.Invested && Signal == SignalType.Long && prediction == 0) { //Console.WriteLine("Long Exit Time: {0} Prediction: {1} Probability: {2}", args.EndTime, prediction, probability); } else if (_securityHolding.Invested && Signal == SignalType.Short && prediction == 1) { //Console.WriteLine("Short Exit Time: {0} Prediction: {1} Probability: {2}", args.EndTime, prediction, probability); } if (prediction != 2) { //Console.WriteLine("Time: {0} Prediction: {1} Probability: {2}, Log Likelihood: {3} Score: {4}", args.EndTime, prediction, probability, logLikelihood); } // EURUSD 0.9999 var probabilityFilter = logLikelihood >= 9;//probability >= 0.999999;// && _previousPredictions.IsReady && _previousPredictions.All((p) => p == prediction); var aboveEma = currentQuote.Close > _ema.Current.Value; var belowEma = currentQuote.Close < _ema.Current.Value; var longExit = Signal == SignalType.Long && belowEma; //prediction == 0; var shortExit = Signal == SignalType.Short && aboveEma; //prediction == 1; if (!_securityHolding.Invested && probabilityFilter && prediction == 1 && _rolling[0] > rolling[1] && aboveEma) { Signal = Signal != SignalType.PendingLong ? SignalType.PendingLong : SignalType.Long; if (_debug) { Console.WriteLine("Long Signal: {0} Probability: {1} Log Likelihood: {2}", Signal, probability, logLikelihood); Console.WriteLine("Long STO: {0} STO MA: {1} Count: {2}", _stoch.Current.Value, args.Value, filtered.Count()); Console.WriteLine("Long Time: {0} Price: {1}", _consolidator.Consolidated.Time, _consolidator.Consolidated.Value); } } else if (!_securityHolding.Invested && probabilityFilter && prediction == 0 && _rolling[0] < rolling[1] && belowEma) { Signal = Signal != SignalType.PendingShort ? SignalType.PendingShort : SignalType.Short; if (_debug) { Console.WriteLine("Short Signal: {0} Probability: {1} Log Likelihood: {2}", Signal, probability, logLikelihood); Console.WriteLine("Short STO: {0} STO MA: {1} Count: {2}", _stoch.Current.Value, args.Value, filtered.Count()); Console.WriteLine("Short Time: {0} Price: {1}", _consolidator.Consolidated.Time, _consolidator.Consolidated.Value); } } else if ((_securityHolding.Invested && longExit) || (_securityHolding.Invested && shortExit)) { if (_debug) { Console.WriteLine("Exit Signal: {0} Probability: {1} Log Likelihood: {2}", Signal, probability, logLikelihood); Console.WriteLine("Exit STO: {0} STO MA: {1} Count: {2}", _stoch.Current.Value, args.Value, filtered.Count()); Console.WriteLine("Exit Time: {0} Price: {1}", _consolidator.Consolidated.Time, _consolidator.Consolidated.Value); } Signal = SignalType.Exit; } else if (!_securityHolding.Invested && (Signal == SignalType.PendingLong || Signal == SignalType.PendingShort)) { Signal = SignalType.NoSignal; } else { //Signal = SignalType.NoSignal; } } catch (Exception ex) { Console.WriteLine(ex.Message); Signal = SignalType.NoSignal; } }; }