/// <summary> /// собственно защита /// </summary> private void CheckProtect(List<MarketOrder> orders, QuoteData curQuote, List<RobotHint> hints) { if (protectList == null) return; if (protectList.orderIds.Count == 0) { protectList = null; return; } var ordersToProtect = (from order in orders let orderId = order.ID where protectList.orderIds.Contains(orderId) select order).ToList(); if (ordersToProtect.Count == 0) return; var pointCost = DalSpot.Instance.GetAbsValue(ordersToProtect[0].Symbol, 1f); // индивидуальная "защита" if (ProtectPosType == ProtectType.Индивидуально) { foreach (var order in ordersToProtect) { var targetStop = order.PriceEnter + order.Side*ProtectTarget*pointCost; // проверка - не пытаться переставить стоп на 0.4 пп например var delta = Math.Abs(targetStop - (order.StopLoss ?? 0)); delta = delta/pointCost; if (delta < ProtectSensitivity) continue; // проверка контрольной отметки var orderProtectLevel = order.PriceEnter + order.Side*ProtectLevel*pointCost; var shouldProtect = order.Side == 1 ? curQuote.bid > orderProtectLevel : curQuote.bid < orderProtectLevel; if (!shouldProtect) continue; order.StopLoss = targetStop; robotContext.SendEditMarketRequest(protectedContext.MakeProtectedContext(), order); if (ShowProtectMarker) { var title = "Защита сделки " + order.ID; hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(), title, title, "p", curQuote.bid) { RobotHintType = RobotHint.HintType.Коментарий, Time = curQuote.time, ColorFill = Color.White, ColorLine = Color.DarkBlue, ColorText = Color.Black }); } protectList.orderIds.Remove(order.ID); } if (protectList.orderIds.Count == 0) protectList = null; return; } // защита по "медианнной цене" или по "худшей цене" // найти ту самую медианную цену float medPrice = 0; if (ProtectPosType == ProtectType.ПоСреднейЦене) { // средняя цена... var sumPrice = ordersToProtect.Sum(o => o.PriceEnter * o.Volume); var sumVolume = ordersToProtect.Sum(o => o.Volume); medPrice = sumPrice/sumVolume; } if (ProtectPosType == ProtectType.ПоХудшейЦене) { var date = ordersToProtect[0].TimeEnter; medPrice = ordersToProtect[0].PriceEnter; for (var i = 1; i < ordersToProtect.Count; i++) { if (ordersToProtect[i].TimeEnter >= date) continue; date = ordersToProtect[i].TimeEnter; medPrice = ordersToProtect[i].PriceEnter; } } var stopPrice = medPrice + ordersToProtect[0].Side * ProtectTarget * pointCost; // проверить все ордера var dealProtected = false; foreach (var order in ordersToProtect) { var delta = Math.Abs(stopPrice - (order.StopLoss ?? 0)); delta = delta / pointCost; if (delta < ProtectSensitivity) continue; // цена прошла рубеж? var shouldProtect = order.Side == 1 ? curQuote.bid > medPrice : curQuote.bid < medPrice; if (!shouldProtect) continue; dealProtected = true; order.StopLoss = stopPrice; protectList.orderIds.Remove(order.ID); } if (ShowProtectMarker && dealProtected) { var text = new StringBuilder(); text.AppendLine("Защита сделок " + string.Join(", ", ordersToProtect.Select(o => o.ID))); text.AppendFormat("Средневзвеш. цена: {0:f4}", medPrice); hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(), "Защита сделок", text.ToString(), "p", curQuote.bid) { RobotHintType = RobotHint.HintType.Коментарий, Time = curQuote.time, ColorFill = Color.White, ColorLine = Color.DarkBlue, ColorText = Color.Black }); } if (protectList.orderIds.Count == 0) protectList = null; return; }
/// <summary> /// проверить условия защиты либо по диверам, либо - по Фибоначчи /// прошерстить все таймфреймы, на каждом ТФ - все диверы /// проверить, выполняется ли условие на защиту покупок или продаж /// </summary> private void CheckProtectTrigger( List<MarketOrder> orders, QuoteData curQuote, List<RobotHint> hints, bool isHistoryStartOff, CandleData newCandle) { if (diversToProtect.Count == 0 && fibonacciProtect.Count == 0) return; var protectConditions = new StringBuilder(); int diverSign = CheckProtectByDivers(curQuote, isHistoryStartOff, protectConditions); if (diverSign == 0) diverSign = CheckProtectByFibos(protectConditions, orders, newCandle); if (diverSign == 0) return; // защищаем сделки с указанным знаком var protectSide = (DealType) diverSign; // создать новый список защиты // старый либо актуализируется, либо игнорируется orders = orders.Where(o => o.Side == (int)protectSide).ToList(); if (orders.Count == 0) return; var newProtectList = new ProtectList { orderIds = orders.Select(o => o.ID).ToList(), side = protectSide }; if (protectList != null) if (newProtectList.AreEqual(protectList)) return; protectList = newProtectList; // добавить маркер на график if (ShowProtectEventMarker) { var eventTitle = protectSide == DealType.Buy ? string.Format("Защита {0} покупок", orders.Count) : string.Format("Защита {0} продаж", orders.Count); var eventText = "Условия: " + protectConditions; hints.Add(new RobotHint(Graphics[0].a, Graphics[0].b.ToString(), eventText, eventTitle, "p", curQuote.bid) { Time = curQuote.time, ColorFill = Color.Yellow, ColorLine = Color.Black, RobotHintType = RobotHint.HintType.Коментарий //diverSign > 0 // ? RobotHint.HintType.Покупка // : RobotHint.HintType.Продажа }); } //Logger.InfoFormat("CheckProtectTrigger: защита сделок [{0}] типа {1}", // string.Join(", ", protectList.orderIds), protectList.side); }
public bool AreEqual(ProtectList list) { if (side != list.side) return false; if (orderIds.Count != list.orderIds.Count) return false; for (var i = 0; i < orderIds.Count; i++) if (orderIds[i] != list.orderIds[i]) return false; return true; }