예제 #1
0
        /// <summary>
        /// Genrate output based on input data
        /// </summary>
        protected virtual IPointModel Parse(dynamic input)
        {
            var props = input.Split(" ");

            long.TryParse(props[0], out long dateTime);

            double.TryParse(props[1], out double bid);
            double.TryParse(props[2], out double bidSize);
            double.TryParse(props[3], out double ask);
            double.TryParse(props[4], out double askSize);

            var response = new PointModel
            {
                Time    = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(dateTime),
                Ask     = ask,
                Bid     = bid,
                Last    = ask,
                AskSize = askSize,
                BidSize = bidSize
            };

            if (ConversionManager.Compare(askSize, 0))
            {
                response.Last = bid;
            }

            return(response);
        }
예제 #2
0
        /// <summary>
        /// Process incoming quotes
        /// </summary>
        /// <param name="input"></param>
        protected void OnInputQuote(InputPointModel input)
        {
            var dateAsk     = input.AskDate;
            var dateBid     = input.BidDate;
            var currentAsk  = input.Ask;
            var currentBid  = input.Bid;
            var previousAsk = _point?.Ask ?? currentAsk;
            var previousBid = _point?.Bid ?? currentBid;
            var symbol      = input.Symbol;

            var point = new PointModel
            {
                Ask        = currentAsk,
                Bid        = currentBid,
                Bar        = new PointBarModel(),
                Instrument = Account.Instruments[symbol],
                AskSize    = input.AskSize,
                BidSize    = input.BidSize,
                Time       = DateTimeOffset.FromUnixTimeMilliseconds(Math.Max(dateAsk.Value, dateBid.Value)).DateTime,
                Last       = ConversionManager.Compare(currentBid, previousBid) ? currentAsk : currentBid
            };

            _point = point;

            UpdatePointProps(point);
        }
예제 #3
0
        /// <summary>
        /// Process incoming quotes
        /// </summary>
        /// <param name="input"></param>
        protected void OnInputQuote(dynamic input)
        {
            var dateAsk     = ConversionManager.To <long>(input.askdate);
            var dateBid     = ConversionManager.To <long>(input.biddate);
            var currentAsk  = ConversionManager.To <double>(input.ask);
            var currentBid  = ConversionManager.To <double>(input.bid);
            var previousAsk = _point?.Ask ?? currentAsk;
            var previousBid = _point?.Bid ?? currentBid;
            var symbol      = $"{ input.symbol }";

            var point = new PointModel
            {
                Ask        = currentAsk,
                Bid        = currentBid,
                Bar        = new PointBarModel(),
                Instrument = Account.Instruments[symbol],
                AskSize    = ConversionManager.To <double>(input.asksz),
                BidSize    = ConversionManager.To <double>(input.bidsz),
                Time       = DateTimeOffset.FromUnixTimeMilliseconds(Math.Max(dateAsk, dateBid)).DateTime,
                Last       = ConversionManager.Compare(currentBid, previousBid) ? currentAsk : currentBid
            };

            _point = point;

            UpdatePointProps(point);
        }
예제 #4
0
        /// <summary>
        /// Calculate single value
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public override RelativeStrengthIndicator Calculate(IIndexCollection <IPointModel> collection)
        {
            var currentPoint = collection.ElementAtOrDefault(collection.Count - 1);

            if (currentPoint == null)
            {
                return(this);
            }

            var positives = new List <double>(Interval);
            var negatives = new List <double>(Interval);

            for (var i = 1; i <= Interval; i++)
            {
                var nextPrice     = collection.ElementAtOrDefault(collection.Count - i);
                var previousPrice = collection.ElementAtOrDefault(collection.Count - i - 1);

                if (nextPrice != null && previousPrice != null)
                {
                    positives.Add(Math.Max(nextPrice.Bar.Close.Value - previousPrice.Bar.Close.Value, 0.0));
                    negatives.Add(Math.Max(previousPrice.Bar.Close.Value - nextPrice.Bar.Close.Value, 0.0));
                }
            }

            var averagePositive    = CalculationManager.SimpleAverage(positives, positives.Count - 1, Interval);
            var averageNegative    = CalculationManager.SimpleAverage(negatives, negatives.Count - 1, Interval);
            var average            = ConversionManager.Compare(averageNegative, 0) ? 1.0 : averagePositive / averageNegative;
            var nextValue          = 100.0 - 100.0 / (1.0 + average);
            var nextIndicatorPoint = new PointModel
            {
                Time      = currentPoint.Time,
                TimeFrame = currentPoint.TimeFrame,
                Last      = nextValue,
                Bar       = new PointBarModel
                {
                    Close = nextValue
                }
            };

            var previousIndicatorPoint = Values.ElementAtOrDefault(collection.Count - 1);

            if (previousIndicatorPoint == null)
            {
                Values.Add(nextIndicatorPoint);
            }

            Values[collection.Count - 1] = nextIndicatorPoint;

            currentPoint.Series[Name]           = currentPoint.Series.TryGetValue(Name, out IPointModel seriesItem) ? seriesItem : new RelativeStrengthIndicator();
            currentPoint.Series[Name].Bar.Close = currentPoint.Series[Name].Last = nextIndicatorPoint.Bar.Close;
            currentPoint.Series[Name].Time      = currentPoint.Time;
            currentPoint.Series[Name].ChartData = ChartData;

            Last = Bar.Close = currentPoint.Series[Name].Bar.Close;

            return(this);
        }
