/// <summary> /// To get the synthetic position for the option. /// </summary> /// <param name="side">The main position direction.</param> /// <returns>The synthetic position.</returns> public KeyValuePair<Security, Sides>[] Position(Sides side) { var asset = Option.GetUnderlyingAsset(_provider); return new[] { new KeyValuePair<Security, Sides>(asset, Option.OptionType == OptionTypes.Call ? side : side.Invert()), new KeyValuePair<Security, Sides>(Option.GetOppositeOption(_provider), side) }; }
private void TryCreateOppositeOrder(List <ExecutionMessage> retVal, SortedDictionary <decimal, RefPair <LevelQuotes, QuoteChange> > quotes, DateTimeOffset localTime, DateTimeOffset serverTime, decimal tradePrice, decimal volume, Sides originSide) { if (HasDepth(localTime)) { return; } var priceStep = GetPriceStep(); var oppositePrice = (tradePrice + _settings.SpreadSize * priceStep * (originSide == Sides.Buy ? 1 : -1)).Max(priceStep); var bestQuote = quotes.FirstOrDefault(); if (bestQuote.Value == null || ((originSide == Sides.Buy && oppositePrice < bestQuote.Key) || (originSide == Sides.Sell && oppositePrice > bestQuote.Key))) { retVal.Add(CreateMessage(localTime, serverTime, originSide.Invert(), oppositePrice, volume)); } }
/// <summary> /// To get the synthetic position for the option. /// </summary> /// <param name="side">The main position direction.</param> /// <returns>The synthetic position.</returns> public KeyValuePair <Security, Sides>[] Position(Sides side) { var asset = Option.GetUnderlyingAsset(_provider); return(new[] { new KeyValuePair <Security, Sides>(asset, Option.OptionType == OptionTypes.Call ? side : side.Invert()), new KeyValuePair <Security, Sides>(Option.GetOppositeOption(_provider), side) }); }
private IEnumerable<ExecutionMessage> IncreaseDepthVolume(DateTime time, DateTimeOffset serverTime, Sides orderSide, decimal leftVolume) { var quotes = orderSide == Sides.Buy ? _asks : _bids; var quote = quotes.LastOrDefault(); if(quote.Value == null) yield break; var side = orderSide.Invert(); var lastVolume = quote.Value.Second.Volume; var lastPrice = quote.Value.Second.Price; while (leftVolume > 0 && lastPrice != 0) { lastVolume *= 2; lastPrice += GetPriceStep() * (side == Sides.Buy ? -1 : 1); leftVolume -= lastVolume; yield return CreateMessage(time, serverTime, side, lastPrice, lastVolume); } }
private void TryCreateOppositeOrder(List<ExecutionMessage> retVal, SortedDictionary<decimal, RefPair<List<ExecutionMessage>, QuoteChange>> quotes, DateTime localTime, DateTimeOffset serverTime, decimal tradePrice, decimal volume, Sides originSide) { if (HasDepth(localTime)) return; var oppositePrice = tradePrice + _settings.SpreadSize * GetPriceStep() * (originSide == Sides.Buy ? 1 : -1); var bestQuote = quotes.FirstOrDefault(); if (bestQuote.Value == null || ((originSide == Sides.Buy && oppositePrice < bestQuote.Key) || (originSide == Sides.Sell && oppositePrice > bestQuote.Key))) retVal.Add(CreateMessage(localTime, serverTime, originSide.Invert(), oppositePrice, volume)); }
private void ProcessMarketOrder(List<ExecutionMessage> retVal, SortedDictionary<decimal, RefPair<List<ExecutionMessage>, QuoteChange>> quotes, DateTimeOffset time, DateTime localTime, Sides orderSide, decimal tradePrice, decimal volume) { // вычисляем объем заявки по рынку, который смог бы пробить текущие котировки. // bigOrder - это наша большая рыночная заявка, которая способствовала появлению tradeMessage var bigOrder = CreateMessage(localTime, time, orderSide, tradePrice, 0, tif: TimeInForce.MatchOrCancel); var sign = orderSide == Sides.Buy ? -1 : 1; var hasQuotes = false; foreach (var pair in quotes) { var quote = pair.Value.Second; if (quote.Price * sign > tradePrice * sign) { bigOrder.Volume += quote.Volume; } else { if (quote.Price == tradePrice) { bigOrder.Volume += volume; //var diff = tradeMessage.Volume - quote.Volume; //// если объем котиовки был меньше объема сделки //if (diff > 0) // retVal.Add(CreateMessage(tradeMessage.LocalTime, quote.Side, quote.Price, diff)); } else { if ((tradePrice - quote.Price).Abs() == _securityDefinition.PriceStep) { // если на один шаг цены выше/ниже есть котировка, то не выполняем никаких действий // иначе добавляем новый уровень в стакан, чтобы не было большого расхождения цен. hasQuotes = true; } break; } //// если котировки с ценой сделки вообще не было в стакане //else if (quote.Price * sign < tradeMessage.TradePrice * sign) //{ // retVal.Add(CreateMessage(tradeMessage.LocalTime, quote.Side, tradeMessage.Price, tradeMessage.Volume)); //} } } retVal.Add(bigOrder); // если собрали все котировки, то оставляем заявку в стакане по цене сделки if (!hasQuotes) retVal.Add(CreateMessage(localTime, time, orderSide.Invert(), tradePrice, volume)); }
/// <summary> /// To get the option position for the synthetic base asset. /// </summary> /// <param name="strike">Strike.</param> /// <param name="expiryDate">The date of the option expiration.</param> /// <param name="side">The main position direction.</param> /// <returns>The option position.</returns> public KeyValuePair<Security, Sides>[] Position(decimal strike, DateTimeOffset expiryDate, Sides side) { var call = _security.GetCall(_provider, strike, expiryDate); var put = _security.GetPut(_provider, strike, expiryDate); return new[] { new KeyValuePair<Security, Sides>(call, side), new KeyValuePair<Security, Sides>(put, side.Invert()) }; }