private static Transaction GetShufflingRegistrationTransaction(TransactionReply shufflingTransaction, ShufflingParticipant lastAccountRs) { var registerTransactions = transactionService.GetBlockchainTransactions(lastAccountRs.AccountId, shufflingTransaction.BlockTimestamp, TransactionSubType.ShufflingRegistration).Result; var registerTransaction = registerTransactions.Transactions.Single(t => ((ShufflingRegistrationAttachment)t.Attachment).ShufflingFullHash.Equals(shufflingTransaction.FullHash)); return(registerTransaction); }
internal void OnTransReplyCall(TransactionReply reply) { if (OnTransReply != null) { OnTransReply(reply); } // invoke event specific for the transaction if (string.IsNullOrEmpty(reply.Comment))//"Initialization user successful" transaction doesn't contain comment { return; } if (QuikService.Storage.Contains(reply.Comment)) { var tr = QuikService.Storage.Get <Transaction>(reply.Comment); lock (tr) { tr.OnTransReplyCall(reply); } } else { // NB ignore unmatched transactions //Trace.Fail("Transaction must exist in persistent storage until it is completed and its reply is recieved"); } }
public async void Visit(KillOrderTransaction transaction) { try { var reply = await transClient.CancelOrder(new CancelOrder { order_id = transaction.OrderExchangeId }); OnMessageReceived(TransactionReply.Accepted(transaction, reply.code)); var oscm = new OrderStateChangeMessage { TransactionId = transaction.TransactionId, OrderExchangeId = reply.code, Quantity = reply.qty, ActiveQuantity = reply.qtyLeft, FilledQuantity = reply.qty_executed, ChangeTime = DateTime.Now, State = OrderState.Cancelled }; OnMessageReceived(oscm); } catch (FTEException e) { OnMessageReceived(TransactionReply.Rejected(transaction, e.Message)); } }
/// <summary> /// Отправляет заявки. /// </summary> /// <param name="transaction"> /// Экземпляр заявки для отправки. /// </param> public void SendTransaction(Transaction transaction) { if (!_initiator.IsLoggedOn) { SendMessage(TransactionReply.Rejected(transaction, "Router is off-line")); } transaction.Accept(this); }
internal void OnTransReplyCall(TransactionReply reply) { if (OnTransReply != null) { OnTransReply(reply); } // this should happen only once per transaction id Trace.Assert(TransactionReply == null); TransactionReply = reply; }
private void Reject(Transaction transaction, string message, params object[] args) { var reply = new TransactionReply { Success = false, TransactionId = transaction.TransactionId, Message = string.Format(message, args) }; connector.IBOrderRouter.Transmit(reply); }
public void Reject(string clOrderId, string message) { Guid transactionId; using (_transactionIdsLock.Lock()) { if (!_clientOrderIdToTransactionIdMap.TryGetValue(clOrderId, out transactionId)) { return; } Forget(transactionId); } _sendMessage(TransactionReply.Rejected(transactionId, message)); }
public void Reject(int seqNum, string message) { Guid transactionId; using (_transactionIdsLock.Lock()) { if (!_seqNumberIdToTransactionIdMap.TryGetValue(seqNum, out transactionId)) { return; } Forget(transactionId); } _sendMessage(TransactionReply.Rejected(transactionId, message)); }
private void TrySendTransactionReplyRejected(uint requestId, string errorMessage) { Guid transactionId; using (transactionIdsByRequestIdLock.Lock()) { if (!transactionIdsByRequestId.TryGetValue(requestId, out transactionId)) { return; } transactionIdsByRequestId.Remove(requestId); transactionRequestIds.Remove(transactionId); } OnMessageReceived(TransactionReply.Rejected(transactionId, errorMessage)); }
internal void OnTransReplyCall(TransactionReply reply) { if (OnTransReply != null) { OnTransReply(reply); } // invoke event specific for the transaction var tr = QuikService.Storage.Get <Transaction>(reply.Comment); if (tr != null) { tr.OnTransReplyCall(reply); // persist transaction with added reply QuikService.Storage.Set(reply.Comment, tr); } Trace.Assert(tr != null, "Transaction must exist in persistent storage until it is completed and its reply is recieved"); }
private void TrySendTransactionReplyAccepted(Guid transactionId) { using (transactionIdsByRequestIdLock.Lock()) { uint requestId; if (transactionRequestIds.TryGetValue(transactionId, out requestId)) { transactionIdsByRequestId.Remove(requestId); } if (!transactionRequestIds.Remove(transactionId)) { return; } } OnMessageReceived(TransactionReply.Accepted(transactionId)); }
/// <summary> /// Обработать транзакцию <see cref="KillOrderTransaction"/> /// </summary> /// <param name="transaction"> /// Транзакция для обработки /// </param> void ITransactionVisitor.Visit(KillOrderTransaction transaction) { if (!_orders.GetOrderParams(transaction.OrderExchangeId, out var _, out var symbol, out var qty, out var side)) { SendMessage(TransactionReply.Rejected(transaction, $"Unknown order: {transaction.OrderExchangeId}")); return; } var msg = new OrderCancelRequest(); var clOrderId = _killOrderTransactions.Add(transaction); msg.ClOrdID = new ClOrdID(clOrderId); msg.OrderID = new OrderID(transaction.OrderExchangeId); msg.Symbol = new Symbol(symbol); msg.Side = new Side(side); msg.OrderQty = new OrderQty(qty); msg.TransactTime = new TransactTime(DateTime.UtcNow); SendFixMessage(msg); }
private static Transaction GetTransactionType(Type objectType) { Transaction transaction; if (objectType == typeof(Transaction)) { transaction = new Transaction(); } else if (objectType == typeof(TransactionReply)) { transaction = new TransactionReply(); } else if (objectType == typeof(ParseTransactionReply)) { transaction = new ParseTransactionReply(); } else { throw new ArgumentException("Can only convert to transaction object"); } return(transaction); }
private async Task ProcessMessage(ConsumeResult <Ignore, TransactionRequest> cr) { var rq = cr.Message.Value; logger.LogInformation($"Consumed message '{rq}' (amount: {rq.AmountCents})'."); var replyGroupId = cr.Message.Headers.SingleOrDefault(p => p.Key == "reply-group-id"); // We are going to pretend that we do some processing here and then send out two events: // * Reply to the Request that it has been processesed // * Publish the fact that the transaction has been created onto the bus // This is obviously not a real world implementation. We're sending two messages independently, without transactions. // We're also not concerned about commits and idempotency upon reprocessing // Also, if we are doing other work, such as databases, things can get complex because you will have multiple transactions, each // of which can fail independently. // Do our 'processing' var reply = new TransactionReply { RequestId = rq.RequestId, Status = $"Transaction of value {rq.AmountCents} has been processed" }; var replyHeaders = new List <Tuple <string, byte[]> >(); if (replyGroupId != null) { replyHeaders.Add(new Tuple <string, byte[]>("reply-group-id", replyGroupId.GetValueBytes())); } var createdEvent = new TransactionCreated { AmountCents = rq.AmountCents, FromAccount = rq.FromAccount, ToAccount = rq.ToAccount, CreatedAt = DateTime.UtcNow, TransactionId = Guid.NewGuid().ToString("B") }; await createdSender.SendToBusWithoutRetries(createdEvent, "transactions"); await replySender.SendToBusWithoutRetries(reply, "transaction-replies", replyHeaders); }
private void Events_OnTransReply(TransactionReply transReply) { int status = transReply.Status; /* * if (transReply.Status == 2) * status = "ошибка при передаче транзакции в торговую систему"; * if (transReply.Status == 3) * status = "транзакция выполнена"; * if (transReply.Status > 3) * status = "ошибка исполнения транзакции " + transReply.Status; * * Log("OnTransReply " + transReply.TransID + " статус " + status + " " + transReply.ResultMsg); */ if (transReply.TransID == stopTransId) { switch (transReply.Status) { case 1: break; case 2: Log("Ошибка при передаче транзакции в торговую систему " + status + " " + transReply.ResultMsg); break; case 3: Log("Стоп-заявка зарегистрирована, номер " + transReply.OrderNum); stopTransId = 0; break; default: Log("Ошибка исполнения транзакции " + status + " " + transReply.ResultMsg); break; } } }
/// <summary> /// Выплюнуть из раутера сообщение /// </summary> /// <param name="message"> /// Сообщение /// </param> internal void Transmit(TransactionReply message) { OnMessageReceived(message); }
public void Visit(Transaction transaction) { OnMessageReceived(TransactionReply.Rejected(transaction, "NotSupported")); }
public async void Visit(NewOrderTransaction transaction) { try { //internal async Task<string> ResolveInstrumentAsync(Instrument instrument) //{ // var data = await instrumentConverter.ResolveInstrumentAsync(this, instrument); // return data?.Symbol; //} var data = await connector.ResolveInstrumentDataAsync(transaction.Instrument); if (data == null) { OnMessageReceived(TransactionReply.Rejected(transaction, $"Unable to get symbol of {transaction.Instrument}")); return; } if (!accounts.TryGetValue(transaction.Account, out var account)) { OnMessageReceived(TransactionReply.Rejected(transaction, $"Не найден счет {transaction.Account}")); return; } var order = new SpimexAdapter.FTE.Order { account = account.code, firm = account.firm, client = account.client, security = data.Symbol, board = data.Board, @type = transaction.GetOrderType(), @params = transaction.GetOrderParams(), buy_sell = transaction.GetOperation(), price = PriceHelper.FromPrice(transaction.Price), qty = transaction.Quantity, trn = transaction.TransactionId.ToString("N"), isMarketMaker = transaction.IsMarketMakerOrder, comment = transaction.Comment, }; var reply = await transClient.SendOrder(order); OnMessageReceived(TransactionReply.Accepted(transaction, reply.code)); OrderState?state = null; switch (reply.status) { case OrderStatus.CANCELED: state = OrderState.Cancelled; break; case OrderStatus.MATCHED: state = OrderState.Filled; break; case OrderStatus.FREEZED: case OrderStatus.QUEUED: state = reply.qty_executed > 0 ? OrderState.PartiallyFilled : OrderState.Active; break; } var oscm = new OrderStateChangeMessage { TransactionId = transaction.TransactionId, OrderExchangeId = reply.code, Quantity = order.qty, ActiveQuantity = reply.qtyLeft, FilledQuantity = reply.qty_executed, Price = PriceHelper.ToPrice(order.price), ChangeTime = DateTime.Now, State = state }; OnMessageReceived(oscm); } catch (FTEException e) { OnMessageReceived(TransactionReply.Rejected(transaction, e.Message)); } }
/// <summary> /// Модификация заявки /// </summary> private async void SendTransactionInternal(ModifyOrderTransaction transaction) { using (LogManager.Scope()) { try { // Получаем счет для транзакции int accountId; var hasAccountId = true; using (accountsLock.ReadLock()) { if (!accountIdsByCode.TryGetValue(transaction.Account, out accountId)) { hasAccountId = false; } } if (!hasAccountId) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Account \"{transaction.Account}\" is unknown")); return; } // Получаем инструмент для транзации uint contractId; try { contractId = await instrumentResolver.GetContractIdAsync(transaction.Instrument); if (contractId == uint.MaxValue) { return; } } catch (OperationCanceledException) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Instrument \"{transaction.Instrument.Code}\" is unknown")); return; } // Формируем запрос OrderRequest msg; using (ordersLock.Lock()) { OrderStatus orderStatus; using (ordersLock.Lock()) { orderStatusByChainOrderId.TryGetValue(transaction.OrderExchangeId, out orderStatus); } if (orderStatus == null) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Order \"{transaction.OrderExchangeId}\" doesn't exist or is not active")); return; } // Пребразовываем цену var price = transaction.Price != null ? instrumentResolver.ConvertPrice(contractId, transaction.Price) : orderStatus.order.limit_price; if (price == null) { OnMessageReceived(TransactionReply.Rejected(transaction, "Unable to convert price")); return; } msg = new OrderRequest { modify_order = new ModifyOrder { order_id = orderStatus.order_id, cl_order_id = transaction.TransactionId.ToString("N"), orig_cl_order_id = orderStatus.order.cl_order_id, account_id = accountId, limit_price = price.Value, qty = transaction.Quantity, when_utc_time = adapter.ResolveDateTime(DateTime.UtcNow) }, request_id = adapter.GetNextRequestId() }; } // Запоминаем транзакцию StoreTransaction(msg.request_id, transaction); // Отправляем заявку Logger.Debug().PrintFormat("Sending {0}", transaction); adapter.SendMessage(msg); } catch (Exception e) { Logger.Error().Print(e, $"Failed to send {transaction}"); OnMessageReceived(TransactionReply.Rejected(transaction, "Unable to send order")); } } }
/// <summary> /// Снятие заявки /// </summary> private void SendTransactionInternal(KillOrderTransaction transaction) { // Получаем счет для транзакции int accountId; var hasAccountId = true; using (accountsLock.ReadLock()) { if (!accountIdsByCode.TryGetValue(transaction.Account, out accountId)) { hasAccountId = false; } } if (!hasAccountId) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Account \"{transaction.Account}\" is unknown")); return; } // Поиск заявки OrderStatus orderStatus; using (ordersLock.Lock()) { orderStatusByChainOrderId.TryGetValue(transaction.OrderExchangeId, out orderStatus); } if (orderStatus == null) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Order \"{transaction.OrderExchangeId}\" is not found")); return; } // Формируем запрос var msg = new OrderRequest { cancel_order = new CancelOrder { cl_order_id = transaction.TransactionId.ToString("N"), account_id = accountId, order_id = orderStatus.order_id, orig_cl_order_id = orderStatus.order.cl_order_id, when_utc_time = adapter.ResolveDateTime(DateTime.UtcNow) }, request_id = adapter.GetNextRequestId() }; // Запоминаем транзакцию StoreTransaction(msg.request_id, transaction); // Отправляем заявку try { Logger.Debug().PrintFormat("Sending {0}", transaction); adapter.SendMessage(msg); } catch (Exception) { OnMessageReceived(TransactionReply.Rejected(transaction, "Unable to send order")); } }
/// <summary> /// Постановка заявки /// </summary> private async void SendTransactionInternal(NewOrderTransaction transaction) { using (LogManager.Scope()) { try { // Получаем счет для транзакции int accountId; var hasAccountId = true; using (accountsLock.ReadLock()) { if (!accountIdsByCode.TryGetValue(transaction.Account, out accountId)) { hasAccountId = false; } } if (!hasAccountId) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Account \"{transaction.Account}\" is unknown")); return; } // Получаем инструмент для транзации uint contractId; try { contractId = await instrumentResolver.GetContractIdAsync(transaction.Instrument); if (contractId == uint.MaxValue) { return; } } catch (OperationCanceledException) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Instrument \"{transaction.Instrument.Code}\" is unknown")); return; } // Пребразовываем цену var price = instrumentResolver.ConvertPrice(contractId, transaction.Price); if (price == null) { OnMessageReceived(TransactionReply.Rejected(transaction, "Unable to convert price")); return; } // Формируем запрос var msg = new OrderRequest { new_order = new NewOrder { order = new WebAPI.Order { cl_order_id = transaction.TransactionId.ToString("N"), account_id = accountId, contract_id = contractId, side = (uint)ConvertionHelper.GetSide(transaction.Operation), order_type = (uint)ConvertionHelper.GetOrderType(transaction.Type), duration = (uint)ConvertionHelper.GetDuration(transaction.ExecutionCondition), limit_price = price.Value, qty = transaction.Quantity, is_manual = transaction.IsManual, user_attribute = { new UserAttribute { name = CommentAttributeName, value = transaction.Comment } } }, suspend = false }, request_id = adapter.GetNextRequestId() }; // Запоминаем заявку using (ordersLock.Lock()) { var order = new Order(transaction); ordersByTransactionId.Add(transaction.TransactionId, order); } // Запоминаем транзакцию StoreTransaction(msg.request_id, transaction); Logger.Debug().PrintFormat("Sending {0}", transaction); adapter.SendMessage(msg); } catch (Exception e) { Logger.Error().Print(e, $"Failed to send {transaction}"); OnMessageReceived(TransactionReply.Rejected(transaction, "Unable to send order")); } } }
private static Transaction GetShufflingProcessingTransaction(ShufflingData shuffling, TransactionReply shufflingTransaction, ShufflingParticipant previousAccountRs) { var processTransactions = transactionService.GetBlockchainTransactions(previousAccountRs.AccountId, shufflingTransaction.BlockTimestamp, TransactionSubType.ShufflingProcessing).Result; var processTransaction = processTransactions.Transactions.Single(t => ((ShufflingProcessingAttachment)t.Attachment).ShufflingId == shuffling.ShufflingId); return(processTransaction); }
/// <summary> /// Транзакция не поддерживается /// </summary> private void TransactionIsNotSupported(Transaction transaction) { OnMessageReceived(TransactionReply.Rejected(transaction, $"Transaction is not supported by CQGC: {transaction}")); }
public void Visit(Transaction transaction) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Transaction of type {transaction.GetType()} is not supported by router")); }
public void OnTransReply(TransactionReply reply) { TransReply?.Invoke(_quik, reply); }
public TransactionReplyHelper(TransactionReply reply) { Reply = reply; PendingStates = new List <PendingState>(); }
/// <summary> /// Обработать транзакцию <see cref="NewOrderTransaction"/> /// </summary> /// <param name="transaction"> /// Транзакция для обработки /// </param> async void ITransactionVisitor.Visit(NewOrderTransaction transaction) { InstrumentData instrumentData; try { instrumentData = await _settings.InstrumentConverter.ResolveInstrumentAsync(this, transaction.Instrument); } catch (Exception e) { _Log.Error().Print(e, $"Failed to resolve instrument {transaction.Instrument}"); SendMessage(TransactionReply.Rejected(transaction, "Failed to resolve instrument")); return; } if (instrumentData == null) { _Log.Error().Print($"Instrument {transaction.Instrument} hasn't been resolved"); SendMessage(TransactionReply.Rejected(transaction, "Instrument hasn't been resolved")); return; } var msg = new NewOrderSingle(); msg.TransactTime = new TransactTime(DateTime.UtcNow); msg.OrdType = new OrdType(OrdType.LIMIT); msg.Symbol = new Symbol(instrumentData.Symbol); msg.Account = new Account(transaction.Account); switch (transaction.ExecutionCondition) { case OrderExecutionCondition.PutInQueue: msg.TimeInForce = new TimeInForce(TimeInForce.DAY); break; case OrderExecutionCondition.FillOrKill: msg.TimeInForce = new TimeInForce(TimeInForce.FILL_OR_KILL); break; default: SendMessage(TransactionReply.Rejected(transaction, $"Unknown execution condition: {transaction.ExecutionCondition}")); return; } switch (transaction.Operation) { case OrderOperation.Buy: msg.Side = new Side(Side.BUY); break; case OrderOperation.Sell: msg.Side = new Side(Side.SELL); break; default: SendMessage(TransactionReply.Rejected(transaction, $"Unknown operation: {transaction.Operation}")); return; } switch (transaction.Type) { case OrderType.Limit: break; default: SendMessage(TransactionReply.Rejected(transaction, $"Unsupported order type: {transaction.Type}")); return; } msg.OrderQty = new OrderQty(transaction.Quantity); msg.Price = new Price(transaction.Price); var clOrderId = _newOrderTransactions.Add(transaction); msg.ClOrdID = new ClOrdID(clOrderId); if (!string.IsNullOrEmpty(transaction.Comment)) { var comment = transaction.Comment; comment = comment.Length > 20 ? comment.Substring(0, 20) : comment; msg.SecondaryClOrdID = new SecondaryClOrdID(comment); } _orders.SaveOrderParams(transaction.TransactionId, clOrderId, msg.Symbol.Obj, msg.OrderQty.Obj, msg.Side.Obj); SendFixMessage(msg); }
private void FailDueToUnknownInstrument(Transaction transaction) { OnMessageReceived(TransactionReply.Rejected( transaction, $"Unable to find tree node for \"{transaction.Instrument.Code}\"")); }
private void OnTransactionReplyCallback(int transactionResult, int transactionExtendedErrorCode, int transactionReplyCode, uint transId, double orderNum, string transactionReplyMessage) { TransactionReply.SafeInvoke(transId, transactionResult.ToCode(), transactionExtendedErrorCode.ToCode(), (OrderStatus)transactionReplyCode, (long)orderNum, transactionReplyMessage); }
/// <summary> /// Обработать прочие транзакции /// </summary> /// <param name="transaction"> /// Транзакция для обработки /// </param> void ITransactionVisitor.Visit(Transaction transaction) { SendMessage(TransactionReply.Rejected(transaction, $"Unknown transaction type: {transaction.GetType().Name}")); }