public async Task <OpenOrderResult> PlaceOpeningOrder(TradeDetail trade, IEnumerable <TradeDetail> relatedTrades) { var market = trade.Match.BetfairData.Markets.Single(x => x.MarketName == trade.MarketName); var runnerId = market.Runners.Single(x => x.Name == trade.RunnerName).Id; var latestRunnerBook = await _runnerService.GetRunnerDetails(market.MarketId, runnerId); var orderTick = _orderPriceFinder.GetPrice(trade.Side, latestRunnerBook.ExchangePrices); var openingOrderWrapper = new OrderWrapper(market.MarketId, runnerId, trade.Side, orderTick, PersistenceType.LAPSE); var policy = Policy.Handle <MarketSuspendedException>().Or <OrderActionErrorException>().Or <OrderNotPlaceableException>().WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt * 4))); var betReport = await policy.Execute(() => _orderPlacer.PlaceOrder(openingOrderWrapper)); var betId = betReport.InstructionReports.Single().BetId; openingOrderWrapper.AddBetId(betId); _sleepService.Sleep(5000); var matchReport = await _runnerService.GetRunnerDetails(market.MarketId, runnerId); var orderReport = matchReport.Orders.Where(x => x.BetId == betId).Sum(x => x.SizeRemaining); if (orderReport != 0) { var cancelReport = await _orderPlacer.CancelOrder(betId, market.MarketId); if (cancelReport.Status == ExecutionReportStatus.SUCCESS) { throw new OrderCancelledException(betId); } } return(new OpenOrderResult(trade, openingOrderWrapper)); }
private async Task CloseoutBet(OpenOrderResult openingOrderSummary) { var marketId = openingOrderSummary.OpenOrderResponse.MarketId; var runnerId = openingOrderSummary.OpenOrderResponse.SelectionId; var betId = openingOrderSummary.OpenOrderResponse.BetId; var latestRunnerBook = await _runnerService.GetRunnerDetails(marketId, runnerId); var openingOrders = latestRunnerBook.Orders.Where(x => x.BetId == betId).ToList(); double closingPrice = 0; if (openingOrderSummary.OpenOrderRequest.TrackingTradeOffset.HasValue) { closingPrice = PriceLadderUtility.GetWinningPriceTarget(Side.BACK, openingOrderSummary.OpenOrderResponse.OrderTick.Price, openingOrderSummary.OpenOrderRequest.TrackingTradeOffset.Value); } else if (openingOrderSummary.OpenOrderResponse.Side == Side.BACK) { closingPrice = latestRunnerBook.ExchangePrices.AvailableToLay.Min(x => x.Price); } else if (openingOrderSummary.OpenOrderResponse.Side == Side.LAY) { closingPrice = latestRunnerBook.ExchangePrices.AvailableToBack.Max(x => x.Price); } else { throw new System.Exception("No closing side specified"); } var closeoutStake = _closingStakeCalculator.GetFullHedgeStake(openingOrders, closingPrice); var orderWrapper = new OrderWrapper(marketId, runnerId, closeoutStake.Key, new OrderTick(closingPrice, closeoutStake.Value), PersistenceType.LAPSE); var closeoutOrderReport = await _orderPlacer.PlaceOrder(orderWrapper); if (closeoutOrderReport.Status != ExecutionReportStatus.SUCCESS) { throw new System.Exception("Closeout bet not placed!"); } var closeoutBetId = closeoutOrderReport.InstructionReports.Single().BetId; _sleepService.Sleep(10000); await ManageCloseoutOrderMatching(marketId, runnerId, closeoutBetId); }