예제 #5
0
        /// <summary>
        /// Create position when there is a position with the same transaction type
        /// </summary>
        /// <param name="nextOrder"></param>
        /// <param name="previousPosition"></param>
        /// <returns></returns>
        protected virtual ITransactionPositionModel DecreasePosition(ITransactionOrderModel nextOrder, ITransactionPositionModel previousPosition)
        {
            if (previousPosition == null)
            {
                return(null);
            }

            var isSameBuy  = Equals(previousPosition.Side, OrderSideEnum.Buy) && Equals(nextOrder.Side, OrderSideEnum.Buy);
            var isSameSell = Equals(previousPosition.Side, OrderSideEnum.Sell) && Equals(nextOrder.Side, OrderSideEnum.Sell);

            if (isSameBuy || isSameSell)
            {
                return(null);
            }

            var openPrices = GetOpenPrices(nextOrder);
            var pointModel = nextOrder.Instrument.PointGroups.LastOrDefault();

            nextOrder.Time   = pointModel.Time;
            nextOrder.Price  = openPrices.Last().Price;
            nextOrder.Status = OrderStatusEnum.Filled;

            var nextPosition = UpdatePositionProps(new TransactionPositionModel(), nextOrder);

            nextPosition.Time       = pointModel.Time;
            nextPosition.OpenPrices = openPrices;
            nextPosition.Price      = nextPosition.OpenPrice = nextOrder.Price;
            nextPosition.Size       = Math.Abs(nextPosition.Size.Value - previousPosition.Size.Value);

            previousPosition.CloseTime      = nextPosition.Time;
            previousPosition.ClosePrice     = nextPosition.OpenPrice;
            previousPosition.GainLoss       = previousPosition.GainLossEstimate;
            previousPosition.GainLossPoints = previousPosition.GainLossPointsEstimate;

            Account.Balance += previousPosition.GainLoss;
            Account.ActiveOrders.Remove(nextOrder);
            Account.ActivePositions.Remove(previousPosition);

            DeleteOrders(previousPosition.Orders.ToArray());

            Account.Orders.Add(nextOrder);
            Account.Positions.Add(previousPosition);

            if (ConversionManager.Compare(nextPosition.Size, 0.0) == false)
            {
                Account.ActivePositions.Add(nextPosition);
            }

            return(nextPosition);
        }
예제 #6
0
        /// <summary>
        /// Calculate single value
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public override MovingAverageIndicator Calculate(IIndexCollection <IPointModel> collection)
        {
            var currentPoint = collection.ElementAtOrDefault(collection.Count - 1);

            if (currentPoint == null)
            {
                return(this);
            }

            var pointPrice = currentPoint.Bar.Close;

            switch (Mode)
            {
            case MovingAverageEnum.Bid: pointPrice = currentPoint.Bid; break;

            case MovingAverageEnum.Ask: pointPrice = currentPoint.Ask; break;
            }

            var nextIndicatorPoint = new PointModel
            {
                Last      = pointPrice,
                Time      = currentPoint.Time,
                TimeFrame = currentPoint.TimeFrame,
                Bar       = new PointBarModel
                {
                    Close = pointPrice
                }
            };

            var previousIndicatorPoint = Values.ElementAtOrDefault(collection.Count - 1);

            if (previousIndicatorPoint == null)
            {
                Values.Add(nextIndicatorPoint);
            }

            Values[collection.Count - 1] = nextIndicatorPoint;

            var average = CalculationManager.LinearWeightAverage(Values.Select(o => o.Bar.Close.Value), Values.Count - 1, Interval);

            currentPoint.Series[Name]           = currentPoint.Series.TryGetValue(Name, out IPointModel seriesItem) ? seriesItem : new MovingAverageIndicator();
            currentPoint.Series[Name].Bar.Close = currentPoint.Series[Name].Last = ConversionManager.Compare(average, 0) ? nextIndicatorPoint.Bar.Close : average;
            currentPoint.Series[Name].Time      = currentPoint.Time;
            currentPoint.Series[Name].ChartData = ChartData;

            Last = Bar.Close = currentPoint.Series[Name].Bar.Close;

            return(this);
        }
