// отзыв заявок по времени и отступу /// <summary> /// слежение за выставленными и ещё не исполненными ордерами /// </summary> void WatcherOpenPosition() { while (true) { Thread.Sleep(1000); // этот метод создан для того, чтобы инициализировать закрытие // не полностью открытых ордеров в конце периода if (StartProgram == StartProgram.IsTester) { // если тестируем return; } Thread.Sleep(1000); try { List <Position> positions = _tab.PositionsOpenAll; if (positions == null || positions.Count == 0) { continue; } // смотрим первый выход - 3 секунды List <Order> myOrderToFirstClose = new List <Order>(); for (int i = 0; i < positions.Count; i++) { if (positions[i].OpenOrders.Count == 1 && positions[i].OpenOrders[0].State == OrderStateType.Activ && positions[i].Comment != "Second") { myOrderToFirstClose.Add(positions[i].OpenOrders[positions[i].OpenOrders.Count - 1]); } if (positions[i].CloseOrders != null && positions[i].CloseOrders.Count == 1 && positions[i].CloseOrders[positions[i].CloseOrders.Count - 1].State == OrderStateType.Activ) { myOrderToFirstClose.Add(positions[i].CloseOrders[positions[i].CloseOrders.Count - 1]); } } for (int i = 0; i < myOrderToFirstClose.Count; i++) { if (myOrderToFirstClose[i].TimeCallBack.AddSeconds(3) < _tab.TimeServerCurrent) { _reActivatorIsOn = false; _tab.CloseOrder(myOrderToFirstClose[i]); } } // смотрим классический выход List <Order> myOrder = new List <Order>(); for (int i = 0; i < positions.Count; i++) { if (positions[i].OpenOrders[positions[i].OpenOrders.Count - 1].State == OrderStateType.Activ) { myOrder.Add(positions[i].OpenOrders[positions[i].OpenOrders.Count - 1]); } if (positions[i].CloseOrders != null && positions[i].CloseOrders[positions[i].CloseOrders.Count - 1].State == OrderStateType.Activ) { myOrder.Add(positions[i].CloseOrders[positions[i].CloseOrders.Count - 1]); } } for (int i = 0; i < myOrder.Count; i++) { Order order = myOrder[i]; // бежим по коллекции ордеров if (order.State != OrderStateType.Done && order.State != OrderStateType.Fail && order.State != OrderStateType.None) { // если какойто не исполнен полностью DateTime startTime = order.TimeCallBack; DateTime marketTime = _tab.TimeServerCurrent; if (startTime == DateTime.MinValue || startTime == DateTime.MaxValue) { continue; } if (startTime.AddSeconds(LagTimeToOpenClose.TotalSeconds) < marketTime) { _tab.CloseOrder(order); Thread.Sleep(2000); if (AlertIsOn) { AlertMessageManager.ThrowAlert(Properties.Resources.wolf01, NameStrategyUniq, "Отзываем ордер по времени"); } _tab.SetNewLogMessage("Отзываем ордер по времени", LogMessageType.System); } else { decimal priceBid = _tab.PriceBestBid; decimal priceAsk = _tab.PriceBestAsk; if (order.Side == Side.Buy && order.Price + LagPunctToOpenClose * _tab.Securiti.PriceStep < priceAsk) { _tab.CloseOrder(order); Thread.Sleep(2000); if (AlertIsOn) { AlertMessageManager.ThrowAlert(Properties.Resources.wolf01, NameStrategyUniq, "Отзываем ордер по отклонению"); } _tab.SetNewLogMessage("Отзываем ордер по отклонению", LogMessageType.System); } if (order.Side == Side.Sell && order.Price - LagPunctToOpenClose * _tab.Securiti.PriceStep > priceBid) { _tab.CloseOrder(order); Thread.Sleep(2000); if (AlertIsOn) { AlertMessageManager.ThrowAlert(Properties.Resources.wolf01, NameStrategyUniq, "Отзываем ордер по отклонению"); } _tab.SetNewLogMessage("Отзываем ордер по отклонению", LogMessageType.System); } } } else if (order.State == OrderStateType.Fail) { if (AlertIsOn) { AlertMessageManager.ThrowAlert(Properties.Resources.wolf01, NameStrategyUniq, "Ошибка выставления ордера"); } myOrder.Remove(order); i--; } } } catch (Exception) { // ignore } } }