예제 #1
0
        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;
        }
예제 #2
0
파일: Trend.cs 프로젝트: w1r2p1/TRx
 public Trend(int interval, string symbol, TrendDirection direction, double speed)
 {
     this.Interval  = interval;
     this.Symbol    = symbol;
     this.Direction = direction;
     this.Speed     = speed;
 }
예제 #3
0
        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));
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        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));
        }
예제 #7
0
        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
            };
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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;
        }
예제 #11
0
        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);
        }
예제 #12
0
        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));
        }
예제 #13
0
        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;
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }
예제 #17
0
        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));
        }
예제 #18
0
        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;
        }
예제 #19
0
        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));
        }
예제 #20
0
        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));
        }
예제 #21
0
        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));
        }
예제 #23
0
        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));
        }
예제 #24
0
        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));
        }
예제 #25
0
        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();
        }
예제 #26
0
        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));
        }
예제 #27
0
 public OrderAction GetOrderAction(TrendDirection trendDirection)
 {
     return(null);
 }
예제 #28
0
 public OrderAction GetOrderAction(TrendDirection trendDirection)
 {
     return null;
 }
예제 #29
0
		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;

			}
		}
예제 #30
0
        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();
                    }
                }
            }
        }
예제 #31
0
        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();
        }
예제 #32
0
        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
            });
        }