Ejemplo n.º 1
0
 /// <inheritdoc />
 protected override ResponseObject <BacktestingCandle[]> GetCandles(TradingPair pair, int limit)
 {
     var client    = _communications.Client;
     var result    = new BacktestingCandle[limit];
     int chunkSize = Configuration.Instance.BinanceClientSettings.CandleRequestSize;
     var width     = Configuration.Instance.CandleWidth;
     var tasks     = new (int, Task <CallResult <BinanceKline[]> >)[(limit / chunkSize) + 1];
Ejemplo n.º 2
0
        public void LowestLowTwoCandles()
        {
            var input = new BacktestingCandle[]
            {
                new BacktestingCandle(
                    openTimestamp: 0L,
                    open: 10M,
                    close: 15M,
                    high: 20M,
                    low: 5,
                    volume: 100,
                    tradingPair: "EOSETH"),

                new BacktestingCandle(
                    openTimestamp: 0L,
                    open: 10M,
                    close: 12M,
                    high: 14M,
                    low: 3,
                    volume: 100,
                    tradingPair: "EOSETH"),
            };

            var result = _buildLowestLowBuffer(input, 1);

            Assert.Equal(2, result.Length);
            Assert.Equal(5M, result[0]);
            Assert.Equal(3M, result[1]);
        }
Ejemplo n.º 3
0
        public void HighestHighTwoCandlesTogetherSmaller()
        {
            var input = new BacktestingCandle[]
            {
                new BacktestingCandle(
                    openTimestamp: 0L,
                    open: 10M,
                    close: 15M,
                    high: 20M,
                    low: 5,
                    volume: 100,
                    tradingPair: "EOSETH"),

                new BacktestingCandle(
                    openTimestamp: 0L,
                    open: 10M,
                    close: 12M,
                    high: 12M,
                    low: 5,
                    volume: 100,
                    tradingPair: "EOSETH"),
            };

            var result = _buildHighestHighBuffer(input, 2);

            Assert.Equal(2, result.Length);
            Assert.Equal(20M, result[0]);
            Assert.Equal(20M, result[1]);
        }
Ejemplo n.º 4
0
        public void HighestHighHugeCase()
        {
            var random  = new Random();
            var candles = new BacktestingCandle[1451];

            for (int i = 0; i < candles.Length; i++)
            {
                var high   = (decimal)(random.NextDouble() * 30) + 1;
                var low    = Math.Min((decimal)(random.NextDouble() * 30) + 1, high);
                var open   = Math.Max(Math.Min((decimal)(random.NextDouble() * 30) + 1, high), low);
                var close  = Math.Max(Math.Min((decimal)(random.NextDouble() * 30) + 1, high), low);
                var volume = (decimal)(random.NextDouble() * 420);

                candles[i] = new BacktestingCandle(
                    openTimestamp: i * 60000,
                    open: open,
                    close: close,
                    high: high,
                    low: low,
                    volume: volume,
                    tradingPair: "EOSETH");
            }

            var result = _buildHighestHighBuffer(candles, 400);

            for (int i = 399; i < candles.Length; i++)
            {
                Assert.Equal(candles.Skip(i - 399).Take(400).Max(x => x.High), result[i]);
            }
        }
            protected override ResponseObject <BacktestingCandle[]> GetCandles(TradingPair pair, int limit)
            {
                var random = new Random("$pread$hare".GetHashCode(StringComparison.InvariantCulture));
                var result = new BacktestingCandle[limit];

                for (int i = 0; i < limit; i++)
                {
                    var high   = (decimal)(random.NextDouble() * 30) + 1;
                    var low    = Math.Min((decimal)(random.NextDouble() * 30) + 1, high);
                    var open   = Math.Max(Math.Min((decimal)(random.NextDouble() * 30) + 1, high), low);
                    var close  = Math.Max(Math.Min((decimal)(random.NextDouble() * 30) + 1, high), low);
                    var volume = (decimal)(random.NextDouble() * 420);

                    result[i] = new BacktestingCandle(
                        openTimestamp: i * 60000,
                        open: open,
                        close: close,
                        high: high,
                        low: low,
                        volume: volume,
                        tradingPair: "EOSETH");
                }

                return(new ResponseObject <BacktestingCandle[]>(result));
            }
Ejemplo n.º 6
0
        public void GetFilledOrderNullOrder()
        {
            var candle = new BacktestingCandle(0, 1, 1, 1, 1, 1, "EOSETH");
            var filled = GetFilledOrder(null, candle, 0);

            Assert.False(filled);
        }
Ejemplo n.º 7
0
        public void GetFilledBuyStoplossOrderUnMutated()
        {
            var order = new OrderUpdate(
                orderId: 9,
                tradeId: 8,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.StopLoss,
                createdTimestamp: 302,
                setPrice: 2.1M,
                side: OrderSide.Buy,
                pair: TradingPair.Parse("TRXETH"),
                setQuantity: 18.6M)
            {
                StopPrice = 1.9M,
            };

            var candle = new BacktestingCandle(0, 1, 1, 2, 1, 0, "EOSETH");

            GetFilledOrder(order, candle, 434424233);
            Assert.Equal(OrderStatus.Filled, order.Status);
            Assert.Equal(OrderTypes.StopLoss, order.OrderType);
            Assert.Equal(1.9M, order.AverageFilledPrice);
            Assert.Equal(1.9M, order.LastFillPrice);
            Assert.Equal(18.6M, order.FilledQuantity);
            Assert.Equal(18.6M, order.LastFillIncrement);
            Assert.Equal(434424233, order.FilledTimestamp);
        }
Ejemplo n.º 8
0
        public void GetFilledBuyLimitOrderUsesMax()
        {
            var order = new OrderUpdate(
                orderId: 0,
                tradeId: 0,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.Limit,
                createdTimestamp: 0,
                setPrice: 6.6M,
                side: OrderSide.Buy,
                pair: TradingPair.Parse("EOSETH"),
                setQuantity: 0);
            var candle = new BacktestingCandle(0, 2, 5, 6.6M, 1.8M, 0, "EOSETH");
            var filled = GetFilledOrder(order, candle, 0);

            Assert.True(filled);
        }
Ejemplo n.º 9
0
        public void GetFilledSellLimitOrderIsNotFilled()
        {
            var order = new OrderUpdate(
                orderId: 0,
                tradeId: 0,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.Limit,
                createdTimestamp: 0,
                setPrice: 3.4M,
                side: OrderSide.Sell,
                pair: TradingPair.Parse("EOSETH"),
                setQuantity: 0);
            var candle = new BacktestingCandle(0, 1, 2, 3.2M, 0.8M, 0, "EOSETH");
            var filled = GetFilledOrder(order, candle, 0);

            Assert.False(filled);
        }
Ejemplo n.º 10
0
        public void GetFilledOrderMarketThrows()
        {
            var order  = GetSomeOrder(OrderTypes.Market);
            var candle = new BacktestingCandle(1, 1, 1, 1, 1, 1, "EOSETH");

            Assert.Throws <UnexpectedOrderTypeException>(() =>
            {
                try
                {
                    GetFilledOrder(order, candle, 0);
                }
                catch (TargetInvocationException e)
                {
                    throw e.InnerException;
                }
            });
        }
Ejemplo n.º 11
0
        public void HighestHighOneCandle()
        {
            var input = new BacktestingCandle[]
            {
                new BacktestingCandle(
                    openTimestamp: 0L,
                    open: 10M,
                    close: 15M,
                    high: 20M,
                    low: 5,
                    volume: 100,
                    tradingPair: "EOSETH"),
            };

            var result = _buildHighestHighBuffer(input, 1);

            Assert.Single(result);
            Assert.Equal(20M, result[0]);
        }
Ejemplo n.º 12
0
        private static bool GetFilledLimitOrder(OrderUpdate order, BacktestingCandle currentCandle, long currentTime)
        {
            bool filled = order.Side == OrderSide.Buy
                ? currentCandle.Low <= order.SetPrice
                : currentCandle.High >= order.SetPrice;

            if (filled)
            {
                order.StopPrice          = order.StopPrice;
                order.FilledQuantity     = order.SetQuantity;
                order.AverageFilledPrice = order.SetPrice;
                order.LastFillIncrement  = order.SetQuantity;
                order.LastFillPrice      = order.SetPrice;
                order.Status             = OrderUpdate.OrderStatus.Filled;
                order.FilledTimestamp    = currentTime;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 13
0
        public void GetFilledSellStoplossOrderIsNotFilled()
        {
            var order = new OrderUpdate(
                orderId: 0,
                tradeId: 0,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.StopLoss,
                createdTimestamp: 0,
                setPrice: 0M,
                side: OrderSide.Sell,
                pair: TradingPair.Parse("EOSETH"),
                setQuantity: 0)
            {
                StopPrice = 8.5M,
            };
            var candle = new BacktestingCandle(0, 10.1M, 11.2M, 12.4M, 10.1M, 0, "EOSETH");
            var filled = GetFilledOrder(order, candle, 0);

            Assert.False(filled);
        }
Ejemplo n.º 14
0
        public void GetFilledBuyStoplossOrderIsFilled()
        {
            var order = new OrderUpdate(
                orderId: 0,
                tradeId: 0,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.StopLoss,
                createdTimestamp: 0,
                setPrice: 0M,
                side: OrderSide.Buy,
                pair: TradingPair.Parse("EOSETH"),
                setQuantity: 0)
            {
                StopPrice = 3.2M,
            };
            var candle = new BacktestingCandle(0, 3, 5, 6.6M, 3M, 0, "EOSETH");
            var filled = GetFilledOrder(order, candle, 0);

            Assert.True(filled);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Returns a bool indicating whether or not the order was filled, and transforms the order into a filled state if so.
        /// </summary>
        /// <param name="order">The order to check as filled.</param>
        /// <param name="currentCandle">The candle to check the order against.</param>
        /// <param name="currentTime">The current time (will be used as time of fill).</param>
        /// <returns>Whether the order was filled.</returns>
        /// <exception cref="UnexpectedOrderTypeException">The order type is not supported by the method.</exception>
        private static bool EvaluateFilledOrder(OrderUpdate order, BacktestingCandle currentCandle, long currentTime)
        {
            Guard.Argument(currentCandle).NotNull();
            if (order == null)
            {
                return(false);
            }

            switch (order.OrderType)
            {
            case OrderUpdate.OrderTypes.Limit:
                return(GetFilledLimitOrder(order, currentCandle, currentTime));

            case OrderUpdate.OrderTypes.StopLoss:
                return(GetFilledStoplossOrder(order, currentCandle, currentTime));

            default:
                throw new UnexpectedOrderTypeException(
                          $"Backtest watchlist should not contain order of type {order.OrderType}");
            }
        }
Ejemplo n.º 16
0
        public void GetFilledSellStoplossOrderUsesMin()
        {
            var order = new OrderUpdate(
                orderId: 0,
                tradeId: 0,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.StopLoss,
                createdTimestamp: 0,
                setPrice: 0,
                side: OrderSide.Sell,
                pair: TradingPair.Parse("EOSETH"),
                setQuantity: 0)
            {
                StopPrice = 3.4M,
            };

            var candle = new BacktestingCandle(0, 5, 4, 6.6M, 3M, 0, "EOSETH");
            var filled = GetFilledOrder(order, candle, 0);

            Assert.True(filled);
            Assert.Equal(3.4M, order.AverageFilledPrice);
        }
Ejemplo n.º 17
0
        public void GetFilledBuyLimitOrderUnMutated()
        {
            var order = new OrderUpdate(
                orderId: 9,
                tradeId: 8,
                orderStatus: OrderUpdate.OrderStatus.New,
                orderType: OrderTypes.Limit,
                createdTimestamp: 302,
                setPrice: 2.1M,
                side: OrderSide.Buy,
                pair: TradingPair.Parse("TRXETH"),
                setQuantity: 15.6M);
            var candle = new BacktestingCandle(0, 5, 6, 100M, 0M, 0, "EOSETH");

            GetFilledOrder(order, candle, 2394923);
            Assert.Equal(OrderStatus.Filled, order.Status);
            Assert.Equal(OrderTypes.Limit, order.OrderType);
            Assert.Equal(2.1M, order.AverageFilledPrice);
            Assert.Equal(2.1M, order.LastFillPrice);
            Assert.Equal(15.6M, order.FilledQuantity);
            Assert.Equal(15.6M, order.LastFillIncrement);
            Assert.Equal(2394923, order.FilledTimestamp);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Compress a list of candles given a certain ratio.
        /// </summary>
        /// <param name="input">The collection of candles to compress.</param>
        /// <param name="compressionRatio">The reducing ratio. (e.g. 2 -> 10 candles become 5 candles.</param>
        /// <returns>An array of candles.</returns>
        public static BacktestingCandle[] CompressCandles(
            BacktestingCandle[] input,
            int compressionRatio)
        {
            Guard.Argument(compressionRatio)
            .NotZero()
            .NotNegative();

            Guard.Argument(input)
            .NotNull(nameof(input))
            .NotEmpty()
            .Require <ArgumentException>(
                x => x.Length % compressionRatio == 0,
                x => $"{nameof(x)} has length {x.Length} which is not divisible by {nameof(compressionRatio)}, namely {compressionRatio}");

            // number of candles used to create new candles
            var result = new BacktestingCandle[input.Length / compressionRatio];

            Parallel.For(0, result.Length, index =>
            {
                var subset = input.Skip(index * compressionRatio).Take(compressionRatio).ToArray();
                var first  = subset[0];
                var last   = subset[subset.Length - 1];

                result[index] = new BacktestingCandle(
                    openTimestamp: first.OpenTimestamp,
                    open: first.Open,
                    close: last.Close,
                    high: subset.Max(x => x.High),
                    low: subset.Min(x => x.Low),
                    volume: subset.Sum(x => x.Volume),
                    tradingPair: first.TradingPair);
            });

            return(result);
        }