public static TrendEvaluation GetTrendEvaluation(TrendDirection trendDirection, TrendInterpretation trendInterpretation) { if (trendInterpretation == TrendInterpretation.Standard) switch (trendDirection) { case TrendDirection.Decreasing: return TrendEvaluation.DownBad; case TrendDirection.Increasing: return TrendEvaluation.UpGood; case TrendDirection.None: return TrendEvaluation.None; case TrendDirection.Unchanged: return TrendEvaluation.NoChangeNoOpinion; } if (trendInterpretation == TrendInterpretation.Inverse) switch (trendDirection) { case TrendDirection.Decreasing: return TrendEvaluation.DownGood; case TrendDirection.Increasing: return TrendEvaluation.UpBad; case TrendDirection.None: return TrendEvaluation.None; case TrendDirection.Unchanged: return TrendEvaluation.NoChangeNoOpinion; } return TrendEvaluation.None; }
public Trend(int interval, string symbol, TrendDirection direction, double speed) { this.Interval = interval; this.Symbol = symbol; this.Direction = direction; this.Speed = speed; }
public Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var mfiValue = _mfiIndicator.GetIndicatorValue(currentCandle).IndicatorValue; Console.WriteLine($"Mfi indicator value: {mfiValue}"); if (mfiValue < 0) { return(Task.FromResult(TrendDirection.None)); } if (mfiValue > 0 && mfiValue <= 20) { if (_lastTrend == TrendDirection.Short) { _lastTrend = TrendDirection.Long; return(Task.FromResult(_lastTrend)); } } if (mfiValue >= 80) { if (_lastTrend == TrendDirection.Long) { _lastTrend = TrendDirection.Short; return(Task.FromResult(_lastTrend)); } } return(Task.FromResult(TrendDirection.None)); }
private void SetSignal(int signal, string message) { if (message != null) { P(message); } _signal = signal; switch (_signal) { case 1: _trendDirection = TrendDirection.Long; BackColor = Color.LightGreen; break; case -1: _trendDirection = TrendDirection.Short; BackColor = Color.Pink; break; case 0: _trendDirection = TrendDirection.Neutral; BackColor = Color.Yellow; break; default: break; } }
public Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var rsiValue = _rsiIndicator.GetIndicatorValue(currentCandle).IndicatorValue; Console.WriteLine($"Rsi value: {rsiValue}"); if (rsiValue < 30 && rsiValue > 0) { if (_lastTrend == TrendDirection.Long) { return(Task.FromResult(TrendDirection.None)); } _lastTrend = TrendDirection.Long; return(Task.FromResult(_lastTrend)); } if (rsiValue > 70) { if (_lastTrend == TrendDirection.Short) { return(Task.FromResult(TrendDirection.None)); } _lastTrend = TrendDirection.Short; return(Task.FromResult(_lastTrend)); } return(Task.FromResult(TrendDirection.None)); }
public Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var candleSticksValue = _candleSticksIndicator.GetIndicatorValue(currentCandle); if (_lastTrend == TrendDirection.Short) { if (candleSticksValue.CandleFormat == CandleFormat.BullishMarubozu) { _lastTrend = TrendDirection.Long; return(Task.FromResult(_lastTrend)); } } if (_lastTrend == TrendDirection.Long) { if (currentCandle.ClosePrice >= _lastBuyPrice * (decimal)1.01 || candleSticksValue.CandleFormat == CandleFormat.BearishMarubozu) { _lastTrend = TrendDirection.Short; } else { return(Task.FromResult(TrendDirection.None)); } } return(Task.FromResult(TrendDirection.None)); }
public OrderAction GetOrderAction(TrendDirection trendDirection) { var ask = _mqlApi.Ask; var bid = _mqlApi.Bid; var lower = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_LOWER, Shift); var main = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_MAIN, Shift); var upper = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_UPPER, Shift); var points = _mqlApi.MarketInfo(_symbol, MqlApi.MODE_POINT); // Todo: Margin should be added! switch (trendDirection) { case TrendDirection.UP: // Case 1 Touches middle band if (ask + _marginPoints * points <= main) { return new OrderAction { OrderActionType = OrderActionType.BUY }; } // Case 2 Touches lower band if (ask + _marginPoints * points <= lower) { return new OrderAction { OrderActionType = OrderActionType.BUY }; } break; case TrendDirection.DOWN: if (ask - _marginPoints * points >= main) { return new OrderAction { OrderActionType = OrderActionType.SELL }; } if (ask - _marginPoints * points >= upper) { return new OrderAction { OrderActionType = OrderActionType.SELL }; } break; } return new OrderAction { OrderActionType = OrderActionType.NONE }; }
public void Trend_Constructor_test() { int interval = 60; string symbol = "RTS-12.13_FT"; TrendDirection direction = TrendDirection.Up; double speed = 30; Trend trend = new Trend(interval, symbol, direction, speed); Assert.AreEqual(interval, trend.Interval); Assert.AreEqual(symbol, trend.Symbol); Assert.AreEqual(direction, trend.Direction); Assert.AreEqual(speed, trend.Speed); }
public TrendDirection GetSpreadTrend() { TrendDirection trd = TrendDirection.UnKnown; if (Spread[0] > Spread[1]) { trd = TrendDirection.Up; } else if (Spread[0] < Spread[1]) { trd = TrendDirection.Down; } return(trd); }
public TradeEngine() { //create main timer for polling mainTimer = new System.Timers.Timer(); mainTimer.Interval = 150000; //launch polling event every 2.5 minutes mainTimer.AutoReset = true; mainTimer.Enabled = true; myAccountSettings = new AccountSettings { BASEURI = BASEURI, APIKEY = APIKEY, ID = ID }; //initialize default variables myAccount = new AccountAccessor(myAccountSettings); myAccount.RegisterTimer(mainTimer); instruments = new InstrumentAccessor(myAccountSettings, "EUR_USD"); instruments.RegisterTimer(mainTimer); orders = new OrderAccessor(myAccountSettings); //OMG, initialize first object in collection SMA50 = new List <IndicatorOverTime>(); SMA50.Add(new IndicatorOverTime { result = Indicators.SMA((instruments.GetBars(50, "M5"))), time = instruments.GetBars(1, "M5").candles[0].time }); trend = new TrendDirection(); //set because log file is written before trend is actually calculated, so should be sideways until there is enough data to actually determine the trend trend = TrendDirection.Sideways; tradeEngineLog = new LogData(); //write headers to csv using (StreamWriter writer = new StreamWriter(outFile)) { CsvWriter csvWriter = new CsvWriter(writer); csvWriter.WriteHeader <LogData>(); csvWriter.NextRecord(); } WriteLog(); mainTimer.Elapsed += OnUpdate; }
public void OnUpdate(object _sender, ElapsedEventArgs _e) { //check if new data needs to be built from bar data, and if so write log file if (instruments.GetBars(1, "M5").candles[0].time > SMA50[SMA50.Count - 1].time) { SMA50.Add(new IndicatorOverTime { result = Indicators.SMA((instruments.GetBars(50, "M5"))), time = instruments.GetBars(1, "M5").candles[0].time }); trend = Indicators.Trend(SMA50); WriteLog(); } //Console.WriteLine("Simple Moving average over 50 bars:{0}", SMA50[SMA50.Count - 1].result); //Console.WriteLine("The current trend is:{0}",trend); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; if (_lastTrend == TrendDirection.Short) { if (shortEmaValue > longEmaValue) { if (_persistenceBuyCount > 2) { _lastTrend = TrendDirection.Long; } else { _persistenceBuyCount++; return(await Task.FromResult(TrendDirection.None)); } } else { return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (shortEmaValue < longEmaValue) { if (_persistenceSellCount > 5) { _lastTrend = TrendDirection.Short; } else { _persistenceSellCount++; return(await Task.FromResult(TrendDirection.None)); } } else { return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public Advice GetAdvice(IList<OHLC> candles) { if (candles.Count < 2) { return Advice.None; } var lastCandle = candles[candles.Count - 1]; var prevCandle = candles[candles.Count - 2]; //var diff = 100 * (ShortMA.Output[i - ShortMA.Begin] - LongMA.Output[i - LongMA.Begin]) / LongMA.Output[i - LongMA.Begin]; double diff = (double)((lastCandle.Close - prevCandle.Close)/prevCandle.Close)*100; if (diff > _upThreshold) { if (_trend != TrendDirection.Up) { _trend = TrendDirection.Up; return Advice.Buy; } // return Advice.Buy; return Advice.None; } else if (diff < _downThreshold) { if (_trend != TrendDirection.Down) { _trend = TrendDirection.Down; return Advice.Sell; } // return Advice.Sell; return Advice.None; } return Advice.None; }
/// <summary> /// Get the last inflection for the given barNo /// </summary> /// <param name="barNo"></param> /// <returns>the number of bars ago/barNo for last inflection</returns> public int GetLastInflection(Series <int> inflection, int barNo, TrendDirection dir, BarIndexType barIdxType) { int inft = -1; for (int i = 1; i < barNo - BarsRequiredToPlot - 1; i++) { if ((inflection[i] < 0 && dir == TrendDirection.Down) || (inflection[i] > 0 && dir == TrendDirection.Up)) { inft = i; } if (barNo >= Input.Count) { Print("inflection[" + i + "]=" + inflection[i] + ", inft=" + inft); } } if (inft > 0 && barIdxType == BarIndexType.BarNO) { inft = CurrentBar - inft; } //Print("GetLastInflection barNo, currentBar, inft=" + barNo + "," + CurrentBar + "," + inft); return(inft); }
public Advice GetAdvice(IList <OHLC> candles) { if (candles.Count < 2) { return(Advice.None); } var lastCandle = candles[candles.Count - 1]; var prevCandle = candles[candles.Count - 2]; //var diff = 100 * (ShortMA.Output[i - ShortMA.Begin] - LongMA.Output[i - LongMA.Begin]) / LongMA.Output[i - LongMA.Begin]; double diff = (double)((lastCandle.Close - prevCandle.Close) / prevCandle.Close) * 100; if (diff > _upThreshold) { if (_trend != TrendDirection.Up) { _trend = TrendDirection.Up; return(Advice.Buy); } // return Advice.Buy; return(Advice.None); } else if (diff < _downThreshold) { if (_trend != TrendDirection.Down) { _trend = TrendDirection.Down; return(Advice.Sell); } // return Advice.Sell; return(Advice.None); } return(Advice.None); }
public Advice GetAdvice(IList <OHLC> candles) { var shortMA = Analysis.MovingAverages.CalculateEMA(candles, _shortEMAPeriod); var longMA = Analysis.MovingAverages.CalculateEMA(candles, _longEMAPeriod); if (shortMA == null || longMA == null) { return(Advice.None); } int i = candles.Count - 1; var diff = 100 * (shortMA.Output[i - shortMA.Begin] - longMA.Output[i - longMA.Begin]) / ((longMA.Output[i - longMA.Begin] + shortMA.Output[i - shortMA.Begin]) / 2); var candle = candles.Last(); if (diff > _buyThreshold) { if (_trend != TrendDirection.Up) { _trend = TrendDirection.Up; return(Advice.Buy); } // return Advice.Buy; return(Advice.None); } else if (diff < _sellThreshold) { if (_trend != TrendDirection.Down) { _trend = TrendDirection.Down; return(Advice.Sell); } // return Advice.Sell; return(Advice.None); } return(Advice.None); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var price = currentCandle.ClosePrice; var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var emaTrend = shortEmaValue > longEmaValue ? TrendDirection.Long : TrendDirection.Short; //Console.WriteLine($"Short EMA value: {shortEmaValue}; Long EMA value: {longEmaValue}; EMA Trend: {emaTrend}; Candlesticks: {candleSticksValue}"); if (_lastTrend == TrendDirection.Short) { if (emaTrend == TrendDirection.Long) { _lastTrend = TrendDirection.Long; _lastBuyPrice = price; } else { return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (price >= _lastBuyPrice * (decimal)1.01 || price < _lastBuyPrice * (decimal)0.9975) { _lastTrend = TrendDirection.Short; } else { return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public Advice GetAdvice(IList<OHLC> candles) { var shortMA = Analysis.MovingAverages.CalculateEMA(candles, _shortEMAPeriod); var longMA = Analysis.MovingAverages.CalculateEMA(candles, _longEMAPeriod); if (shortMA == null || longMA == null) { return Advice.None; } int i = candles.Count - 1; var diff = 100 * (shortMA.Output[i - shortMA.Begin] - longMA.Output[i - longMA.Begin]) / ((longMA.Output[i - longMA.Begin] + shortMA.Output[i - shortMA.Begin]) / 2); var candle = candles.Last(); if (diff > _buyThreshold) { if (_trend != TrendDirection.Up) { _trend = TrendDirection.Up; return Advice.Buy; } // return Advice.Buy; return Advice.None; } else if (diff < _sellThreshold) { if (_trend != TrendDirection.Down) { _trend = TrendDirection.Down; return Advice.Sell; } // return Advice.Sell; return Advice.None; } return Advice.None; }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var emaDiffValue = shortEmaValue - longEmaValue; var signalEmaValue = Math.Round(_signalEmaIndicator.GetIndicatorValue(emaDiffValue).IndicatorValue, 4); var macdValue = Math.Round(emaDiffValue - signalEmaValue, 4); Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"MACD: {macdValue};\t" + $"PeekMACD: {_maxOrMinMacd};\t" + $"Close price: {currentCandle.ClosePrice};"); if (!_lastMacd.HasValue) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } if (_lastMacd < 0 && macdValue >= 0) { if (_macdSwitch) { _maxMacd = 0; } else { _macdSwitch = true; } } if (_lastMacd > 0 && macdValue <= 0) { if (_macdSwitch) { _minMacd = 0; } else { _macdSwitch = true; } } if (macdValue < 0 && macdValue < _minMacd) { _minMacd = macdValue; _minMacdClosePrice = currentCandle.ClosePrice; } if (macdValue > 0 && macdValue > _maxMacd) { _maxMacd = macdValue; _maxMacdClosePrice = currentCandle.ClosePrice; } // wait 1 hour if (_candleCount <= 60) { _candleCount++; return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if (macdValue > 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_stopTrading == false && macdValue < _options.BuyThreshold && diffPreviousMacd < -(decimal)1.0 && macdValue > _lastMacd && currentCandle.ClosePrice > _lastClosePrice) { _macdRate = (1 - Math.Round(_minMacdClosePrice / _maxMacdClosePrice, 4)) * 100; Console.WriteLine($"MaxMacd: {_maxMacdClosePrice}; MinMacd: {_minMacdClosePrice}; Rate: {_macdRate}%"); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; if (_macdRate < (decimal)2.75 || _macdRate > (decimal)5.5) { _stopTrading = true; return(await Task.FromResult(TrendDirection.None)); } _lastTrend = TrendDirection.Long; _maxOrMinMacd = 0; _lastBuyPrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = 1 - (_macdRate - (decimal)0.4) / 100; var profitPercentage = 1 + (_macdRate + (decimal)0.4) / 100; //(decimal) 1.038; var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_lastMacd > macdValue && diffPreviousMacd > (decimal)1.0 && (currentCandle.ClosePrice > _lastBuyPrice * profitPercentage || currentCandle.ClosePrice < _lastBuyPrice * stopPercentage)) { Console.WriteLine($"Stop percentage: {stopPercentage}; Profit percentage: {profitPercentage}"); _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var macdValue = Math.Round(shortEmaValue - longEmaValue, 4); var ichimokuCloudValue = _ichimokuCloudIndicator.GetIndicatorValue(currentCandle); var ema200Value = _ema200Indicator.GetIndicatorValue(currentCandle).IndicatorValue; Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"SSA: {ichimokuCloudValue.IchimokuCloud?.SenkouSpanAValue}; " + $"SSB: {ichimokuCloudValue.IchimokuCloud?.SenkouSpanBValue}; " + $"TS: {ichimokuCloudValue.IchimokuCloud?.TenkanSenValue}; " + $"KS: {ichimokuCloudValue.IchimokuCloud?.KijunSenValue}; " + $"EMA200: {ema200Value}; " + $"MACD: {macdValue}; " + $"MinMaxMacd: {_maxOrMinMacd}; " + $"Close price: {currentCandle.ClosePrice};"); if (!_lastMacd.HasValue || _lastMacd == 0) { _lastMacd = macdValue; return(await Task.FromResult(TrendDirection.None)); } if (ichimokuCloudValue.IchimokuCloud == null) { _lastMacd = macdValue; return(await Task.FromResult(TrendDirection.None)); } var ssa = ichimokuCloudValue.IchimokuCloud.SenkouSpanAValue; var ssb = ichimokuCloudValue.IchimokuCloud.SenkouSpanBValue; //var ts = ichimokuCloudValue.IchimokuCloud.TenkanSenValue; //var ks = ichimokuCloudValue.IchimokuCloud.KijunSenValue; //var ichimokuCloudMin = new List<decimal> { ssa, ssb, ts, ks}.Min(); var ichimokuCloudSsList = new List <decimal> { ssa, ssb }; _last10Ema200ClosePriceRate.Enqueue(Math.Round(currentCandle.ClosePrice / ema200Value, 4)); if (_lastTrend == TrendDirection.Short) { if (macdValue > 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_stopTrading == false && macdValue < 0 && diffPreviousMacd < -(decimal)0.2 && macdValue > _lastMacd && currentCandle.ClosePrice > _lastClosePrice && currentCandle.ClosePrice > ema200Value && currentCandle.ClosePrice <= ichimokuCloudSsList.Max() && currentCandle.ClosePrice >= ichimokuCloudSsList.Min() && _last10Ema200ClosePriceRate.GetItems().Count(a => a > (decimal)1.0) > 5) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _lastTrend = TrendDirection.Long; _maxOrMinMacd = 0; _lastBuyPrice = currentCandle.ClosePrice; _stopTrading = true; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = (decimal)0.98; var profitPercentage = (decimal)1.03; if (currentCandle.ClosePrice <= _lastBuyPrice * stopPercentage) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; return(await Task.FromResult(_lastTrend)); } var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_lastMacd > macdValue && diffPreviousMacd > (decimal)0.4 //&& currentCandle.ClosePrice < ema200Value //&& currentCandle.ClosePrice > _lastBuyPrice * profitPercentage ) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; if (currentCandle.ClosePrice <= _lastBuyPrice * profitPercentage) { return(await Task.FromResult(TrendDirection.None)); } Console.WriteLine($"Stop percentage: {stopPercentage}; Profit percentage: {profitPercentage}"); _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var macdValue = Math.Round(shortEmaValue - longEmaValue, 4); var rsiValue = _rsiIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var ichimokuCloudValue = _ichimokuCloudIndicator.GetIndicatorValue(currentCandle); var ssa = ichimokuCloudValue.IchimokuCloud?.SenkouSpanAValue; var ssb = ichimokuCloudValue.IchimokuCloud?.SenkouSpanBValue; var ts = ichimokuCloudValue.IchimokuCloud?.TenkanSenValue; var ks = ichimokuCloudValue.IchimokuCloud?.KijunSenValue; Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"SSA: {ssa}; " + $"SSB: {ssb}; " + $"TS: {ts}; " + $"KS: {ks}; " + $"MACD: {macdValue}; " + $"MinMaxMacd: {_maxOrMinMacd}; " + $"RSI: {rsiValue}; " + $"Close price: {Math.Round(currentCandle.ClosePrice, 4)};"); // wait 1 hour if (_candleCount <= 60) { _candleCount++; _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if ((currentCandle.ClosePrice < ssa && currentCandle.ClosePrice < ssb) && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } if (currentCandle.ClosePrice > ssa && currentCandle.ClosePrice > ssb && currentCandle.CandleType == CandleType.Green && _stopTrading == false && macdValue < 15 ) { _lastMacd = macdValue; _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastTrend = TrendDirection.Long; _lastBuyPrice = currentCandle.ClosePrice; _lastClosePrice = currentCandle.ClosePrice; } else { _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (_delayCount < 10) { Console.WriteLine($"DelayCount: {_delayCount}"); _delayCount++; _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = (decimal)0.95; var profitPercentage = (decimal)1.015; var diffPreviousMacd = _maxOrMinMacd < 0 ? 0 : Math.Abs(_maxOrMinMacd - macdValue); var diffLastClosePricePercentage = (currentCandle.ClosePrice / _lastClosePrice) * (decimal)100.0 - 100; if (diffLastClosePricePercentage <= (decimal) - 1.5) { _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(_lastTrend)); } if (currentCandle.ClosePrice < _lastBuyPrice * stopPercentage) { _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(_lastTrend)); } if ( macdValue > 0 && _lastMacd > 0 && _lastMacd > macdValue && diffPreviousMacd > (decimal)1.0 && currentCandle.ClosePrice > _lastBuyPrice * profitPercentage) { _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(_lastTrend)); } _last5Macd.Enqueue(macdValue); _prevClosePrices.Enqueue(currentCandle.ClosePrice); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } return(await Task.FromResult(_lastTrend)); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var macdValue = Math.Round(shortEmaValue - longEmaValue, 4); var rsiValue = _rsiIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var ichimokuCloudValue = _ichimokuCloudIndicator.GetIndicatorValue(currentCandle); var ssa = ichimokuCloudValue.IchimokuCloud?.SenkouSpanAValue; var ssb = ichimokuCloudValue.IchimokuCloud?.SenkouSpanBValue; var ts = ichimokuCloudValue.IchimokuCloud?.TenkanSenValue; var ks = ichimokuCloudValue.IchimokuCloud?.KijunSenValue; Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"SSA: {ssa}; " + $"SSB: {ssb}; " + $"TS: {ts}; " + $"KS: {ks}; " + //$"LFSsa: {ichimokuCloudValue.IchimokuCloud?.SsaFuture.Last()}; " + //$"LFSsb: {ichimokuCloudValue.IchimokuCloud?.SsbFuture.Last()}; " + $"MACD: {macdValue}; " + $"MinMaxMacd: {_maxOrMinMacd}; " + $"RSI: {rsiValue}; " + $"Close price: {Math.Round(currentCandle.ClosePrice, 4)};"); // wait 1 hour if (_candleCount <= 60) { _candleCount++; _last5Macd.Enqueue(macdValue); return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if (macdValue < 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } if (currentCandle.ClosePrice > ssa && currentCandle.ClosePrice > ssb && currentCandle.CandleType == CandleType.Green //&& ts > ks && currentCandle.ClosePrice > ts && currentCandle.ClosePrice > ks && macdValue > 0 && macdValue < 1 && _stopTrading == false && rsiValue >= 70 && _lastMacd < macdValue && _last5Macd.GetItems().All(a => a < macdValue) ) { _lastMacd = macdValue; _last5Macd.Enqueue(macdValue); _lastTrend = TrendDirection.Long; _lastBuyPrice = currentCandle.ClosePrice; _lastClosePrice = currentCandle.ClosePrice; } else { _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (_delayCount < 10) { Console.WriteLine($"DelayCount: {_delayCount}"); _delayCount++; _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = (decimal)0.985; var profitPercentage = (decimal)1.018; var diffPreviousMacd = Math.Abs(_maxOrMinMacd - macdValue); if (currentCandle.ClosePrice < _lastBuyPrice * stopPercentage) { _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(_lastTrend)); } if ( macdValue > 0 && //_lastMacd > 0 && _lastMacd < macdValue && //diffPreviousMacd > (decimal)0.2 && //rsiValue > 80 && (ssa * (decimal)1.005 >= currentCandle.ClosePrice || ssb * (decimal)1.005 >= currentCandle.ClosePrice) && currentCandle.ClosePrice > _lastBuyPrice * profitPercentage) { _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(_lastTrend)); } //if ( // macdValue > 0 && // _lastMacd > 0 && // _lastMacd < macdValue && // _lastClosePrice > currentCandle.ClosePrice && // //_lastClosePrice - currentCandle.ClosePrice > 2 && // rsiValue > 80 && // currentCandle.ClosePrice > _lastBuyPrice * profitPercentage) //{ // _last5Macd.Enqueue(macdValue); // _lastMacd = macdValue; // _delayCount = 1; // _lastTrend = TrendDirection.Short; // _stopTrading = true; // _lastClosePrice = currentCandle.ClosePrice; // return await Task.FromResult(_lastTrend); //} if (currentCandle.ClosePrice < ts && currentCandle.ClosePrice < ks && currentCandle.ClosePrice < ssa || currentCandle.ClosePrice < ssb) { _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; if (currentCandle.ClosePrice >= _lastBuyPrice * stopPercentage) { return(await Task.FromResult(TrendDirection.None)); } _delayCount = 1; _lastTrend = TrendDirection.Short; _stopTrading = true; } else { _last5Macd.Enqueue(macdValue); _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var macdValue = Math.Round(shortEmaValue - longEmaValue, 4); var signalEmaValue = Math.Round(_signalEmaIndicator.GetIndicatorValue(macdValue).IndicatorValue, 4); var histogramValue = Math.Round(macdValue - signalEmaValue, 4); var depth = await _exchangeProvider.GetDepth(tradingPair); var bidsSum = depth.Bids.Sum(s => s.Quantity); var asksSum = depth.Asks.Sum(s => s.Quantity); Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"MACD Value/Hist.: {macdValue}/{histogramValue};\t" + $"Bids price/qty/sum qty: {depth.Bids.First(f => f.Quantity == depth.Bids.Max(b => b.Quantity))}/{Math.Round(bidsSum,4)};\t" + $"Asks price/qty/sum qty: {depth.Asks.First(f => f.Quantity == depth.Asks.Max(b => b.Quantity))}/{Math.Round(asksSum, 4)};\t" + $"Close price: {currentCandle.ClosePrice};"); _volumenQueue.Enqueue(currentCandle.Volume); if (!_lastMacd.HasValue || _lastMacd == 0) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _macdDirection = macdValue < 0 ? MacdDirection.LessThanZero : MacdDirection.GreaterThanZero; return(await Task.FromResult(TrendDirection.None)); } //CreateMacdStatistics(macdValue, currentCandle); if (_lastMacd < 0 && macdValue >= 0) { if (_macdSwitch) { _maxMacd = 0; } else { _macdSwitch = true; } } if (_lastMacd > 0 && macdValue <= 0) { if (_macdSwitch) { _minMacd = 0; } else { _macdSwitch = true; } } if (macdValue < 0 && macdValue < _minMacd) { _minMacd = macdValue; _minMacdClosePrice = currentCandle.ClosePrice; } if (macdValue > 0 && macdValue > _maxMacd) { _maxMacd = macdValue; _maxMacdClosePrice = currentCandle.ClosePrice; } // wait 0.5 hour if (_candleCount <= 30) { _candleCount++; if (macdValue < 0 && macdValue < _minWarmupMacd) { _minWarmupMacd = macdValue; } Console.WriteLine($"Min warmup Macd: {_minWarmupMacd}"); return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if (macdValue > 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } //var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_stopTrading == false && macdValue < _options.BuyThreshold //&& diffPreviousMacd < -(decimal)0.2 && macdValue > _lastMacd && currentCandle.ClosePrice > _lastClosePrice) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _profitEstimationRate = CheckProfitPrecentageAsync(depth, currentCandle.ClosePrice); if (_profitEstimationRate < 0) { return(await Task.FromResult(TrendDirection.None)); } _lastTrend = TrendDirection.Long; _maxOrMinMacd = 0; _lastBuyPrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = 1 - _profitEstimationRate / (decimal)100.0; //1 - (_macdRate - (decimal)0.4) / 100; //(decimal) 0.97; var profitPercentage = 1 + (_profitEstimationRate + (decimal)0.4) / (decimal)100.0; //1 + (_macdRate + (decimal)0.4) / 100; //(decimal) 1.038; //var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_lastMacd > macdValue //&& diffPreviousMacd > (decimal)1.0 && currentCandle.ClosePrice > _lastBuyPrice * profitPercentage || currentCandle.ClosePrice < _lastBuyPrice * stopPercentage) { Console.WriteLine($"Stop percentage: {stopPercentage}; Profit percentage: {profitPercentage}"); _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var macdValue = Math.Round(shortEmaValue - longEmaValue, 4); var signalEmaValue = Math.Round(_signalEmaIndicator.GetIndicatorValue(macdValue).IndicatorValue, 4); var histogramValue = Math.Round(macdValue - signalEmaValue, 4); var ichimokuCloudValue = _ichimokuCloudIndicator.GetIndicatorValue(currentCandle); var ssa = ichimokuCloudValue.IchimokuCloud?.SenkouSpanAValue; var ssb = ichimokuCloudValue.IchimokuCloud?.SenkouSpanBValue; DepthModel depth = null; if (ichimokuCloudValue.IchimokuCloud != null) { depth = await _exchangeProvider.GetDepth(tradingPair); } var bid = depth?.Bids.First(f => f.Quantity == depth.Bids.Max(b => b.Quantity)); var ask = depth?.Asks.First(f => f.Quantity == depth.Asks.Max(b => b.Quantity)); var bidPrice = bid?.Price ?? Math.Round(currentCandle.ClosePrice, 4); var askPrice = ask?.Price ?? Math.Round(currentCandle.ClosePrice, 4); var bidPercentage = Math.Round((currentCandle.ClosePrice / bidPrice) * (decimal)100.0 - (decimal)100.0, 2); var askPercentage = Math.Round((currentCandle.ClosePrice / askPrice) * (decimal)100.0 - (decimal)100.0, 2); Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"MACD Value: {macdValue}; " + $"SSA/SSB: {ssa}/{ssb}; " + $"Bids price/qty/%: {bid}/{bidPercentage}%; " + $"Asks price/qty/%: {ask}/{askPercentage}%; " + $"Close price: {Math.Round(currentCandle.ClosePrice, 4)};"); _volumenQueue.Enqueue(currentCandle.Volume); if (!_lastMacd.HasValue || _lastMacd == 0) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _macdDirection = macdValue < 0 ? MacdDirection.LessThanZero : MacdDirection.GreaterThanZero; return(await Task.FromResult(TrendDirection.None)); } if (_lastMacd < 0 && macdValue >= 0) { if (_macdSwitch) { _maxMacd = 0; } else { _macdSwitch = true; } } if (_lastMacd > 0 && macdValue <= 0) { if (_macdSwitch) { _minMacd = 0; } else { _macdSwitch = true; } } if (macdValue < 0 && macdValue < _minMacd) { _minMacd = macdValue; _minMacdClosePrice = currentCandle.ClosePrice; } if (macdValue > 0 && macdValue > _maxMacd) { _maxMacd = macdValue; _maxMacdClosePrice = currentCandle.ClosePrice; } // wait 0.5 hour if (_candleCount <= 30) { _candleCount++; if (macdValue < 0 && macdValue < _minWarmupMacd) { _minWarmupMacd = macdValue; } Console.WriteLine($"Min warmup Macd: {_minWarmupMacd}"); return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if (macdValue > 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } //var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_stopTrading == false && macdValue < _options.BuyThreshold && currentCandle.ClosePrice > ssa && currentCandle.ClosePrice > ssb && currentCandle.CandleType == CandleType.Green //&& diffPreviousMacd < -(decimal)0.2 && macdValue > _lastMacd && currentCandle.ClosePrice > _lastClosePrice) { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; _profitEstimationRate = CheckProfitPrecentageAsync(depth, currentCandle.ClosePrice); if (_profitEstimationRate < 0) { return(await Task.FromResult(TrendDirection.None)); } _lastTrend = TrendDirection.Long; _maxOrMinMacd = 0; _lastBuyPrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } if (macdValue < 0) { _maxOrMinMacd = 0; } var stopPercentage = 1 - _profitEstimationRate / (decimal)100.0; //1 - (_macdRate - (decimal)0.4) / 100; //(decimal) 0.97; var profitPercentage = 1 + (_profitEstimationRate + (decimal)0.4) / (decimal)100.0; //1 + (_macdRate + (decimal)0.4) / 100; //(decimal) 1.038; //var diffPreviousMacd = _maxOrMinMacd - macdValue; if (_lastMacd > macdValue //&& diffPreviousMacd > (decimal)1.0 && currentCandle.ClosePrice > _lastBuyPrice * profitPercentage || currentCandle.ClosePrice < _lastBuyPrice * stopPercentage) { Console.WriteLine($"Stop percentage: {stopPercentage}; Profit percentage: {profitPercentage}"); _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; } else { _lastMacd = macdValue; _lastClosePrice = currentCandle.ClosePrice; return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
private void SimpleTrendFollowing() { SqlConnection dbConnect = new SqlConnection(connectionString); dbConnect.Open(); EUR_USDDataContext linqInterop = new EUR_USDDataContext(dbConnect); void BuildLog(int _i) //build object for logging to database { SimpleTrendFollowing row = new SimpleTrendFollowing { BarTime = bars.candles[_i].time, SystemTime = DateTime.Now, StandardDeviation = standardDeviation, TimeFrame = timeFrame, SMA50 = indicator[_i].result, LossTrades = lossTrades, ProfitTrades = profitTrades, TakeProfit = takeProfit, Distance = distance, TotalTrades = totalTrades, Trade = trade, StopLoss = stopLoss, AccountBalance = accountBalance, Trend = trend.ToString() }; linqInterop.SimpleTrendFollowings.InsertOnSubmit(row); linqInterop.SubmitChanges(); } decimal padding = 1.0M; //added to standard deviation for stoploss calculation int tradesPerDay = maxTradesPerDay; bool openOrder = false; int windowSize = 50; //should be same as SMA period //trade when market is strongest, EST TimeSpan start = new TimeSpan(05, 00, 00); TimeSpan end = new TimeSpan(22, 59, 00); for (int i = 1; i <= bars.candles.Count - 1; i++) { trade = default; //create sliding window OandaRootInstrumentObject barWindow = new OandaRootInstrumentObject(); if (i < windowSize) { barWindow.candles = new List <Candle>(); barWindow.candles = bars.candles.GetRange(0, i + 1); } /* * else if (i>bars.candles.Count-1-windowSize) * { * barWindow.candles = new List<Candle>(); * barWindow.candles = bars.candles.GetRange(i, bars.candles.Count-i); * } */ else { barWindow.candles = new List <Candle>(); barWindow.candles = bars.candles.GetRange(i - windowSize, windowSize); } indicator.Add(new IndicatorOverTime { result = Indicators.SMA(barWindow), time = bars.candles[i].time }); trend = Indicators.Trend(indicator); //if time of bar within trading window if (bars.candles[i].time.TimeOfDay <= end && bars.candles[i].time.TimeOfDay >= start && openOrder == false) { if (tradesPerDay > 0) { if (trend == TrendDirection.StrongUp) //go long { trade = "Long:Start"; closingPrice = new List <double>(); //get closing price for last 100 bars to calc standard deviation for (int i2 = 0; i2 < barWindow.candles.Count - 1; i2++) { closingPrice.Add((double)barWindow.candles[i2].mid.c); } standardDeviation = (decimal)MathNet.Numerics.Statistics.ArrayStatistics.StandardDeviation(closingPrice.ToArray()); distance = (standardDeviation * 2 + (standardDeviation * padding)); stopLoss = (decimal)bars.candles[i].mid.c - distance; takeProfit = (decimal)bars.candles[i].mid.c + (distance * riskVsReward); tradesPerDay = tradesPerDay - 1; openOrder = true; BuildLog(i); } else if (trend == TrendDirection.StrongDown) //short { trade = "Short:Start"; closingPrice = new List <double>(); //get closing price for last 100 bars to calc standard deviation for (int i2 = 0; i2 < barWindow.candles.Count - 1; i2++) { closingPrice.Add((double)barWindow.candles[i2].mid.c); } standardDeviation = (decimal)MathNet.Numerics.Statistics.ArrayStatistics.StandardDeviation(closingPrice.ToArray()); distance = (standardDeviation * 2 + (standardDeviation * padding)); stopLoss = (decimal)bars.candles[i].mid.c + distance; takeProfit = (decimal)bars.candles[i].mid.c - (distance * riskVsReward); tradesPerDay = tradesPerDay - 1; openOrder = true; BuildLog(i); } } } else if (openOrder == true) //check if price targets have been met { if (stopLoss > takeProfit) //short { if (bars.candles[i].mid.c <= takeProfit) //profit { openOrder = false; trade = "Short:Profit"; profitTrades++; totalTrades = profitTrades + lossTrades; Profit(); BuildLog(i); } else if (bars.candles[i].mid.c >= stopLoss) //loss { openOrder = false; trade = "Short:Loss"; lossTrades++; totalTrades = profitTrades + lossTrades; Loss(); BuildLog(i); } } else //long { if (bars.candles[i].mid.c >= takeProfit) //profit { openOrder = false; trade = "Long:Profit"; profitTrades++; totalTrades = profitTrades + lossTrades; Profit(); BuildLog(i); } else if (bars.candles[i].mid.c <= stopLoss) //loss { openOrder = false; trade = "Long:Loss"; lossTrades++; totalTrades = profitTrades + lossTrades; Loss(); BuildLog(i); } } } if (bars.candles[i].time.TimeOfDay == new TimeSpan(00, 00, 00)) //check for end of day, reset count { tradesPerDay = maxTradesPerDay; //closingPrice = new List<double>(); //closedTrade = default; } } linqInterop.Dispose(); dbConnect.Close(); }
public async Task <TrendDirection> CheckTrendAsync(string tradingPair, CandleModel currentCandle) { var shortEmaValue = _shortEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var longEmaValue = _longEmaIndicator.GetIndicatorValue(currentCandle).IndicatorValue; var emaDiffValue = shortEmaValue - longEmaValue; var signalEmaValue = Math.Round(_signalEmaIndicator.GetIndicatorValue(emaDiffValue).IndicatorValue, 4); var macdValue = Math.Round(emaDiffValue - signalEmaValue, 4); Console.WriteLine($"DateTs: {currentCandle.StartDateTime:s}; " + $"MACD: {macdValue}; " + $"PeekMACD: {_maxOrMinMacd}; " + $"Close price: {currentCandle.ClosePrice}; "); if (!_lastMacd.HasValue) { _lastMacd = macdValue; return(await Task.FromResult(TrendDirection.None)); } if (_lastTrend == TrendDirection.Short) { if (macdValue > 0 && _stopTrading) { _stopTrading = false; } if (macdValue < 0 && macdValue < _lastMacd) { _maxOrMinMacd = macdValue; } _lastMacd = macdValue; if (_stopTrading == false && macdValue < _options.BuyThreshold) { _lastTrend = TrendDirection.Long; _maxOrMinMacd = 0; _lastBuyPrice = currentCandle.ClosePrice; } else { return(await Task.FromResult(TrendDirection.None)); } } else if (_lastTrend == TrendDirection.Long) { if (macdValue > 0 && macdValue > _lastMacd) { _maxOrMinMacd = macdValue; } _lastMacd = macdValue; if (_maxOrMinMacd > _options.SellThreshold && currentCandle.ClosePrice > _lastBuyPrice * (decimal)1.01) { _lastTrend = TrendDirection.Short; _maxOrMinMacd = 0; _stopTrading = true; } else { return(await Task.FromResult(TrendDirection.None)); } } return(await Task.FromResult(_lastTrend)); }
public OrderAction GetOrderAction(TrendDirection trendDirection) { return(null); }
public OrderAction GetOrderAction(TrendDirection trendDirection) { return null; }
public async Task StartTradingAsync(string tradingPair, CandlePeriod candlePeriod, CancellationToken cancellationToken) { _cancellationToken = cancellationToken; _tradingPair = tradingPair; _delayInMilliseconds = (int)candlePeriod * _delayInMilliseconds; var lastSince = GetSinceUnixTime(candlePeriod); var lastScanId = _candleRepository.GetLatestScanId(); CandleModel currentCandle = null; if (_strategy.DelayInCandlePeriod > 1) { await ExecutePastCandleCheck(tradingPair, candlePeriod, lastScanId); } while (!cancellationToken.IsCancellationRequested) { var startWatcher = new Stopwatch(); startWatcher.Start(); var candles = await _exchangeProvider.GetCandlesAsync(tradingPair, candlePeriod, lastSince, lastSince + (int)candlePeriod * 60); var candlesList = candles.ToList(); if (candlesList.Count == 1) { currentCandle = candlesList.Last(); if (!_isSetFirstPrice) { _userBalanceService.FirstPrice = currentCandle; _isSetFirstPrice = true; } var trendDirection = await _strategy.CheckTrendAsync(tradingPair, currentCandle); await _candleRepository.SaveCandleAsync(tradingPair, Mapper.Map <List <CandleDto> >(new List <CandleModel> { currentCandle }), lastScanId); _lastTrendDirection = trendDirection; if (trendDirection == TrendDirection.Long) { await BuyAsync(currentCandle); } else if (trendDirection == TrendDirection.Short) { await SellAsync(currentCandle); } } else { Console.WriteLine($"DateTs: {DateTimeOffset.FromUnixTimeSeconds(lastSince):s}; Trend: [NO TRADES]; Close price: [NO TRADES]; Volumen: [NO TRADES]; Elapsed time: {startWatcher.ElapsedMilliseconds} ms"); } var utcNow = DateTime.UtcNow; var delayStartInSeconds = (int)candlePeriod * 60 - utcNow.Minute % (int)candlePeriod * 60 - utcNow.Second; // ReSharper disable once MethodSupportsCancellation await Task.Delay(delayStartInSeconds * 1000); lastSince += (int)candlePeriod * 60; startWatcher.Stop(); } if (cancellationToken.IsCancellationRequested) { if (currentCandle != null) { _userBalanceService.LastPrice = currentCandle; if (_lastTrendDirection == TrendDirection.Long) { // ReSharper disable once MethodSupportsCancellation SellAsync(currentCandle).Wait(); } } } }
public void Run(string _algorithim, string[] _timeFrames) { //run backtesting against specific algorithim against multiple timeframes SqlConnection dbConnect = new SqlConnection(connectionString); dbConnect.Open(); EUR_USDDataContext linqInterop = new EUR_USDDataContext(dbConnect); ProgressBarOptions progressBarOptions = new ProgressBarOptions { ProgressCharacter = '-' }; ProgressBar progressBar = new ProgressBar(runLength * _timeFrames.Count(), "Backtesting against Bar data", progressBarOptions); foreach (var tf in _timeFrames) { timeFrame = tf; totalTrades = default; profitTrades = default; lossTrades = default; accountBalance = startingBalance; for (int i = 0; i < runLength - 1; i++) { bars = new OandaRootInstrumentObject { candles = new List <Candle>(), granularity = tf, instrument = "EUR_USD" }; DateTime runDate = startDate.AddDays(i); //won't be days in DB for weekends, or december 25th, jan 01 if (!(runDate.DayOfWeek == DayOfWeek.Saturday) && !(runDate.DayOfWeek == DayOfWeek.Sunday) && !(runDate.Date == new DateTime(runDate.Year, 12, 25)) && !(runDate.Date == new DateTime(runDate.Year, 1, 1))) { //get all bars for the day for the selected timeframe, ordered by ID ascending, ID is identity and PK so these should always be unique in ascending order var results = from r in linqInterop.BarDatas where (r.BarTime.Date == runDate.Date && r.Timeframe == tf) orderby r.ID ascending select r; //need to massage data from sql db to OandaRootInstrumentObject foreach (var bar in results) { bars.candles.Add(new Candle { volume = bar.Volume, mid = (new Mid { c = bar.c, h = bar.h, l = bar.l, o = bar.o }), time = bar.BarTime }); } indicator = new List <IndicatorOverTime>(); indicator.Add(new IndicatorOverTime { result = bars.candles[0].mid.c, time = bars.candles[0].time }); trend = new TrendDirection(); //set because log file is written before trend is actually calculated, so should be sideways until there is enough data to actually determine the trend trend = TrendDirection.Sideways; switch (_algorithim) { case "SimpleTrendFollowing": { SimpleTrendFollowing(); break; } } } progressBar.Tick(); } } linqInterop.Dispose(); dbConnect.Close(); }
public OrderAction GetOrderAction(TrendDirection trendDirection) { var ask = _mqlApi.Ask; var bid = _mqlApi.Bid; var lower = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_LOWER, Shift); var main = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_MAIN, Shift); var upper = _mqlApi.iBands(_symbol, _timeFrame, _period, Deviation, BandsShift, AppliedPrice, MqlApi.MODE_UPPER, Shift); var points = _mqlApi.MarketInfo(_symbol, MqlApi.MODE_POINT); // Todo: Margin should be added! switch (trendDirection) { case TrendDirection.UP: // Case 1 Touches middle band if (ask + _marginPoints * points <= main) { return(new OrderAction { OrderActionType = OrderActionType.BUY }); } // Case 2 Touches lower band if (ask + _marginPoints * points <= lower) { return(new OrderAction { OrderActionType = OrderActionType.BUY }); } break; case TrendDirection.DOWN: if (ask - _marginPoints * points >= main) { return(new OrderAction { OrderActionType = OrderActionType.SELL }); } if (ask - _marginPoints * points >= upper) { return(new OrderAction { OrderActionType = OrderActionType.SELL }); } break; } return(new OrderAction { OrderActionType = OrderActionType.NONE }); }