Exemple #1
0
// Common behaviours to persist and publish populated Execution entity into our data layer and message bus
func (app FIXClient) processExecutionReport(er *proto.Execution) quickfix.MessageRejectError {

	// Find the Order by using the OrderKey without the Version
	// Need to try to LOAD the order, if that fails then alert stating unsolicited order received
	keyVersion := strings.Split(er.ClientOrderId, ".")
	if len(keyVersion) != 2 {
		return quickfix.ValueIsIncorrect(tag.ClOrdID)
	}
	if oKey, err := strconv.Atoi(keyVersion[0]); err != nil {
		return quickfix.ValueIsIncorrect(tag.ClOrdID)
	} else {
		if ord, err := app.OrderStore.OrderGetByOrderKey(int32(oKey)); err != nil {
			log.WithError(err).Warnf("Received ExecutionReport with OrderKey(%v) does not exist.", oKey)
			return nil // TODO: ignore or quickfix.ValueIsIncorrect(tag.ClOrdID)
		} else {
			er.OrderId = ord.OrderId
		}
	}

	// Persist the execution report
	if err := app.OrderStore.ExecutionCreate(er); err == nil {
		//publish to message bus
		data, _ := er.Marshal()
		app.MessageBus.Publish("order.Execution", data)
	} else {
		log.WithField("execution", er).WithError(err).Error("[ MC ] ERROR Create Reject Execution")
	}

	// Do any validating and if we are good to continue

	// Check if we need to cancel any execution
	// Check if we need to correct any execution
	switch er.ExecType {
	case proto.Execution_TRADE_CANCEL:
	case proto.Execution_TRADE_CORRECT:
	//TODO: TryGetAmendedExecution
	case proto.Execution_RESTATED:
	case proto.Execution_REJECTED:
	}

	// Check if the trade is fully filled or is done for day or canceled
	// .. Send message to TradePump to say trade filled and already to book.

	return nil
}