public async Task ProcessMessage(TradeDetail trade) { try { CopyMatchMetadata(trade); var strategyTradeManagers = _managerFactory.GetStrategyTradeManagerPair(trade.StrategyId); var openingOrderSummary = await strategyTradeManagers.OpeningOrderManager.PlaceOpeningOrder(trade, new List <TradeDetail>()); await strategyTradeManagers.ClosingOrderManager.ManageCloseout(openingOrderSummary); var databaseTradeRecord = BuildTradeRecord(trade, "COMPLETE", null); databaseTradeRecord.OpeningId = openingOrderSummary.OpenOrderResponse.BetId; WriteToDatabase(databaseTradeRecord); _console.WriteLineWithTimestamp($"Trade complete - {trade.Id}"); } catch (OrderCancelledException e) { _console.WriteLineWithTimestamp(e.Message); _console.WriteLineWithTimestamp($"Trade cancelled - {trade.Id}"); var databaseTradeRecord = BuildTradeRecord(trade, e.ExceptionCode, null); databaseTradeRecord.OpeningId = e.BetId; WriteToDatabase(databaseTradeRecord); } catch (NoPriceWithRequiredStakeAvailableException e) { HandleTradeException(trade, e); } catch (OrderActionErrorException e) { HandleTradeException(trade, e); } catch (MarketSuspendedException e) { HandleTradeException(trade, e); } catch (InsufficientFundsException e) { HandleTradeException(trade, e); } catch (Exception e) { _console.WriteLineWithTimestamp(e.Message); _console.WriteLineWithTimestamp(e.StackTrace); _console.WriteLineWithTimestamp($"Trade failed - {trade.Id}"); var databaseTradeRecord = BuildTradeRecord(trade, "ERROR", e.Message); WriteToDatabase(databaseTradeRecord); } }