public void Visit(ModifyOrderTransaction transaction) { var symbol = adapter.ResolveSymbolAsync(transaction.Instrument).Result; if (symbol == null) { Logger.Error().Print($"Unable to resolve symbol for {transaction.Instrument}"); return; } var newTransactionId = IncTransId(); var qlTrans = new QLTransaction { ACTION = ACTION.MOVE_ORDERS, ACCOUNT = transaction.Account, CLIENT_CODE = transaction.Account + @"//" + transaction.Comment, COMMENT = transaction.Comment, SECCODE = symbol, CLASSCODE = symbol.Length >= 5 ? "SPBOPT" : "SPBFUT", EXECUTION_CONDITION = EXECUTION_CONDITION.PUT_IN_QUEUE, TRANS_ID = newTransactionId.ToString(), TYPE = TYPE.L, FIRST_ORDER_NUMBER = transaction.OrderExchangeId, FIRST_ORDER_NEW_QUANTITY = transaction.Quantity.ToString(), FIRST_ORDER_NEW_PRICE = transaction.Price.ToString(), // TODO Тут похоже нужно проставлять ещё поле комментарий, нужно отследить по // таблице заявок квика, что становится с комментов заявки после modify }; Logger.Debug().PrintFormat("Visit: {0}", qlTrans); adapter.SendMessage(qlTrans); container.PutTransaction(newTransactionId, transaction); }
/// <summary> /// Получить транзакцию на изменение заявки по номеру заявки /// </summary> /// <param name="orderId"></param> /// <returns></returns> public ModifyOrderTransaction GetModifyOrderTransactionByOrderId(long orderId) { ModifyOrderTransaction rValue = null; using (locker.ReadLock()) { mapOrderIdOnModifyOrderTransaction.TryGetValue(orderId, out rValue); } return(rValue); }
/// <summary> /// Сохранить транзакцию на изменение заявки по её идентификатору /// </summary> /// <param name="id"></param> /// <param name="modifyOrderTransaction"></param> public void PutTransaction(long id, ModifyOrderTransaction modifyOrderTransaction) { using (locker.WriteLock()) { currentSeccionTransactionIds.Add(id); mapQuikTransIdOnModifyOrderTransaction.Add(id, modifyOrderTransaction); long orderExchangeId = long.MinValue; if (long.TryParse(modifyOrderTransaction.OrderExchangeId, out orderExchangeId)) { mapQuikTransIdOnOrderExchangeId[id] = orderExchangeId; mapOrderIdOnModifyOrderTransaction[orderExchangeId] = modifyOrderTransaction; } else { log.Error().Print( $"Can't save modify transaction. Unable to parse {LogFieldNames.ExchangeOrderId} from {modifyOrderTransaction.OrderExchangeId}" ); } } }
/// <summary> /// Обработать транзакцию <see cref="ModifyOrderTransaction"/> /// </summary> /// <param name="transaction"> /// Транзакция для обработки /// </param> void ITransactionVisitor.Visit(ModifyOrderTransaction transaction) { if (!_orders.GetOrderParams(transaction.OrderExchangeId, out var _, out var symbol, out var _, out var side)) { SendMessage(TransactionReply.Rejected(transaction, $"Unknown order: {transaction.OrderExchangeId}")); return; } var msg = new OrderCancelReplaceRequest(); msg.OrderID = new OrderID(transaction.OrderExchangeId); msg.Price = new Price(transaction.Price); msg.OrderQty = new OrderQty(transaction.Quantity); msg.Symbol = new Symbol(symbol); msg.TransactTime = new TransactTime(DateTime.UtcNow); msg.Side = new Side(side); var clOrderId = _modifyOrderTransactions.Add(transaction); msg.ClOrdID = new ClOrdID(clOrderId); SendFixMessage(msg); }
/// <summary> /// Обработать транзакцию <see cref="ModifyOrderTransaction"/> /// </summary> /// <param name="transaction"> /// Транзакция для обработки /// </param> void ITransactionVisitor.Visit(ModifyOrderTransaction transaction) { TransactionIsNotSupported(transaction); }
public void Visit(ModifyOrderTransaction transaction) { OnMessageReceived(TransactionReply.Rejected(transaction, "NotSupported")); }
/// <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")); } } }
void ITransactionVisitor.Visit(ModifyOrderTransaction transaction) { router.SendTransactionInternal(transaction); }