예제 #7
0
        /// <summary>
        /// Calculate indicator value
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public override ScaleIndicator Calculate(IIndexCollection <IPointModel> collection)
        {
            var currentPoint = collection.ElementAtOrDefault(collection.Count - 1);

            if (currentPoint == null || currentPoint.Series == null)
            {
                return(this);
            }

            var pointValue = currentPoint.Bar.Close ?? 0.0;

            _min = _min == null ? pointValue : Math.Min(_min.Value, pointValue);
            _max = _max == null ? pointValue : Math.Max(_max.Value, pointValue);

            var nextValue = ConversionManager.Compare(_min, _max) ? 0.0 : Min + (pointValue - _min.Value) * (Max - Min) / (_max.Value - _min.Value);

            var nextIndicatorPoint = new PointModel
            {
                Time      = currentPoint.Time,
                TimeFrame = currentPoint.TimeFrame,
                Last      = nextValue,
                Bar       = new PointBarModel
                {
                    Close = nextValue
                }
            };

            var previousIndicatorPoint = Values.ElementAtOrDefault(collection.Count - 1);

            if (previousIndicatorPoint == null)
            {
                Values.Add(nextIndicatorPoint);
            }

            Values[collection.Count - 1] = nextIndicatorPoint;

            currentPoint.Series[Name]           = currentPoint.Series.TryGetValue(Name, out IPointModel seriesItem) ? seriesItem : new ScaleIndicator();
            currentPoint.Series[Name].Bar.Close = currentPoint.Series[Name].Last = CalculationManager.LinearWeightAverage(Values.Select(o => o.Bar.Close.Value), Values.Count - 1, Interval);
            currentPoint.Series[Name].Time      = currentPoint.Time;
            currentPoint.Series[Name].ChartData = ChartData;

            Last = Bar.Close = currentPoint.Series[Name].Bar.Close;

            return(this);
        }
예제 #8
0
        /// <summary>
        /// Define open price based on order
        /// </summary>
        /// <param name="nextOrder"></param>
        protected virtual IList <ITransactionOrderModel> GetOpenPrices(ITransactionOrderModel nextOrder)
        {
            var openPrice  = nextOrder.Price;
            var pointModel = nextOrder.Instrument.PointGroups.LastOrDefault();

            if (ConversionManager.Compare(openPrice ?? 0.0, 0.0))
            {
                openPrice = Equals(nextOrder.Side, OrderSideEnum.Buy) ? pointModel.Ask : pointModel.Bid;
            }

            return(new List <ITransactionOrderModel>
            {
                new TransactionOrderModel
                {
                    Price = openPrice,
                    Size = nextOrder.Size,
                    Time = pointModel.Time
                }
            });
        }
예제 #9
0
        public void ShouldCalculateKestnerRatio()
        {
            var inputs = new List <double> {
                2.0, 5.0, 15.0, 35.0, 20.0, 55.0, 150.0
            };
            var logs = inputs
                       .Select(o => Math.Log(o))
                       .Where(o => double.IsInfinity(o) == false && ConversionManager.Compare(o, 0) == false)
                       .ToList();

            var count      = logs.Count;
            var deviation  = 0.0;
            var regression = new double[count];
            var slope      = Math.Log(inputs.Last()) / count;

            for (var i = 0; i < count; i++)
            {
                var v   = inputs.ElementAtOrDefault(i);
                var log = Math.Log(v);

                if (double.IsNaN(log) == false)
                {
                    regression[i] = regression.ElementAtOrDefault(i - 1) + slope;
                    deviation    += Math.Pow(regression[i] - log, 2);
                }
            }

            var error       = Math.Sqrt(deviation / count) / Math.Sqrt(count);
            var expectation = slope / (error * count);
            var deals       = inputs.Select((o, i) => new InputData {
                Value = o
            });
            var kestnerRatio = new KestnerRatio
            {
                Values = deals
            };

            var ratio = kestnerRatio.Calculate();

            Assert.Equal(expectation, ratio, 2);
        }
