/// <summary> /// Submits an order to be executed by the broker /// </summary> /// <param name="order">The order to submit</param> public void SubmitOrder(Broker.Order order) { Dictionary <Broker.Order.OrderType, BasicallyMe.RobinhoodNet.OrderType> orderTypeLookup = new Dictionary <Broker.Order.OrderType, OrderType>() { { Broker.Order.OrderType.MARKET, BasicallyMe.RobinhoodNet.OrderType.Market }, { Broker.Order.OrderType.LIMIT, BasicallyMe.RobinhoodNet.OrderType.Limit }, { Broker.Order.OrderType.STOP, BasicallyMe.RobinhoodNet.OrderType.StopLoss }, { Broker.Order.OrderType.STOP_LIMIT, BasicallyMe.RobinhoodNet.OrderType.StopLoss }, }; bool isStopOrder = ((order.Type == Broker.Order.OrderType.STOP) || (order.Type == Broker.Order.OrderType.STOP_LIMIT)); NewOrderSingle newOrder = new NewOrderSingle() { AccountUrl = getAccount().AccountUrl, InstrumentUrl = Client.FindInstrument(order.Symbol).Result.First().InstrumentUrl, OrderType = orderTypeLookup[order.Type], Price = order.LimitPrice, Quantity = (int)order.Quantity, Side = ((order.BuySell == Broker.Order.BuySellType.BUY) ? Side.Buy : Side.Sell), StopPrice = (isStopOrder ? order.StopPrice : (decimal?)null), Symbol = order.Symbol, TimeInForce = TimeInForce.GoodForDay, Trigger = isStopOrder ? TriggerType.Stop : TriggerType.Immediate }; Client.PlaceOrder(newOrder).ContinueWith((result) => { OrderSnapshot orderResult = result.Result; ActiveOrders.Add(new RobinhoodOrder(order.Symbol, orderResult)); }); }
public OrderStateMachine RegisterMessage(NewOrderSingle newOrderSingle, CancellationToken cancellationToken) { var or = new OrderStateMachine(newOrderSingle, cancellationToken, this, Log); Requests[or.Id] = or; return(or); }
public static QuickFix.Message ToFixMessage(FixOrder order) { var dd = new DataDictionary(); var clOrdId = new ClOrdID(Guid.NewGuid().ToString()); int ordTypeId = (int)order.OrderType; var map = dd.GetMapForMessage(order.MsgType.ToString()); string side = ((int)order.Side).ToString(); var otherSide = side.ToString(); var orderMsg = new NewOrderSingle( clOrdId, new Side(side[0]), new TransactTime(DateTime.Now), new OrdType('2') //TODO: fix this ); orderMsg.Set(new HandlInst('1')); orderMsg.Set(new OrderQty(order.OrderQuantity)); orderMsg.Set(new TimeInForce('1')); //Day orderMsg.Set(new Price(order.Price)); return(orderMsg); }
static void PlaceOrder() { //Order settings NewOrderSingle newOrder = new NewOrderSingle(CurrentStockSymbol); newOrder.AccountUrl = Setup.UserAccount.AccountUrl; newOrder.Quantity = Math.Abs(Quantity); newOrder.Side = Side.Buy; newOrder.TimeInForce = OrderDuration; if (Price == 0) { newOrder.OrderType = OrderType.Market; } else { newOrder.OrderType = OrderType.Limit; newOrder.Price = Price; } //Places the order OrderSnapshot order = new OrderSnapshot(); try { order = Setup.Client.PlaceOrder(newOrder).Result; Console.WriteLine("Order Placed"); Console.ReadKey(); } catch { Console.WriteLine("There was a problem placing the order, might be insufficent funds or shares"); Console.ReadKey(); } }
private void Run() { var order = new NewOrderSingle( new ClOrdID("temp"), new Symbol("MSFT"), new Side(Side.BUY), new TransactTime(DateTime.UtcNow), new OrdType(OrdType.LIMIT) ) { Price = new Price(100), OrderQty = new OrderQty(1) }; Logger.Information("Starting"); for (var i = 0; i < MessagesCount; ++i) { var count = i + 1; var clOrdId = count.ToString().PadLeft(10, '0'); order.ClOrdID = new ClOrdID(clOrdId); Session.SendToTarget(order, _sessionId); if (count % 1_000 == 0) { Logger.Information($"Sent {count} NewOrderSingle messages"); } } }
public void OnMessage(NewOrderSingle order, SessionID sessionId) { var orderId = Interlocked.Increment(ref _orderSeq); var orderIdString = orderId.ToString().PadLeft(10, '0'); var report = new ExecutionReport( new OrderID(orderIdString), new ExecID(orderIdString), new ExecType(ExecType.NEW), new OrdStatus(OrdStatus.NEW), order.Symbol, order.Side, new LeavesQty(order.OrderQty.Obj), new CumQty(0), new AvgPx(0) ) { ClOrdID = order.ClOrdID }; Session.SendToTarget(report, sessionId); if (orderId % 1000 == 0) { Logger.Information($"Received & responded to {orderId} NewOrderSingle messages"); } }
public void SendNewOrderSingle(NewOrderSingle order) { SingleOrder singleOrder = order as SingleOrder; if (singleOrder.IsFilled || singleOrder.IsCancelled) { return; } this.EmitExecutionReport(new ExecutionReport { TransactTime = Clock.Now, ClOrdID = order.ClOrdID, ExecType = ExecType.New, OrdStatus = OrdStatus.New, Symbol = order.Symbol, OrdType = order.OrdType, Side = order.Side, Price = order.Price, StopPx = order.StopPx, OrderQty = order.OrderQty, CumQty = 0.0, LeavesQty = order.OrderQty, Currency = order.Currency, Text = order.Text }); new SimulationExecutionProcessor(this, order); }
public void Serialize_Empty() { var command = new NewOrderSingle(); var json = _serializer.Serialize(command); json.Should().Be("{}"); }
public static ExecutionReport CreateRejectNewOrderExecutionReport( NewOrderSingle n, string execID, string rejectionReason, int? rejectionCode = null) { var exReport = new ExecutionReport( new OrderID("unknown orderID"), new ExecID(execID), new ExecTransType(ExecTransType.NEW), new ExecType(ExecType.REJECTED), new OrdStatus(OrdStatus.REJECTED), n.Symbol, n.Side, new LeavesQty(0m), new CumQty(0m), new AvgPx(0m)); if (rejectionCode.HasValue) { exReport.OrdRejReason = new OrdRejReason(rejectionCode.Value); } exReport.Set(n.ClOrdID); exReport.Set(n.OrderQty); if (n.IsSetAccount()) exReport.SetField(n.Account); return exReport; }
public void SendNewOrderSingle(NewOrderSingle order) { Order order1 = Map.FQ_OQ_Order[(object)order] as Order; this.orderRecords.Add(order1, new OrderRecord(order as SingleOrder)); this.provider.CallSend(order1); }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var newOrderSingle = new NewOrderSingle { HandlInst = new HandlInst(HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE), Symbol = _modelConverter.ConvertLykkeSymbol(signal.Instrument.Name), Side = _modelConverter.ConvertSide(signal.TradeType), OrderQty = new OrderQty(signal.Volume), OrdType = _modelConverter.ConverOrderType(signal.OrderType), TimeInForce = new TimeInForce(TimeInForce.IMMEDIATE_OR_CANCEL), TransactTime = new TransactTime(DateTime.UtcNow), Price = new Price(signal.Price ?? 0m) }; var cts = new CancellationTokenSource(timeout); var report = await _connector.AddOrderAsync(newOrderSingle, cts.Token); var trade = _modelConverter.ConvertExecutionReport(report); try { var handlerTrade = _modelConverter.ConvertExecutionReport(report); handlerTrade.ExecType = ExecType.Trade; await _executionHandler.Handle(handlerTrade); } catch (Exception ex) { await _log.WriteErrorAsync(nameof(AddOrderAndWaitExecution), "Posting order to Jfd", ex); } return(trade); }
public void Serialize() { var message = new NewOrderSingle { MsgType = MsgTypes.NewOrderSingle, // camel case, simple string Account = 123456789, // all lower, number Price = 111111.1111M.ToFixString(), // decimal CapPrice = 0M.ToFixString(), // zero decimal ExecInst = { "exec_inst_1", "exec_inst_2" }, // array PositionId = 234567891, // "Id" serialization SLTP = { new [] { new SLTP // array, should be all lower case { // check some nested fields Price = 666666.6666M.ToFixString(), CapPrice = 0M.ToFixString(), OrdType = OrdType.Pegged, }, } } }; const string expected = "{\"msgType\":\"D\",\"price\":\"111111.1111\",\"account\":123456789," + "\"execInst\":[\"exec_inst_1\",\"exec_inst_2\"],\"positionId\":234567891,\"sltp\":[{" + "\"ordType\":\"P\",\"price\":\"666666.6666\"}]}"; var json = _serializer.Serialize(message); json.Should().Be(expected); }
public void SendNewOrderSingle(NewOrderSingle order) { Order order2 = Map.SQ_OQ_Order[order] as Order; this.orderRecords.Add(order2, new OrderRecord(order as SingleOrder)); this.provider.CallSend(order2); }
public Message CreateNewOrderSingleMessage(string symbol, MarketSide marketSide, string clOrdID, TradingAccount account, decimal price, decimal quantity, OrderType orderType, string execID) { var fOrdType = TranslateFixFields.Translate(orderType); var fSide = TranslateFixFields.Translate(marketSide); var fSymbol = new Symbol(symbol); var fTransactTime = new TransactTime(DateTime.Now); var fClOrdID = new ClOrdID(clOrdID); var nos = new NewOrderSingle(fClOrdID, fSymbol, fSide, fTransactTime, fOrdType) { OrderQty = new OrderQty(quantity), TimeInForce = new TimeInForce(TimeInForce.GOOD_TILL_CANCEL) }; if (orderType == OrderType.Limit) { nos.Price = new Price(price); } return(nos); }
public void SendNewOrderSingle(NewOrderSingle order) { SingleOrder key = order as SingleOrder; orderRecords.Add(key, new OrderRecord(key)); Send(key); }
public static ExecutionReport CreateRejectNewOrderExecutionReport( NewOrderSingle n, string execID, string rejectionReason, int?rejectionCode = null) { var exReport = new ExecutionReport( new OrderID("unknown orderID"), new ExecID(execID), new ExecTransType(ExecTransType.NEW), new ExecType(ExecType.REJECTED), new OrdStatus(OrdStatus.REJECTED), n.Symbol, n.Side, new LeavesQty(0m), new CumQty(0m), new AvgPx(0m)); if (rejectionCode.HasValue) { exReport.OrdRejReason = new OrdRejReason(rejectionCode.Value); } exReport.Set(n.ClOrdID); exReport.Set(n.OrderQty); if (n.IsSetAccount()) { exReport.SetField(n.Account); } return(exReport); }
public void SendNewOrderSingle(string symbol, int quantity, decimal? price, decimal? stop, decimal? gain, string account, SessionID session) { clOrdId = DateTime.Now.Ticks.ToString(); lastSymbol = symbol; lastAccount = account; var newOrderSingle = new NewOrderSingle(new ClOrdID(clOrdId), new Symbol(symbol), new Side(Side.BUY), new TransactTime(DateTime.Now), new OrdType(gain.HasValue ? 'X' : stop.HasValue ? OrdType.STOP : price.HasValue ? OrdType.LIMIT : OrdType.MARKET)) { Account = new Account(account), OrderQty = new OrderQty(quantity), TargetStrategy = new TargetStrategy(TargetStrategy), TimeInForce = new TimeInForce(TIF), }; if (TIF == TimeInForce.GOOD_TILL_DATE) newOrderSingle.ExpireDate = new ExpireDate(DateTime.Today.AddDays(1).AsLocalMktDate()); if (stop.HasValue) newOrderSingle.StopPx = new StopPx(stop.Value); if (price.HasValue) newOrderSingle.Price = new Price(price.Value); if (gain.HasValue) newOrderSingle.SetField(new DecimalField(6001, gain.Value)); Session.SendToTarget(newOrderSingle, session); }
public static void AddStopLoss(this NewOrderSingle command, decimal stopPrice) { command.SLTP.Add(new SLTP { OrdType = OrdType.Stop, StopPx = stopPrice.ToFixString() }); }
public static void AddTakeProfit(this NewOrderSingle command, decimal price) { command.SLTP.Add(new SLTP { OrdType = OrdType.Limit, Price = price.ToFixString() }); }
/// <summary> /// Creates and returns a new <see cref="NewOrderSingle"/> FIX message. /// </summary> /// <param name="accountNumber">The account number.</param> /// <param name="order">The order to submit.</param> /// <param name="positionIdBroker">The optional broker position identifier.</param> /// <param name="timeNow">The time now.</param> /// <returns>The FIX message.</returns> public static NewOrderSingle Create( AccountNumber accountNumber, Order order, PositionIdBroker?positionIdBroker, ZonedDateTime timeNow) { Debug.NotDefault(timeNow, nameof(timeNow)); var message = new NewOrderSingle(); message.SetField(new ClOrdID(order.Id.Value)); message.SetField(new Account(accountNumber.Value)); message.SetField(new Symbol(order.Symbol.Code)); message.SetField(FxcmMessageHelper.GetFixOrderSide(order.OrderSide)); message.SetField(FxcmMessageHelper.GetFixOrderType(order.OrderType)); message.SetField(FxcmMessageHelper.GetFixTimeInForce(order.TimeInForce)); message.SetField(new OrderQty(order.Quantity.Value)); message.SetField(new TransactTime(timeNow.ToDateTimeUtc())); if (!(positionIdBroker is null)) { message.SetField(new StringField(FxcmTags.PosID, positionIdBroker.Value)); } if (order.ExpireTime.HasValue) { var expireTime = FxcmMessageHelper.ToExpireTimeFormat(order.ExpireTime.Value); message.SetField(new StringField(126, expireTime)); } // Add price if (order.Price?.Value != null) { switch (order.OrderType) { case OrderType.Limit: message.SetField(new Price(order.Price.Value)); break; case OrderType.Stop: message.SetField(new StopPx(order.Price.Value)); break; case OrderType.StopLimit: message.SetField(new StopPx(order.Price.Value)); break; case OrderType.Market: case OrderType.Undefined: goto default; default: throw ExceptionFactory.InvalidSwitchArgument(order.OrderType, nameof(order.OrderType)); } } return(message); }
private static void nKWRNT2TM(object sender, FIXNewOrderSingleEventArgs e) { NewOrderSingle order = e.NewOrderSingle as NewOrderSingle; if (ServiceManager.NewOrderSingle != null) { ServiceManager.NewOrderSingle(typeof(ServiceManager), new NewOrderSingleEventArgs(sender as IExecutionService, order)); } }
public Task <ExecutionReport> AddOrderAsync(NewOrderSingle order, CancellationToken cancellationToken) { EnsureCanHandleRequest(); lock (RejectLock) { var request = _ordersHandler.RegisterMessage(order, cancellationToken); SendRequest(request.Message); RegisterForRejectResponse(request); var result = request.Send(); return(result); } }
public static NewOrderSingle CrearNewOrderSinglePorString(string fixString) { var defaultMsgFactory = new DefaultMessageFactory(); var dataDictionary = new QuickFix.DataDictionary.DataDictionary(); //https://www.tradingtechnologies.com/xtrader-help/apis/fix-adapter/fix-adapter-resources/ dataDictionary.Load(AppDomain.CurrentDomain.BaseDirectory + "\\FIX42.xml"); var mensaje = new NewOrderSingle(); mensaje.FromString(fixString, false, dataDictionary, dataDictionary, defaultMsgFactory); return(mensaje); }
public override void SendNewOrderSingle(NewOrderSingle order) { if (!order.ContainsField(1) && !string.IsNullOrWhiteSpace(this.DefaultAccount)) { order.Account = this.DefaultAccount.Trim(); } if (!order.ContainsField(109) && !string.IsNullOrWhiteSpace(this.DefaultClientID)) { order.SetStringValue(109, this.DefaultClientID.Trim()); } base.SendNewOrderSingle(order); }
public void WrapMessage_Fail() { // arrange var badFormattedFixMessage = "abcdefg"; var fmNewOrder = new NewOrderSingle(); fmNewOrder = null; // fmNewOrder.FromStringHeader(badFormattedFixMessage); var pseudoHeader = "toCounteryPartyInfo"; // act + assert Assert.Throws <NullReferenceException>(() => _jsonFixWrapper.Wrap(fmNewOrder, pseudoHeader)); }
/// <summary> /// Translate FIX44 NewOrderSingle message to OrderData /// </summary> /// <param name="newOrder">The message</param> /// <returns>The order data</returns> /// <exception cref="QuickFix.IncorrectTagValue"></exception> private static Order Convert(NewOrderSingle newOrder) { ValidateIsSupportedOrderType(newOrder.OrdType); return(Convert(MessageType.NewOrderSingle, newOrder.Symbol, newOrder.Side, newOrder.OrdType, newOrder.OrderQty, newOrder.Price, newOrder.ClOrdID, newOrder.IsSetAccount() ? newOrder.Account : null)); }
private void lCXP6mCfhb(NewOrderSingle e) { SingleOrder singleOrder = e as SingleOrder; if (singleOrder.IsFilled || singleOrder.IsCancelled) { return; } if (e.OrderQty > 0.0) { ExecutionReport report = new ExecutionReport(); report.TransactTime = Clock.Now; report.ClOrdID = e.ClOrdID; report.ExecType = ExecType.New; report.OrdStatus = OrdStatus.New; report.Symbol = e.Symbol; report.OrdType = e.OrdType; report.Side = e.Side; report.Price = e.Price; report.StopPx = e.StopPx; report.TrailingAmt = e.TrailingAmt; report.OrderQty = e.OrderQty; report.CumQty = 0.0; report.LeavesQty = e.OrderQty; report.Currency = e.Currency; report.Text = e.Text; this.JPVPJSWclF(report); zo21q6cy3fImtUHATQ zo21q6cy3fImtUhatq = new zo21q6cy3fImtUHATQ(this, e); } else { ExecutionReport report = new ExecutionReport(); report.TransactTime = DateTime.Now; report.ClOrdID = e.ClOrdID; report.ExecType = ExecType.Rejected; report.OrdStatus = OrdStatus.Rejected; report.Symbol = e.Symbol; report.OrdType = e.OrdType; report.Side = e.Side; report.Price = e.Price; report.StopPx = e.StopPx; report.TrailingAmt = e.TrailingAmt; report.OrderQty = e.OrderQty; report.CumQty = 0.0; report.LeavesQty = e.OrderQty; report.Currency = e.Currency; report.Text = e.Text; this.JPVPJSWclF(report); } }
public SingleOrder() : base() { this.reports = new ExecutionReportList(); this.rejects = new OrderCancelRejectList(); this.replaceOrder = new NewOrderSingle(); this.ClOrdID = OrderManager.GetOrdId(); this.OrdStatus = OrdStatus.PendingNew; this.HandlInst = '1'; this.TimeInForce = TimeInForce.Day; this.Currency = Framework.Configuration.DefaultCurrency; this.Persistent = false; this.IsSent = false; }
/// <summary> /// Tratamento do New Order Single - Efetuar inserção na tabela Ordem /// </summary> /// <param name="nos"></param> /// <param name="s"></param> public void OnMessage(NewOrderSingle nos, SessionID s) { try { TODropCopyDB to = new TODropCopyDB(); to.MensagemQF = nos; to.Sessao = s; to.TipoMsg = MsgType.NEWORDERSINGLE; this._addMessage(to); } catch (Exception ex) { logger.Error("Problemas no processamento da mensagem NewOrderSingle: " + ex.Message, ex); } }
/// <summary> /// Create FIX Order /// </summary> /// <param name="order"></param> /// <returns></returns> private NewOrderSingle CreateFixOrder(Order order) { QuickFix.FIX42.NewOrderSingle orderSingle = new NewOrderSingle(); //set id orderSingle.Set(new ClOrdID(order.OrderID)); //set account orderSingle.Set(new Account(_account)); //set handle inst orderSingle.Set(new HandlInst(HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE)); //set symbol orderSingle.Set(new Symbol(order.Security.Symbol)); //set locate required orderSingle.Set(new LocateReqd(LocateReqd.NO)); //set time in force orderSingle.Set(new TimeInForce(TimeInForce.DAY)); //set destination orderSingle.Set(new ExDestination(order.Exchange)); //set date time orderSingle.Set(new TransactTime(order.OrderDateTime)); //set order size orderSingle.Set(new OrderQty(order.OrderSize)); //set order side if (order.OrderSide == OrderSide.BUY) { orderSingle.Set(new Side(Side.BUY)); } else if (order.OrderSide == OrderSide.SELL) { orderSingle.Set(new Side(Side.SELL)); } else if (order.OrderSide == OrderSide.SHORT) { orderSingle.Set(new Side(Side.SELL)); orderSingle.Set(new LocateReqd(LocateReqd.YES)); } //only limit and market orders are supported. if (order.GetType() == typeof(LimitOrder)) { orderSingle.Set(new OrdType(OrdType.LIMIT)); orderSingle.Set(new Price(((LimitOrder)order).LimitPrice)); } else if (order.GetType() == typeof(MarketOrder)) { orderSingle.Set(new OrdType(OrdType.MARKET)); } return(orderSingle); }
public NewOrderSingle CreateNewOrderSingle(TradingSignal tradingSignal) { var newOrderSingle = new NewOrderSingle { Symbol = new Symbol(LykkeSymbolToExchangeSymbol(tradingSignal.Instrument.Name)), Currency = new Currency(tradingSignal.Instrument.Base), Side = ConvertSide(tradingSignal.TradeType), OrderQty = new OrderQty(tradingSignal.Volume), OrdType = ConvertOrderType(tradingSignal.OrderType), TimeInForce = new TimeInForce(TimeInForce.IMMEDIATE_OR_CANCEL), TransactTime = new TransactTime(DateTime.UtcNow), Price = new Price(tradingSignal.Price ?? 0m) }; return(newOrderSingle); }
public static void AddTrailingStopLoss(this NewOrderSingle command, decimal trailingOffset, decimal capPrice = 0) { var sltp = new SLTP { OrdType = OrdType.Stop, PegPriceType = PegPriceType.TrailingStopPeg, PegOffsetType = PegOffsetType.BasisPoints, PegOffsetValue = trailingOffset.ToFixString(), }; if (capPrice != 0) { sltp.CapPrice = capPrice.ToFixString(); } command.SLTP.Add(sltp); }
public void OnMessage(NewOrderSingle n, SessionID sessionID) { var execID = _execIdGenerator(); try { var orderData = TranslateFixMessages.Translate(n); _commandFactory.EnqueueAddOrder(_messageGenerator, sessionID, orderData, execID); } catch (QuickFIXException e) { var rejectMessage = "Unable to add order: " + e.Message; var message = CreateFix44Message.CreateRejectNewOrderExecutionReport(n, execID, rejectMessage); _fixFacade.SendToTarget(message, sessionID); } }
private void Send(NewOrderSingle order) { if (!_bTdConnected) { EmitError(-1,-1,"交易服务器没有连接,无法报单"); return; } Instrument inst = InstrumentManager.Instruments[order.Symbol]; string altSymbol = inst.GetSymbol(this.Name); string altExchange = inst.GetSecurityExchange(this.Name); //最小变动价格修正 double price; //没有设置就直接用 if (inst.TickSize > 0) { //将价格调整为最小价格的整数倍,此处是否有问题?到底应当是向上调还是向下调呢?此处先这样 double num = 0; if (order.Side == Side.Buy) { num = Math.Round(order.Price / inst.TickSize, 0, MidpointRounding.AwayFromZero); //num = Math.Ceiling(order.Price / inst.TickSize); } else { num = Math.Round(order.Price / inst.TickSize, 0, MidpointRounding.AwayFromZero); //num = Math.Floor(order.Price / inst.TickSize); } price = inst.TickSize * num; //string PF = string.Format("{{0:{0}}}", inst.PriceDisplay); //price = Convert.ToDouble(string.Format(PF, price)); } else { price = order.Price; } //市价修正,如果不连接行情,此修正不执行,得策略层处理 CThostFtdcDepthMarketDataField DepthMarket; if (_dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket)) { if (price >= DepthMarket.UpperLimitPrice) price = DepthMarket.UpperLimitPrice; else if (price <= DepthMarket.LowerLimitPrice) price = DepthMarket.LowerLimitPrice; //如果是市价单,先调整价格 if (OrdType.Market == order.OrdType) price = order.Side == Side.Buy ? DepthMarket.UpperLimitPrice : DepthMarket.LowerLimitPrice; } else { //没有订阅行情价,是否改用交易接口补上行情? } int YdPosition = 0; int TodayPosition = 0; string szCombOffsetFlag; if (order.Side == Side.Buy) { //买,先看有没有空单,有就平空单,没有空单,直接买开多单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Short, TThostFtdcHedgeFlagType.Speculation, out YdPosition, out TodayPosition); } else//是否要区分Side.Sell与Side.SellShort呢? { //卖,先看有没有多单,有就平多单,没有多单,直接买开空单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Long, TThostFtdcHedgeFlagType.Speculation, out YdPosition, out TodayPosition); } List<SOrderSplitItem> OrderSplitList = new List<SOrderSplitItem>(); SOrderSplitItem orderSplitItem; //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能 int nOpenCloseFlag = 0; if (order.Text.StartsWith(OpenPrefix)) { nOpenCloseFlag = 1; } else if (order.Text.StartsWith(ClosePrefix)) { nOpenCloseFlag = -1; } int leave = (int)order.OrderQty; //是否上海?上海先平今,然后平昨,最后开仓 //使用do主要是想利用break功能 //平仓部分 do { //指定开仓,直接跳过 if (1 == nOpenCloseFlag) break; if (SupportCloseToday.Contains(altExchange)) { //先看平今 if (leave > 0 && TodayPosition > 0) { int min = Math.Min(TodayPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } if (leave > 0 && YdPosition > 0) { int min = Math.Min(YdPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } else { //平仓 int position = TodayPosition + YdPosition; if (leave > 0 && position > 0) { int min = Math.Min(position, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Close, (byte)TThostFtdcOffsetFlagType.Close }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } } while (false); do { //指定平仓,直接跳过 if (-1 == nOpenCloseFlag) break; if (leave > 0) { byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Open, (byte)TThostFtdcOffsetFlagType.Open }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = leave; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); leave = 0; } } while (false); if (leave > 0) { string strErr = string.Format("CTP:还剩余{0}手,你应当是强制指定平仓了,但持仓数小于要平手数", leave); Console.WriteLine(strErr); EmitError(-1, -1, strErr); } //将第二腿也设置成一样,这样在使用组合时这地方不用再调整 byte[] bytes2 = { (byte)HedgeFlagType, (byte)HedgeFlagType }; string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length); bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange); foreach (SOrderSplitItem it in OrderSplitList) { int nRet = 0; switch (order.OrdType) { case OrdType.Limit: nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, price, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); break; case OrdType.Market: if (bSupportMarketOrder) { nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, 0, TThostFtdcOrderPriceTypeType.AnyPrice, TThostFtdcTimeConditionType.IOC, TThostFtdcContingentConditionType.Immediately, order.StopPx); } else { nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, price, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); } break; default: EmitError(-1, -1, string.Format("没有实现{0}", order.OrdType)); break; } if (nRet > 0) { _OrderRef2Order.Add(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), order as SingleOrder); } } }
public void OnMessage(NewOrderSingle n, SessionID sessionID) { _fix44MessageHandler.OnMessage(n, sessionID); }
public void SendNewOrderSingle(NewOrderSingle order) { Order order2 = Map.SQ_OQ_Order[order] as Order; this.orderRecords.Add(order2, new OrderRecord(order as SingleOrder)); this.provider.CallSend(order2); }
public void ProcessNewOrderSingle(NewOrderSingle nos) { }
public void ProcessOrderCancelRequest(NewOrderSingle nos, OrderCancelRequest msg) { }
private void Send(NewOrderSingle order) { if (order == null) return; if (!_bTdConnected) { EmitError(-1, -1, "交易服务器没有连接,无法报单"); tdlog.Error("交易服务器没有连接,无法报单"); return; } Instrument inst = InstrumentManager.Instruments[order.Symbol]; string altSymbol = inst.GetSymbol(Name); string altExchange = inst.GetSecurityExchange(Name); double tickSize = inst.TickSize; string type = inst.SecurityType; // CThostFtdcInstrumentField _Instrument; // if (_dictInstruments.TryGetValue(altSymbol, out _Instrument)) // { // //从合约列表中取交易所名与tickSize,不再依赖用户手工设置的参数了 // tickSize = _Instrument.PriceTick; // altExchange = _Instrument.ExchangeID; // } //最小变动价格修正 double price = order.Price; //市价修正,如果不连接行情,此修正不执行,得策略层处理 DFITCDepthMarketDataField DepthMarket; //如果取出来了,并且为有效的,涨跌停价将不为0 _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket); // 市价单模拟 if (OrdType.Market == order.OrdType) { //按买卖调整价格 if (order.Side == Side.Buy) { price = DepthMarket.LastPrice + LastPricePlusNTicks * tickSize; } else { price = DepthMarket.LastPrice - LastPricePlusNTicks * tickSize; } } //没有设置就直接用 if (tickSize > 0) { decimal remainder = ((decimal)price % (decimal)tickSize); if (remainder != 0) { if (order.Side == Side.Buy) { price = Math.Ceiling(price / tickSize) * tickSize; } else { price = Math.Floor(price / tickSize) * tickSize; } } else { //正好能整除,不操作 } } if (0 == DepthMarket.UpperLimitPrice && 0 == DepthMarket.LowerLimitPrice) { //涨跌停无效 } else { //防止价格超过涨跌停 if (price >= DepthMarket.UpperLimitPrice) price = DepthMarket.UpperLimitPrice; else if (price <= DepthMarket.LowerLimitPrice) price = DepthMarket.LowerLimitPrice; } DFITCOpenCloseTypeType szCombOffsetFlag; //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能 if (order.Text.StartsWith(OpenPrefix)) { szCombOffsetFlag = DFITCOpenCloseTypeType.OPEN; } else if (order.Text.StartsWith(ClosePrefix)) { szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSE; } else if (order.Text.StartsWith(CloseTodayPrefix)) { szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSETODAY; } else if (order.Text.StartsWith(CloseYesterdayPrefix)) { szCombOffsetFlag = DFITCOpenCloseTypeType.CLOSE; } else if (order.Text.StartsWith(ExecutePrefix)) { szCombOffsetFlag = DFITCOpenCloseTypeType.EXECUTE; } else { szCombOffsetFlag = DFITCOpenCloseTypeType.OPEN; } DFITCInsertType insertType = DFITCInsertType.BASIC_ORDER; if(order.Text.Length>=3) { if(order.Text[2] == '*') { insertType = DFITCInsertType.AUTO_ORDER; } } int leave = (int)order.OrderQty; DFITCSpeculatorType szCombHedgeFlag = SpeculatorType; bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange); tdlog.Info("Side:{0},Price:{1},LastPrice:{2},Qty:{3},Text:{4}", order.Side, order.Price, DepthMarket.LastPrice, order.OrderQty, order.Text); DFITCBuySellTypeType sBuySellType = order.Side == Side.Buy ? DFITCBuySellTypeType.BUY : DFITCBuySellTypeType.SELL; DFITCOrderTypeType orderType = DFITCOrderTypeType.LIMITORDER; DFITCOrderPropertyType orderProperty = DFITCOrderPropertyType.NON; DFITCInstrumentTypeType nInstrumentType = (FIXSecurityType.FutureOption == type) ? DFITCInstrumentTypeType.OPT_TYPE : DFITCInstrumentTypeType.COMM_TYPE; switch(order.TimeInForce) { case TimeInForce.IOC: orderProperty = DFITCOrderPropertyType.FAK; break; case TimeInForce.FOK: orderProperty = DFITCOrderPropertyType.FOK; break; default: break; } int nRet = 0; switch (order.OrdType) { case OrdType.Limit: break; case OrdType.Market: if (SwitchMakertOrderToLimitOrder || !bSupportMarketOrder) { } else { //price = 0; orderType = DFITCOrderTypeType.MKORDER; } break; default: tdlog.Warn("没有实现{0}", order.OrdType); return; } nRet = TraderApi.TD_SendOrder(m_pTdApi,-1, altSymbol, sBuySellType, szCombOffsetFlag, szCombHedgeFlag, leave, price, orderType, orderProperty, nInstrumentType, insertType); if (nRet > 0) { _OrderRef2Order[string.Format("{0}:{1}",_RspUserLogin.sessionID,nRet)] = order as SingleOrder; } }
public Message CreateNewOrderSingleMessage(string symbol, MarketSide marketSide, string clOrdID, TradingAccount account, decimal price, decimal quantity, OrderType orderType, string execID) { var fOrdType = TranslateFixFields.Translate(orderType); var fSide = TranslateFixFields.Translate(marketSide); var fSymbol = new Symbol(symbol); var fTransactTime = new TransactTime(DateTime.Now); var fClOrdID = new ClOrdID(clOrdID); var nos = new NewOrderSingle(fClOrdID, fSymbol, fSide, fTransactTime, fOrdType) { OrderQty = new OrderQty(quantity), TimeInForce = new TimeInForce(TimeInForce.GOOD_TILL_CANCEL) }; if (orderType == OrderType.Limit) nos.Price = new Price(price); return nos; }
private void Send(NewOrderSingle order) { if (!_bTdConnected) { EmitError(-1,-1,"交易服务器没有连接,无法报单"); return; } Instrument inst = InstrumentManager.Instruments[order.Symbol]; string altSymbol = inst.GetSymbol(this.Name); string altExchange = inst.GetSecurityExchange(this.Name); double price; CThostFtdcDepthMarketDataField DepthMarket; if (_dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket)) { //没有设置就直接用 if (inst.TickSize > 0) { //将价格调整为最小价格的整数倍,此处是否有问题?到底应当是向上调还是向下调呢? double num = Math.Round(order.Price / inst.TickSize, 0, MidpointRounding.AwayFromZero); price = inst.TickSize * num; string PF = string.Format("{{0:{0}}}", inst.PriceDisplay); price = Convert.ToDouble(string.Format(PF, price)); } else { price = order.Price; } //市价修正 if (price >= DepthMarket.UpperLimitPrice) price = DepthMarket.UpperLimitPrice; else if (price <= DepthMarket.LowerLimitPrice) price = DepthMarket.LowerLimitPrice; int YdPosition = 0; int TodayPosition = 0; string szCombOffsetFlag; if (order.Side == Side.Buy) { //买,先看有没有空单,有就平空单,没有空单,直接买开多单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Short, TThostFtdcHedgeFlagType.Speculation, out YdPosition, out TodayPosition); } else//是否要区分Side.Sell与Side.SellShort呢? { //卖,先看有没有多单,有就平多单,没有多单,直接买开空单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Long, TThostFtdcHedgeFlagType.Speculation, out YdPosition, out TodayPosition); } List<SOrderSplitItem> OrderSplitList = new List<SOrderSplitItem>(); SOrderSplitItem orderSplitItem; //是否上海?上海先平今,然后平昨,最后开仓 int leave = (int)order.OrderQty; if (SupportCloseToday.Contains(altExchange)) { //先看平今 if (leave > 0 && TodayPosition > 0) { int min = Math.Min(TodayPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } if (leave > 0 && YdPosition > 0) { int min = Math.Min(YdPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } else { int position = TodayPosition + YdPosition; if (leave > 0 && position > 0) { int min = Math.Min(position, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Close, (byte)TThostFtdcOffsetFlagType.Close }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } if (leave > 0) { byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Open, (byte)TThostFtdcOffsetFlagType.Open }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = leave; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } //目前默认只支持投机,并且将第二腿也设置成投机,这样在使用组合时这地方不用再调整 //byte[] bytes = { (byte)TThostFtdcHedgeFlagType.Speculation, (byte)TThostFtdcHedgeFlagType.Speculation }; //string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); string szCombHedgeFlag = "11";//这样好直接啊!两个投机 foreach (SOrderSplitItem it in OrderSplitList) { int nRet = 0; switch (order.OrdType) { case OrdType.Limit: nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, price, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); break; case OrdType.Market: nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, order.Side == Side.Buy ? DepthMarket.UpperLimitPrice : DepthMarket.LowerLimitPrice, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); break; default: EmitError(-1, -1, string.Format("没有实现{0}", order.OrdType)); break; } if (nRet > 0) { _OrderRef2Order.Add(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), order as SingleOrder); } } } }
public void RegisterOrder(NewOrderSingle order) { }
private void Send(NewOrderSingle order) { if (!_bTdConnected) { EmitError(-1,-1,"交易服务器没有连接,无法报单"); tdlog.Error("交易服务器没有连接,无法报单"); return; } Instrument inst = InstrumentManager.Instruments[order.Symbol]; string altSymbol = inst.GetSymbol(Name); string altExchange = inst.GetSecurityExchange(Name); double tickSize = inst.TickSize; CThostFtdcInstrumentField _Instrument; if (_dictInstruments.TryGetValue(altSymbol, out _Instrument)) { //从合约列表中取交易所名与tickSize,不再依赖用户手工设置的参数了 tickSize = _Instrument.PriceTick; altExchange = _Instrument.ExchangeID; } //最小变动价格修正 double price = order.Price; //市价修正,如果不连接行情,此修正不执行,得策略层处理 CThostFtdcDepthMarketDataField DepthMarket; //如果取出来了,并且为有效的,涨跌停价将不为0 _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket); //市价单模拟 if (OrdType.Market == order.OrdType) { //按买卖调整价格 if (order.Side == Side.Buy) { price = DepthMarket.LastPrice + LastPricePlusNTicks * tickSize; } else { price = DepthMarket.LastPrice - LastPricePlusNTicks * tickSize; } } //没有设置就直接用 if (tickSize > 0) { decimal remainder = ((decimal)price % (decimal)tickSize); if (remainder != 0) { if (order.Side == Side.Buy) { price = Math.Ceiling(price / tickSize) * tickSize; } else { price = Math.Floor(price / tickSize) * tickSize; } } else { //正好能整除,不操作 } } if (0 == DepthMarket.UpperLimitPrice && 0 == DepthMarket.LowerLimitPrice) { //涨跌停无效 } else { //防止价格超过涨跌停 if (price >= DepthMarket.UpperLimitPrice) price = DepthMarket.UpperLimitPrice; else if (price <= DepthMarket.LowerLimitPrice) price = DepthMarket.LowerLimitPrice; } int YdPosition = 0; int TodayPosition = 0; string szCombOffsetFlag; if (order.Side == Side.Buy) { //买,先看有没有空单,有就平空单,没有空单,直接买开多单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Short, HedgeFlagType, out YdPosition, out TodayPosition);//TThostFtdcHedgeFlagType.Speculation } else//是否要区分Side.Sell与Side.SellShort呢? { //卖,先看有没有多单,有就平多单,没有多单,直接买开空单 _dbInMemInvestorPosition.GetPositions(altSymbol, TThostFtdcPosiDirectionType.Long, HedgeFlagType, out YdPosition, out TodayPosition); } tdlog.Info("Side:{0},Price:{1},LastPrice:{2},Qty:{3},Text:{4},YdPosition:{5},TodayPosition:{6}", order.Side, order.Price, DepthMarket.LastPrice, order.OrderQty, order.Text, YdPosition, TodayPosition); List<SOrderSplitItem> OrderSplitList = new List<SOrderSplitItem>(); SOrderSplitItem orderSplitItem; //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能 int nOpenCloseFlag = 0; if (order.Text.StartsWith(OpenPrefix)) { nOpenCloseFlag = 1; } else if (order.Text.StartsWith(ClosePrefix)) { nOpenCloseFlag = -1; } else if (order.Text.StartsWith(CloseTodayPrefix)) { nOpenCloseFlag = -2; } else if (order.Text.StartsWith(CloseYesterdayPrefix)) { nOpenCloseFlag = -3; } int leave = (int)order.OrderQty; //是否上海?上海先平今,然后平昨,最后开仓 //使用do主要是想利用break功能 //平仓部分 do { //指定开仓,直接跳过 if (nOpenCloseFlag>0) break; //表示指定平今与平昨 if (nOpenCloseFlag<-1) { if (-2 == nOpenCloseFlag) { byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); } else { //肯定是-3了 byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); } orderSplitItem.qty = leave; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); leave = 0; break; } if (SupportCloseToday.Contains(altExchange)) { //先看平今 if (leave > 0 && TodayPosition > 0) { int min = Math.Min(TodayPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseToday, (byte)TThostFtdcOffsetFlagType.CloseToday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } if (leave > 0 && YdPosition > 0) { int min = Math.Min(YdPosition, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.CloseYesterday, (byte)TThostFtdcOffsetFlagType.CloseYesterday }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } else { //平仓 int position = TodayPosition + YdPosition; if (leave > 0 && position > 0) { int min = Math.Min(position, leave); leave -= min; byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Close, (byte)TThostFtdcOffsetFlagType.Close }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = min; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); } } } while (false); do { //指定平仓,直接跳过 if (nOpenCloseFlag<0) break; if (leave > 0) { byte[] bytes = { (byte)TThostFtdcOffsetFlagType.Open, (byte)TThostFtdcOffsetFlagType.Open }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = leave; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); leave = 0; } } while (false); if (leave > 0) { tdlog.Info("CTP:还剩余{0}手,你应当是强制指定平仓了,但持仓数小于要平手数", leave); } //将第二腿也设置成一样,这样在使用组合时这地方不用再调整 byte[] bytes2 = { (byte)HedgeFlagType, (byte)HedgeFlagType }; string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length); bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange); foreach (SOrderSplitItem it in OrderSplitList) { int nRet = 0; switch (order.OrdType) { case OrdType.Limit: nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, price, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); break; case OrdType.Market: if (bSupportMarketOrder) { nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, 0, TThostFtdcOrderPriceTypeType.AnyPrice, TThostFtdcTimeConditionType.IOC, TThostFtdcContingentConditionType.Immediately, order.StopPx); } else { nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, order.Side == Side.Buy ? TThostFtdcDirectionType.Buy : TThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, price, TThostFtdcOrderPriceTypeType.LimitPrice, TThostFtdcTimeConditionType.GFD, TThostFtdcContingentConditionType.Immediately, order.StopPx); } break; default: tdlog.Warn("没有实现{0}", order.OrdType); break; } if (nRet > 0) { _OrderRef2Order.Add(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), order as SingleOrder); } } }
private void Send(NewOrderSingle order) { if (!_bTdConnected) { EmitError(-1, -1, "交易服务器没有连接,无法报单"); tdlog.Error("交易服务器没有连接,无法报单"); return; } // 表示特殊的Json格式 if (order.Text.StartsWith("{") && order.Text.EndsWith("}")) { TextParameter parameter = JsonConvert.DeserializeObject<TextParameter>(order.Text); switch (parameter.Type) { case EnumGroupType.COMMON: { TextCommon t = JsonConvert.DeserializeObject<TextCommon>(order.Text); CommonOrderItem item = CommonOrderCombiner.Add(order as SingleOrder, t); Send(item); } break; case EnumGroupType.QUOTE: { TextQuote t = JsonConvert.DeserializeObject<TextQuote>(order.Text); QuoteOrderItem item = QuoteOrderCombiner.Add(order as SingleOrder, t); } break; case EnumGroupType.SP: { TextSP t = JsonConvert.DeserializeObject<TextSP>(order.Text); SPOrderItem item = SPOrderCombiner.Add(order as SingleOrder, t); Send(item); } break; case EnumGroupType.SPC: { TextSPC t = JsonConvert.DeserializeObject<TextSPC>(order.Text); SPCOrderItem item = SPCOrderCombiner.Add(order as SingleOrder, t); Send(item); } break; case EnumGroupType.SPD: { TextSPD t = JsonConvert.DeserializeObject<TextSPD>(order.Text); SPDOrderItem item = SPDOrderCombiner.Add(order as SingleOrder, t); Send(item); } break; } } else { // 无法识别的格式,直接发送报单,只开仓 TextCommon t = new TextCommon() { Type = EnumGroupType.COMMON, OpenClose = EnumOpenClose.OPEN }; CommonOrderItem item = CommonOrderCombiner.Add(order as SingleOrder, t); Send(item); } }
private void Send(NewOrderSingle order) { if (!_bTdConnected) { EmitError(-1,-1,"交易服务器没有连接,无法报单"); return; } Instrument inst = InstrumentManager.Instruments[order.Symbol]; string altSymbol = inst.GetSymbol(this.Name); string altExchange = inst.GetSecurityExchange(this.Name); double tickSize = inst.TickSize; CZQThostFtdcInstrumentField _Instrument; if (_dictInstruments.TryGetValue(altSymbol, out _Instrument)) { //从合约列表中取交易所名与tickSize,不再依赖用户手工设置的参数了 tickSize = _Instrument.PriceTick; altExchange = _Instrument.ExchangeID; } //最小变动价格修正 double price = order.Price; //市价修正,如果不连接行情,此修正不执行,得策略层处理 CZQThostFtdcDepthMarketDataField DepthMarket; //如果取出来了,并且为有效的,涨跌停价将不为0 _dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket); //市价单模拟 if (OrdType.Market == order.OrdType) { //按买卖调整价格 if (order.Side == Side.Buy) { price = DepthMarket.LastPrice + LastPricePlusNTicks * tickSize; } else { price = DepthMarket.LastPrice - LastPricePlusNTicks * tickSize; } } //没有设置就直接用 if (tickSize > 0) { //将价格调整为最小价格的整数倍,此处是否有问题?到底应当是向上调还是向下调呢?此处先这样 double num = 0; if (order.Side == Side.Buy) { num = Math.Round(price / tickSize, 0, MidpointRounding.AwayFromZero); } else { num = Math.Round(price / tickSize, 0, MidpointRounding.AwayFromZero); } price = tickSize * num; } if (0 == DepthMarket.UpperLimitPrice && 0 == DepthMarket.LowerLimitPrice) { //涨跌停无效 } else { //防止价格超过涨跌停 if (price >= DepthMarket.UpperLimitPrice) price = DepthMarket.UpperLimitPrice; else if (price <= DepthMarket.LowerLimitPrice) price = DepthMarket.LowerLimitPrice; } int YdPosition = 0; int TodayPosition = 0; int nLongFrozen = 0; int nShortFrozen = 0; string szCombOffsetFlag; _dbInMemInvestorPosition.GetPositions(altSymbol, TZQThostFtdcPosiDirectionType.Net, HedgeFlagType, out YdPosition, out TodayPosition, out nLongFrozen, out nShortFrozen); if (OutputLogToConsole) { Console.WriteLine("Side:{0},OrderQty:{1},YdPosition:{2},TodayPosition:{3},LongFrozen:{4},ShortFrozen:{5},Text:{6}", order.Side, order.OrderQty, YdPosition, TodayPosition, nLongFrozen, nShortFrozen,order.Text); } List<SOrderSplitItem> OrderSplitList = new List<SOrderSplitItem>(); SOrderSplitItem orderSplitItem; //根据 梦翔 与 马不停蹄 的提示,新加在Text域中指定开平标志的功能 //int nOpenCloseFlag = 0; //if (order.Text.StartsWith(OpenPrefix)) //{ // nOpenCloseFlag = 1; //} //else if (order.Text.StartsWith(ClosePrefix)) //{ // nOpenCloseFlag = -1; //} //else if (order.Text.StartsWith(CloseTodayPrefix)) //{ // nOpenCloseFlag = -2; //} //else if (order.Text.StartsWith(CloseYesterdayPrefix)) //{ // nOpenCloseFlag = -3; //} int leave = (int)order.OrderQty; if (leave > 0) { //开平已经没有意义了 byte[] bytes = { (byte)TZQThostFtdcOffsetFlagType.Open, (byte)TZQThostFtdcOffsetFlagType.Open }; szCombOffsetFlag = System.Text.Encoding.Default.GetString(bytes, 0, bytes.Length); orderSplitItem.qty = leave; orderSplitItem.szCombOffsetFlag = szCombOffsetFlag; OrderSplitList.Add(orderSplitItem); leave = 0; } if (leave > 0) { string strErr = string.Format("CTP:还剩余{0}手,你应当是强制指定平仓了,但持仓数小于要平手数", leave); Console.WriteLine(strErr); //EmitError(-1, -1, strErr); } //将第二腿也设置成一样,这样在使用组合时这地方不用再调整 byte[] bytes2 = { (byte)HedgeFlagType, (byte)HedgeFlagType }; string szCombHedgeFlag = System.Text.Encoding.Default.GetString(bytes2, 0, bytes2.Length); //bool bSupportMarketOrder = SupportMarketOrder.Contains(altExchange); string strPrice = string.Format("{0}", price); foreach (SOrderSplitItem it in OrderSplitList) { int nRet = 0; switch (order.OrdType) { case OrdType.Limit: nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, altExchange, order.Side == Side.Buy ? TZQThostFtdcDirectionType.Buy : TZQThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, strPrice, TZQThostFtdcOrderPriceTypeType.LimitPrice, TZQThostFtdcTimeConditionType.GFD, TZQThostFtdcContingentConditionType.Immediately, order.StopPx); break; case OrdType.Market: //if (bSupportMarketOrder) { nRet = TraderApi.TD_SendOrder(m_pTdApi, altSymbol, altExchange, order.Side == Side.Buy ? TZQThostFtdcDirectionType.Buy : TZQThostFtdcDirectionType.Sell, it.szCombOffsetFlag, szCombHedgeFlag, it.qty, "0", TZQThostFtdcOrderPriceTypeType.AnyPrice, TZQThostFtdcTimeConditionType.IOC, TZQThostFtdcContingentConditionType.Immediately, order.StopPx); } //else //{ // nRet = TraderApi.TD_SendOrder(m_pTdApi, // altSymbol, // altExchange, // order.Side == Side.Buy ? TZQThostFtdcDirectionType.Buy : TZQThostFtdcDirectionType.Sell, // it.szCombOffsetFlag, // szCombHedgeFlag, // it.qty, // strPrice, // TZQThostFtdcOrderPriceTypeType.LimitPrice, // TZQThostFtdcTimeConditionType.GFD, // TZQThostFtdcContingentConditionType.Immediately, // order.StopPx); //} break; default: EmitError(-1, -1, string.Format("没有实现{0}", order.OrdType)); break; } if (nRet > 0) { _OrderRef2Order.Add(string.Format("{0}:{1}:{2}", _RspUserLogin.FrontID, _RspUserLogin.SessionID, nRet), order as SingleOrder); } } }
public void SendNewOrderSingle(NewOrderSingle order) { SingleOrder key = order as SingleOrder; this.orderRecords.Add(key, new OrderRecord(key)); Send(key); }
public void RegisterOrder(NewOrderSingle order) { tdlog.Info("RegisterOrder"); }