Example #1
0
            public PartiallyClosedOrdersAdjuster(List <IOrderInfo> live, List <IOrderInfo> history)
            {
                _live      = live;
                _history   = history;
                _toResolve = new List <IOrderInfo>();
                _history.Sort((o1, o2) =>
                {
                    try
                    {
                        var cmp = o1.GetCloseTime().CompareTo(o2.GetCloseTime());
                        if (cmp == 0)
                        {
                            cmp = string.Compare(o1.GetSymbol(), o2.GetSymbol(), StringComparison.Ordinal);
                            if (cmp == 0)
                            {
                                cmp = o1.GetTradeOperation() - o2.GetTradeOperation();
                                if (cmp == 0)
                                {
                                    var d = o1.GetOpenPrice() - o2.GetOpenPrice();
                                    cmp   = d == 0 ? 0 : (d > 0 ? 1 : -1);
                                    if (cmp == 0)
                                    {
                                        var t = o1.GetOpenTime() - o2.GetOpenTime();
                                        cmp   = t.TotalSeconds == 0 ? 0 : (t.TotalSeconds > 0 ? 1 : -1);
                                        if (cmp == 0)
                                        {
                                            cmp = o1.GetMagic() - o2.GetMagic();
                                            if (cmp == 0)
                                            {
                                                var t1 = o1.Ticket();
                                                var t2 = o2.Ticket();
                                                cmp    = t1 > t2 ? -1 : (t1 < t2 ? 1 : 0); // reverse order for stack
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        return(cmp);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        return(0);
                    }
                });
                _live.Sort((o1, o2) => o1.Ticket() > o2.Ticket() ? 1 : -1);
                //
                var notBuySellOrders = new List <IOrderInfo>();

                _orders    = _live.ToDictionary(info => info.Ticket());
                _buySide   = new List <Stack <IOrderInfo> >();
                _sellSide  = new List <Stack <IOrderInfo> >();
                _buyAtTop  = new Dictionary <long, bool>();
                _sellAtTop = new Dictionary <long, bool>();
                _hedgedBy  = new Dictionary <long, long>();
                _closedBy  = new Dictionary <long, long>();
                OComparator lastOrderCmpInfo = null;
                var         closeHedgeBy     = @"close hedge by #";

                foreach (var o in history)
                {
                    _orders[o.Ticket()] = o;
                    var tradeOperation = o.GetTradeOperation();
                    if (tradeOperation != TradeOperation.OP_BUY && tradeOperation != TradeOperation.OP_SELL)
                    {
                        notBuySellOrders.Add(o);
                        continue;
                    }
                    //
                    if (o.GetComment().StartsWith(closeHedgeBy))
                    {
                        long t;
                        if (long.TryParse(o.GetComment().Substring(closeHedgeBy.Length), out t))
                        {
                            _hedgedBy[o.Ticket()] = t;
                            _closedBy[t]          = o.Ticket();
                        }
                        else
                        {
                            Logger.Warn($"Not expected, not numeric ticket in comment: {o.GetComment()}");
                        }
                    }
                    //
                    var side = tradeOperation == TradeOperation.OP_BUY ? _buySide : _sellSide;
                    var top  = tradeOperation == TradeOperation.OP_BUY ? _buyAtTop : _sellAtTop;
                    //
                    if (lastOrderCmpInfo == null || !lastOrderCmpInfo.IsSameOrder(o))
                    {
                        lastOrderCmpInfo = new OComparator(o);
                        var stack = new Stack <IOrderInfo>();
                        stack.Push(o);
                        side.Add(stack);
                    }
                    else
                    {
                        var stack = side[side.Count - 1];
                        top.Remove(stack.Peek().Ticket());
                        stack.Push(o);
                    }
                    top[o.Ticket()] = true;
                }
                //
                history.Clear();//rebuilding historical orders
                history.AddRange(notBuySellOrders);
            }
Example #2
0
            private bool CheckHedges(Stack <IOrderInfo> bStack)
            {
                Stack <IOrderInfo> cbStack  = null;
                Stack <IOrderInfo> hdgStack = null;
                long tmpTicket;

                if (_closedBy.TryGetValue(bStack.Peek().Ticket(), out tmpTicket))
                {
                    cbStack = bStack;
                    if (_sellAtTop.ContainsKey(tmpTicket))
                    {
                        hdgStack = _sellSide.FirstOrDefault(sellStack => sellStack.Peek().Ticket() == tmpTicket);
                    }
                }
                if (_hedgedBy.TryGetValue(bStack.Peek().Ticket(), out tmpTicket))
                {
                    hdgStack = bStack;
                    if (_sellAtTop.ContainsKey(tmpTicket))
                    {
                        cbStack = _sellSide.FirstOrDefault(sellStack => sellStack.Peek().Ticket() == tmpTicket);
                    }
                }
                if (cbStack != null && hdgStack != null)
                {
                    var cbOrder  = cbStack.Pop();
                    var hdgOrder = hdgStack.Pop();
                    //
                    _history.Add(hdgOrder);
                    _history.Add(cbOrder);
                    //
                    IOrderInfo cbNext  = null;
                    IOrderInfo hdgNext = null;
                    //
                    Dictionary <long, bool> cbTop  = cbOrder.GetTradeOperation() == TradeOperation.OP_BUY ? _buyAtTop : _sellAtTop;
                    Dictionary <long, bool> hdgTop = hdgOrder.GetTradeOperation() == TradeOperation.OP_BUY ? _buyAtTop : _sellAtTop;
                    cbTop.Remove(cbOrder.Ticket());
                    hdgTop.Remove(hdgOrder.Ticket());
                    if (cbStack.Count > 0)
                    {
                        cbTop[(cbNext = cbStack.Peek()).Ticket()] = true;
                    }
                    if (hdgStack.Count > 0)
                    {
                        hdgTop[(hdgNext = hdgStack.Peek()).Ticket()] = true;
                    }
                    //
                    cbOrder.SetClosedBy(hdgOrder);
                    if (cbNext == null && hdgNext == null)
                    {
                        //check live orders for next
                        var cbC  = new OComparator(cbOrder);
                        var hdgC = new OComparator(hdgOrder);
                        cbNext =
                            _live.FirstOrDefault(
                                order => order.Ticket() > cbOrder.Ticket() && cbC.IsSameLiveOrder(order));
                        hdgNext =
                            _live.FirstOrDefault(
                                order => order.Ticket() > hdgOrder.Ticket() && hdgC.IsSameLiveOrder(order));
                    }
                    var next = cbNext == null
                        ? hdgNext
                        : (hdgNext == null
                            ? cbNext
                            : (cbNext.Ticket() > hdgNext.Ticket() ? hdgNext : cbNext)); // use minimal ticket number for next order
                    if (next != null)
                    {
                        if (ReferenceEquals(next, cbNext))
                        {
                            cbOrder.SetNext(next);
                        }
                        if (ReferenceEquals(next, hdgNext))
                        {
                            hdgOrder.SetNext(next);
                        }
                    }
                    //
                    // remove empty stack from a side
                    if (cbStack.Count == 0)
                    {
                        (cbOrder.GetTradeOperation() == TradeOperation.OP_BUY ? _buySide : _sellSide).Remove(cbStack);
                    }
                    if (hdgStack.Count == 0)
                    {
                        (hdgOrder.GetTradeOperation() == TradeOperation.OP_BUY ? _buySide : _sellSide).Remove(hdgStack);
                    }
                    //
                    return(true);
                }
                return(false);
            }