예제 #10
0
        /// <summary>
        /// Process incoming quotes
        /// </summary>
        /// <param name="input"></param>
        protected void OnInputData(InputPointModel input)
        {
            var currentAsk  = input.Ask;
            var currentBid  = input.Bid;
            var previousAsk = _point?.Ask ?? currentAsk;
            var previousBid = _point?.Bid ?? currentBid;
            var instrument  = $"{ input.Instrument }";

            var point = new PointModel
            {
                Ask        = currentAsk,
                Bid        = currentBid,
                Time       = input.Time,
                Bar        = new PointBarModel(),
                Instrument = Account.Instruments[instrument],
                Last       = ConversionManager.Compare(currentBid, previousBid) ? currentAsk : currentBid
            };

            if (input.Asks.Any())
            {
                var edge = input.Asks.Min(o => new { o.Price, o.Size });

                point.Ask     = Math.Min(point.Ask.Value, edge.Price.Value);
                point.AskSize = edge.Size;
            }

            if (input.Bids.Any())
            {
                var edge = input.Bids.Max(o => new { o.Price, o.Size });

                point.Bid     = Math.Max(point.Bid.Value, edge.Price.Value);
                point.BidSize = edge.Size;
            }

            _point = point;

            UpdatePointProps(point);
        }
예제 #11
0
        /// <summary>
        /// Convert abstract order to a real one
        /// </summary>
        /// <param name="internalOrder"></param>
        /// <param name="orderClass"></param>
        /// <returns></returns>
        //protected async Task<ITransactionOrderModel> CreateOrder(ITransactionOrderModel internalOrder, dynamic orderClass = null)
        //{
        //  var size = ConversionManager.To<long>(internalOrder.Size);
        //  var price = ConversionManager.To<decimal>(internalOrder.Price);
        //  var span = MapInput.GetTimeSpan(internalOrder.TimeSpan.Value).Value;
        //  var orderSide = MapInput.GetOrderSide(internalOrder.Side.Value).Value;
        //  var orderType = MapInput.GetOrderType(internalOrder.Type.Value).Value;
        //  var activationPrice = ConversionManager.To<decimal>(internalOrder.ActivationPrice);
        //  var orderQuery = new NewOrderRequest(internalOrder.Instrument.Name, size, orderSide, orderType, span)
        //  {
        //    ClientOrderId = internalOrder.Id
        //  };

        //  if (orderClass != null)
        //  {
        //    orderQuery.OrderClass = orderClass;
        //  }

        //  switch (orderType)
        //  {
        //    case OrderType.Stop: orderQuery.StopPrice = price; break;
        //    case OrderType.Limit: orderQuery.LimitPrice = price; break;
        //    case OrderType.StopLimit: orderQuery.StopPrice = activationPrice; orderQuery.LimitPrice = price; break;
        //  }

        //  await _executionClient.PostOrderAsync(orderQuery);

        //  foreach (var childData in internalOrder.Orders)
        //  {
        //    await CreateOrder(childData);
        //  }

        //  return internalOrder;
        //}

        /// <summary>
        /// Load account data
        /// </summary>
        /// <returns></returns>
        //protected async Task GetAccountData()
        //{
        //  var account = await _executionClient.GetAccountAsync();

        //  Account.Leverage = account.Multiplier;
        //  Account.Currency = account.Currency.ToUpper();
        //  Account.Balance = ConversionManager.To<double>(account.Equity);
        //  Account.InitialBalance = ConversionManager.To<double>(account.LastEquity);
        //}

        /// <summary>
        /// Load orders
        /// </summary>
        /// <returns></returns>
        //protected async Task GetOrders()
        //{
        //  var orders = await _executionClient.ListOrdersAsync(new ListOrdersRequest
        //  {
        //    LimitOrderNumber = 500,
        //    OrderListSorting = SortDirection.Descending,
        //    OrderStatusFilter = OrderStatusFilter.Closed
        //  });

        //  foreach (var o in orders)
        //  {
        //    var order = new TransactionOrderModel();

        //    Account.Instruments.TryGetValue(o.Symbol, out IInstrumentModel instrument);

        //    order.Size = o.Quantity;
        //    order.Time = o.CreatedAtUtc;
        //    order.Id = o.OrderId.ToString();
        //    order.Type = MapOutput.GetOrderType(o.OrderType);
        //    order.Side = MapOutput.GetOrderSide(o.OrderSide);
        //    order.Status = MapOutput.GetOrderStatus(o.OrderStatus);
        //    order.TimeSpan = MapOutput.GetTimeSpan(o.TimeInForce);
        //    order.Price = ConversionManager.To<double>(o.AverageFillPrice ?? o.StopPrice ?? o.LimitPrice);
        //    order.Instrument = instrument ?? new InstrumentModel
        //    {
        //      Name = o.Symbol
        //    };

        //    Account.Orders.Add(order);
        //  }
        //}

        /// <summary>
        /// Load active orders
        /// </summary>
        /// <returns></returns>
        //protected async Task GetActiveOrders()
        //{
        //  var orders = await _executionClient.ListOrdersAsync(new ListOrdersRequest
        //  {
        //    LimitOrderNumber = 500,
        //    OrderListSorting = SortDirection.Descending,
        //    OrderStatusFilter = OrderStatusFilter.Open
        //  });

        //  foreach (var o in orders)
        //  {
        //    var order = new TransactionOrderModel();

        //    Account.Instruments.TryGetValue(o.Symbol, out IInstrumentModel instrument);

        //    order.Size = o.Quantity;
        //    order.Time = o.CreatedAtUtc;
        //    order.Id = o.OrderId.ToString();
        //    order.Type = MapOutput.GetOrderType(o.OrderType);
        //    order.Side = MapOutput.GetOrderSide(o.OrderSide);
        //    order.Status = MapOutput.GetOrderStatus(o.OrderStatus);
        //    order.TimeSpan = MapOutput.GetTimeSpan(o.TimeInForce);
        //    order.Price = ConversionManager.To<double>(o.AverageFillPrice ?? o.StopPrice ?? o.LimitPrice);
        //    order.Instrument = instrument ?? new InstrumentModel
        //    {
        //      Name = o.Symbol
        //    };

        //    Account.ActiveOrders.Add(order);
        //  }
        //}

        /// <summary>
        /// Load active positions
        /// </summary>
        /// <returns></returns>
        //protected async Task GetActivePositions()
        //{
        //  var positions = await _executionClient.ListPositionsAsync();

        //  foreach (var o in positions)
        //  {
        //    var position = new TransactionPositionModel();

        //    Account.Instruments.TryGetValue(o.Symbol, out IInstrumentModel instrument);

        //    position.Size = o.Quantity;
        //    position.Time = DateTime.MinValue;
        //    position.Type = OrderTypeEnum.Market;
        //    position.Side = MapOutput.GetPositionSide(o.Side);
        //    position.OpenPrice = ConversionManager.To<double>(o.AverageEntryPrice);
        //    position.ClosePrice = ConversionManager.To<double>(o.AssetCurrentPrice);
        //    position.GainLoss = ConversionManager.To<double>(o.UnrealizedProfitLoss);
        //    position.GainLossPoints = ConversionManager.To<double>((o.AssetCurrentPrice - o.AverageEntryPrice)) * MapOutput.GetDirection(position.Side.Value);
        //    position.Instrument = instrument ?? new InstrumentModel
        //    {
        //      Name = o.Symbol
        //    };

        //    position.OpenPrices = new List<ITransactionOrderModel>
        //    {
        //      new TransactionOrderModel
        //      {
        //        Price = position.OpenPrice,
        //        Instrument = position.Instrument
        //      }
        //    };

        //    Account.ActivePositions.Add(position);
        //  }
        //}

        /// <summary>
        /// Process incoming quotes
        /// </summary>
        /// <param name="input"></param>
        protected void OnInputQuote(dynamic input)
        {
            var currentAsk  = ConversionManager.To <double>(input.P);
            var currentBid  = ConversionManager.To <double>(input.p);
            var previousAsk = _point?.Ask ?? currentAsk;
            var previousBid = _point?.Bid ?? currentBid;
            var symbol      = $"{ input.T }";

            var point = new PointModel
            {
                Ask        = currentAsk,
                Bid        = currentBid,
                Bar        = new PointBarModel(),
                Instrument = Account.Instruments[symbol],
                AskSize    = ConversionManager.To <double>(input.S),
                BidSize    = ConversionManager.To <double>(input.s),
                Time       = _unixTime.AddTicks(ConversionManager.To <long>(input.t) / 100),
                Last       = ConversionManager.Compare(currentBid, previousBid) ? currentAsk : currentBid
            };

            _point = point;

            UpdatePointProps(point);
        }