Example #1
0
        /// <summary>
        /// Retrieve candles from a file containing transactions
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="candleDurationInMinutes"></param>
        /// <param name="pair"></param>
        /// <param name="inputFile"></param>
        /// <returns></returns>
        public List<OHLC> GetCandlesFromCSVTransactions(DateTime from, DateTime? to, int candleDurationInMinutes, CurrencyPair pair, string inputFile = null)
        {
            if (string.IsNullOrEmpty(inputFile))
            {
                inputFile = GetTransactionsStoreFileName(pair);
            }
            if (!File.Exists(inputFile))
            {
                return new List<OHLC>();
            }
            var fromTimeStamp = BitstampAPI.UnixTimeHelper.GetFromDateTime(from);
            var toTimeStamp = to != null ? BitstampAPI.UnixTimeHelper.GetFromDateTime(to.Value) : (uint?)null;

            long? nextStamp = null;
            int candleDurationInSeconds = candleDurationInMinutes * 60;
            List<decimal> pricesForCurrentCandle = new List<decimal>();
            List<OHLC> candles = new List<OHLC>();
            using (var sr = new StreamReader(inputFile))
            {
                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                    var buf = line.Split(new[] { ',' });
                    long transTimeStamp = Convert.ToInt64(buf[0]);
                    if (transTimeStamp < fromTimeStamp)
                    {
                        continue;
                    }
                    decimal price = Convert.ToDecimal(buf[1], CultureInfo.InvariantCulture);
                    if (nextStamp == null)
                    {
                        nextStamp = transTimeStamp + candleDurationInSeconds;
                    }
                    if (transTimeStamp < nextStamp)
                    {
                        pricesForCurrentCandle.Add(price);
                    }
                    else//New candle
                    {
                        OHLC ohlc = new OHLC();
                        if (pricesForCurrentCandle.Count > 0)
                        {
                            ohlc = new OHLC
                            {
                                Open = pricesForCurrentCandle.First(),
                                High = pricesForCurrentCandle.Max(),
                                Low = pricesForCurrentCandle.Min(),
                                Close = pricesForCurrentCandle.Last(),
                                Date = BitstampAPI.UnixTimeHelper.ConvertToDateTime((uint)nextStamp)
                            };

                        }
                        else//No prices for this candle... use previous candle's close value
                        {
                            var prev = candles.Last();
                            ohlc = new OHLC
                            {
                                Open = prev.Close,
                                High = prev.Close,
                                Low = prev.Close,
                                Close = prev.Close,
                                Date = BitstampAPI.UnixTimeHelper.ConvertToDateTime((uint)nextStamp)
                            };
                        }
                        candles.Add(ohlc);

                        nextStamp = nextStamp + candleDurationInSeconds;
                        pricesForCurrentCandle.Clear();
                        if (toTimeStamp != null && nextStamp > toTimeStamp.Value)
                        {
                            break;
                        }
                    }

                }
            }//using

            return candles;


        }
Example #2
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 firstIndex = _longEMAPeriod - 1;
            if (candles.Count < _longEMAPeriod + _signalPeriod - 1)
            {
                return Advice.None;
            }

            int i = candles.Count - 1;

            var emaDiff = new OHLC[i - firstIndex + 1];
            for (int k = firstIndex; k <= i; k++)
            {
                emaDiff[k - firstIndex] = new OHLC
                    {
                        Close = (decimal)shortMA.Output[k - shortMA.Begin] - (decimal)longMA.Output[k - longMA.Begin]
                    };
            }

            var signal = Analysis.MovingAverages.CalculateEMA(emaDiff, _signalPeriod);
            if (signal == null)
            {
                return Advice.None;
            }

            var macdDiff = shortMA.Output[i - shortMA.Begin] - longMA.Output[i - longMA.Begin] - signal.Output[i - firstIndex - signal.Begin];


            if (macdDiff > 0.025/* settings.thresholds.up*/)
            {

                // new trend detected
                if (this._trend.Direction != TrendDirection.Up)
                    // reset the state for the new trend
                    this._trend = new Trend
                    {
                        Duration = 0,
                        Persisted = false,
                        Direction = TrendDirection.Up,
                        Adviced = false
                    };

                this._trend.Duration++;

                //log.debug('In uptrend since', this.trend.duration, 'candle(s)');

                if (this._trend.Duration >= 1/*settings.thresholds.persistence*/)
                    this._trend.Persisted = true;

                if (this._trend.Persisted && !this._trend.Adviced)
                {
                    this._trend.Adviced = true;
                    return Advice.Buy;
                }
                else return Advice.None;

            }
            else if (macdDiff < -0.025/* settings.thresholds.down*/)
            {

                // new trend detected
                if (this._trend.Direction != TrendDirection.Down)
                    // reset the state for the new trend
                    this._trend = new Trend
                    {
                        Duration = 0,
                        Persisted = false,
                        Direction = TrendDirection.Down,
                        Adviced = false
                    };

                this._trend.Duration++;

                //log.debug('In downtrend since', this.trend.duration, 'candle(s)');

                if (this._trend.Duration >= 1/*settings.thresholds.persistence*/)
                {
                    this._trend.Persisted = true;
                }

                if (this._trend.Persisted && !this._trend.Adviced)
                {
                    this._trend.Adviced = true;
                    return Advice.Sell;
                }
                else
                    return Advice.None;

            }
            else
            {
                return Advice.None;
            }

        }