public void Connect() { if (!this.isConnected) { ReportArgs rargs = this.trader.Logon(this.ip, this.port, this.version, this.departmentID, this.accountID, this.fundID, this.password); if (rargs.Succeeded) { this.isConnected = true; if (this.timer == null) { this.timer = new System.Timers.Timer(); this.timer.Interval = this.refreshTime * 1000; this.timer.Elapsed += new ElapsedEventHandler(tickTimer_Elapsed); this.timer.Start(); } Console.WriteLine("已登录."); if (Connected != null) { Connected(this, new EventArgs()); } if (StatusChanged != null) { StatusChanged(this, new EventArgs()); } } else { this.EmitError(this.Id, -1, rargs.ErrorInfo); } } }
public ReportArgs Logon(string ip, short port, string version, short departmentID, string accountID, string fundID, string password) { this.ip = ip; this.port = port; this.version = version; this.departmentID = departmentID; this.accountID = accountID; this.fundID = fundID; this.password = password; StringBuilder errInfo = new StringBuilder(256); this.clientID = TDXWrapper.Logon(this.ip, this.port, this.version, this.departmentID, this.accountID, this.fundID, this.password, string.Empty, errInfo); ReportArgs reportArgs = new ReportArgs(); if (this.clientID == -1) { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else { reportArgs.Succeeded = true; } return(reportArgs); }
public ReportArgs SendOrder(OrderSide orderSide, OrderType orderType, string securityID, float price, long quantity) { ReportArgs reportArgs = new ReportArgs(); if (this.clientID != -1) { //股东代码似乎可以为空 string shareholderCode = ""; StringBuilder errInfo = new StringBuilder(256); StringBuilder result = new StringBuilder(1024 * 1024); TDXWrapper.SendOrder(this.clientID, (int)orderSide, (int)orderType, shareholderCode, securityID, price, (int)quantity, result, errInfo); if (errInfo.ToString() != string.Empty)//下单失败 { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else//下单成功 { List <string[]> data = this.pickUp(result); reportArgs.Succeeded = true; if (data.Count > 1) { reportArgs.Result = data[1][0];//返回订单编号 } } } else { reportArgs.Succeeded = false; reportArgs.ErrorInfo = "交易账号未登录."; } return(reportArgs); }
public ReportArgs CancelOrder(string orderID) { ReportArgs reportArgs = new ReportArgs(); if (this.clientID != -1) { //交易所编号,似乎可以为空 string exchangeID = ""; StringBuilder errInfo = new StringBuilder(256); StringBuilder result = new StringBuilder(1024 * 1024); TDXWrapper.CancelOrder(this.clientID, exchangeID, orderID, result, errInfo); if (errInfo.ToString() != string.Empty)//撤单失败 { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else//下单成功 { List <string[]> data = this.pickUp(result); reportArgs.Succeeded = true; if (data.Count > 1) { reportArgs.Result = data[1][0]; } } } else { reportArgs.Succeeded = false; reportArgs.ErrorInfo = "交易账号未登录."; } return(reportArgs); }
public void SendOrderCancelRequest(FIXOrderCancelRequest request) { if (!this.isConnected) { this.EmitError(this.Id, -1, "The TDXTradeProvider is not connected."); } string origOuterOrderID = request.OrigClOrdID; OrderRecord orderRecord = this.orders.GetRecord(origOuterOrderID, 1); if (orderRecord == null) { string errorInfo = "要取消的订单没有记录。"; this.EmitError(this.Id, -1, errorInfo); OrderCancelReject report = new OrderCancelReject(); report.TransactTime = DateTime.Now; report.OrigClOrdID = request.OrigClOrdID; report.ClOrdID = request.ClOrdID; report.CxlRejReason = CxlRejReason.UnknownOrder; report.CxlRejResponseTo = CxlRejResponseTo.CancelRequest; report.Text = errorInfo; report.OrdStatus = OrdStatus.Rejected; if (OrderCancelReject != null) { OrderCancelReject(this, new OrderCancelRejectEventArgs(report)); } return; } string origInnerOrderID = orderRecord.InnerOrderID; ReportArgs rargs = this.trader.CancelOrder(origInnerOrderID); if (rargs.Succeeded) { Thread.Sleep(1000); this.updateOrders(); } else { this.EmitError(this.Id, -1, rargs.ErrorInfo); OrderCancelReject report = new OrderCancelReject(); report.TransactTime = DateTime.Now; report.OrigClOrdID = request.OrigClOrdID; report.ClOrdID = request.ClOrdID; report.CxlRejReason = CxlRejReason.BrokerOption; report.CxlRejResponseTo = CxlRejResponseTo.CancelRequest; report.Text = rargs.ErrorInfo; report.OrdStatus = OrdStatus.Rejected; if (OrderCancelReject != null) { OrderCancelReject(this, new OrderCancelRejectEventArgs(report)); } } }
public BrokerInfo GetBrokerInfo() { BrokerInfo brokerInfo = new BrokerInfo(); if (!this.isConnected) { this.EmitError(this.Id, -1, "The TDXTradeProvider is not connected."); return(brokerInfo); } ReportArgs rargs = this.trader.QueryFund(); if (rargs.Succeeded && rargs.Result != null) { FundRecord fundRecord = (FundRecord)rargs.Result; BrokerAccount brokerAccount = new BrokerAccount("通达信-" + this.fundID); brokerAccount.AddField("Balance", fundRecord.Balance.ToString()); brokerAccount.AddField("Available", fundRecord.Available.ToString()); brokerAccount.AddField("TotalAssets", fundRecord.TotalAsserts.ToString()); brokerAccount.AddField("Desirable", fundRecord.Desirable.ToString()); brokerAccount.AddField("MarketValue", fundRecord.MarketValue.ToString()); brokerAccount.AddField("Frozen", fundRecord.Frozen.ToString()); brokerAccount.BuyingPower = fundRecord.Available; brokerInfo.Accounts.Add(brokerAccount); rargs = this.trader.QueryPositions(); if (rargs.Succeeded && rargs.Result != null) { List <PositionRecord> positions = (List <PositionRecord>)rargs.Result; foreach (PositionRecord position in positions) { BrokerPosition brokerPosition = new BrokerPosition(); brokerPosition.SecurityExchange = position.SecurityExchange; brokerPosition.Symbol = position.SecurityExchange + "." + position.SecurityID; brokerPosition.AddCustomField("Available", position.Available.ToString()); brokerPosition.Qty = position.Quantity; brokerPosition.AddCustomField("CostPrice", position.CostPrice.ToString()); brokerPosition.LongQty = position.Quantity; brokerAccount.AddPosition(brokerPosition); } } else { this.EmitError(this.Id, -1, rargs.ErrorInfo); } } else { this.EmitError(this.Id, -1, rargs.ErrorInfo); } return(brokerInfo); }
public ReportArgs QueryPositions() { ReportArgs reportArgs = new ReportArgs(); if (this.clientID != -1) { StringBuilder errInfo = new StringBuilder(256); StringBuilder result = new StringBuilder(1024 * 1024); TDXWrapper.QueryData(this.clientID, 1, result, errInfo); if (errInfo.ToString() != string.Empty)//查询失败 { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else//查询成功 { List <string[]> data = this.pickUp(result); reportArgs.Succeeded = true; List <PositionRecord> positions = new List <PositionRecord>(); for (int i = 1; i < data.Count; i++) { PositionRecord positionRecord = new PositionRecord(); positionRecord.SecurityID = data[i][0]; positionRecord.Quantity = double.Parse(data[i][2]); positionRecord.Available = double.Parse(data[i][3]); positionRecord.CostPrice = double.Parse(data[i][4]); switch (int.Parse(data[i][11])) { case 1: positionRecord.SecurityExchange = "SHSE"; break; case 0: positionRecord.SecurityExchange = "SZSE"; break; } positions.Add(positionRecord); } reportArgs.Result = positions; } } else { reportArgs.Succeeded = false; reportArgs.ErrorInfo = "交易账号未登录."; } return(reportArgs); }
public ReportArgs ReLogon() { StringBuilder errInfo = new StringBuilder(256); this.clientID = TDXWrapper.Logon(this.ip, this.port, this.version, this.departmentID, this.accountID, this.fundID, this.password, string.Empty, errInfo); ReportArgs reportArgs = new ReportArgs(); if (this.clientID == -1) { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else { reportArgs.Succeeded = true; } return(reportArgs); }
public ReportArgs QueryFund() { ReportArgs reportArgs = new ReportArgs(); if (this.clientID != -1) { StringBuilder errInfo = new StringBuilder(256); StringBuilder result = new StringBuilder(1024 * 1024); TDXWrapper.QueryData(this.clientID, 0, result, errInfo); if (errInfo.ToString() != string.Empty)//查询失败 { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else//查询成功 { List <string[]> data = this.pickUp(result); reportArgs.Succeeded = true; if (data.Count > 1) { FundRecord fundRecord = new FundRecord(); fundRecord.Balance = double.Parse(data[1][1]); fundRecord.Available = double.Parse(data[1][2]); fundRecord.Frozen = double.Parse(data[1][3]); fundRecord.Desirable = double.Parse(data[1][4]); fundRecord.TotalAsserts = double.Parse(data[1][5]); fundRecord.MarketValue = double.Parse(data[1][6]); reportArgs.Result = fundRecord; } } } else { reportArgs.Succeeded = false; reportArgs.ErrorInfo = "交易账号未登录."; } return(reportArgs); }
private void updateOrders() { if (!this.isConnected) { this.EmitError(this.Id, -1, "The TDXTradeProvider is not connected."); } lock (this.updating) { ReportArgs rargs = this.trader.QueryOrders(); if (rargs.Succeeded) { List <OrderRecord> orderRecords = (List <OrderRecord>)rargs.Result; foreach (OrderRecord orderRecord in orderRecords) { bool needReport = false; OrderRecord prevOrderRecord = this.orders.GetRecord(orderRecord.InnerOrderID, 0); if (prevOrderRecord == null) { prevOrderRecord = this.orders.SearchRecord(orderRecord); } if (prevOrderRecord != null) { if (prevOrderRecord.OrderStatus != orderRecord.OrderStatus) { needReport = true; } else if (orderRecord.OrderStatus == OrderStatus.PartiallyFilled && prevOrderRecord.CumQty < orderRecord.CumQty) { needReport = true; } } if (needReport) { ExecutionReport report = new ExecutionReport(); report.TransactTime = orderRecord.TransactTime; switch (orderRecord.OrderStatus) { case OrderStatus.New: report.ExecType = ExecType.New; report.OrdStatus = OrdStatus.New; break; case OrderStatus.PartiallyFilled: report.ExecType = ExecType.PartialFill; report.OrdStatus = OrdStatus.PartiallyFilled; break; case OrderStatus.Filled: report.ExecType = ExecType.Fill; report.OrdStatus = OrdStatus.Filled; break; case OrderStatus.PendingCancel: report.ExecType = ExecType.PendingCancel; report.OrdStatus = OrdStatus.PendingCancel; break; case OrderStatus.Cancelled: report.ExecType = ExecType.Cancelled; report.OrdStatus = OrdStatus.Cancelled; break; case OrderStatus.Rejected: report.ExecType = ExecType.Rejected; report.OrdStatus = OrdStatus.Rejected; break; default: report.ExecType = ExecType.Undefined; report.OrdStatus = OrdStatus.Undefined; break; } report.ClOrdID = prevOrderRecord.OuterOrderID; if (orderRecord.OrderStatus == OrderStatus.PendingCancel || orderRecord.OrderStatus == OrderStatus.Cancelled) { report.OrigClOrdID = prevOrderRecord.OuterOrderID; } report.OrderQty = orderRecord.OrderQty; report.AvgPx = orderRecord.AvgPx; report.CumQty = orderRecord.CumQty; report.LeavesQty = orderRecord.OrderQty - orderRecord.CumQty; switch (orderRecord.OrderSide) { case (OrderSide.Buy): report.Side = Side.Buy; break; case (OrderSide.Sell): report.Side = Side.Sell; break; default: report.Side = Side.Undefined; break; } //计算费率 if (report.CumQty > 0) { report.Commission = this.commission * report.CumQty * report.AvgPx; report.CommType = CommType.Absolute; if (report.Commission < this.minCommission) { report.Commission = this.minCommission; } if (report.Side == Side.Sell) { report.Commission += this.stampDuty * report.CumQty * report.AvgPx; } } if (ExecutionReport != null) { ExecutionReport(this, new ExecutionReportEventArgs(report)); } prevOrderRecord.OrderStatus = orderRecord.OrderStatus; prevOrderRecord.AvgPx = orderRecord.AvgPx; prevOrderRecord.CumQty = orderRecord.CumQty; } } } else { this.EmitError(this.Id, -1, rargs.ErrorInfo); } } }
public void SendNewOrderSingle(NewOrderSingle order) { if (!this.isConnected) { this.EmitError(this.Id, -1, "The TDXTradeProvider is not connected."); } try { Instrument curInstrument = InstrumentManager.Instruments[order.Symbol]; string securityID = curInstrument.SecurityID; OrderSide orderSide; switch (order.Side) { case Side.Buy: orderSide = OrderSide.Buy; break; case Side.Sell: orderSide = OrderSide.Sell; break; default: throw new Exception("不支持的买卖指令。"); } OrderType orderType; switch (order.OrdType) { case OrdType.Market: orderType = OrderType.CancelAfterFiveQuoteTransaction; break; case OrdType.Limit: orderType = OrderType.Limit; break; default: throw new Exception("不支持的订单类型"); } ReportArgs rargs = this.trader.SendOrder(orderSide, orderType, securityID, (float)order.Price, (long)order.OrderQty); if (rargs.Succeeded) //下单成功 { string orderID = (string)rargs.Result; //委托编号 OrderRecord orderRecord = new OrderRecord(); orderRecord.InnerOrderID = orderID; orderRecord.OuterOrderID = order.ClOrdID; orderRecord.SecurityID = order.SecurityID; orderRecord.OrderStatus = OrderStatus.New; orderRecord.OrderSide = orderSide; orderRecord.OrderType = orderType; orderRecord.OrderPrice = order.Price; orderRecord.OrderQty = (long)order.OrderQty; orderRecord.AvgPx = 0.0; orderRecord.CumQty = 0; orderRecord.TransactTime = Clock.Now; lock (this.orders) { this.orders.AddRecord(orderRecord, orderID, order.ClOrdID); } ExecutionReport report = new ExecutionReport(); report.TransactTime = orderRecord.TransactTime; report.ExecType = ExecType.New; report.ClOrdID = order.ClOrdID; report.OrdStatus = OrdStatus.New; report.AvgPx = 0.0; report.CumQty = 0; report.OrderQty = order.OrderQty; report.Price = order.Price; report.LeavesQty = order.OrderQty; report.Side = order.Side; if (order.OrdType == OrdType.Limit) { report.TimeInForce = TimeInForce.Day;//强制限价单为当日有效 } if (ExecutionReport != null) { ExecutionReport(this, new ExecutionReportEventArgs(report)); } Thread.Sleep(1000); this.updateOrders(); } else//下单失败 { this.EmitError(this.Id, -1, rargs.ErrorInfo); ExecutionReport report = new ExecutionReport(); report.TransactTime = DateTime.Now; report.ExecType = ExecType.Rejected; report.ClOrdID = order.ClOrdID; report.OrdStatus = OrdStatus.Rejected; report.AvgPx = 0.0; report.CumQty = 0; report.OrderQty = order.OrderQty; report.Price = order.Price; report.LeavesQty = order.OrderQty; report.Side = order.Side; report.Text = rargs.ErrorInfo; if (ExecutionReport != null) { ExecutionReport(this, new ExecutionReportEventArgs(report)); } } }catch (Exception ex) { this.EmitError(this.Id, -1, ex.Message); } }
public ReportArgs QueryOrders() { ReportArgs reportArgs = new ReportArgs(); if (this.clientID != -1) { StringBuilder errInfo = new StringBuilder(256); StringBuilder result = new StringBuilder(1024 * 1024); TDXWrapper.QueryData(this.clientID, 2, result, errInfo); if (errInfo.ToString() != string.Empty)//查询失败 { reportArgs.Succeeded = false; reportArgs.ErrorInfo = errInfo.ToString(); } else//查询成功 { List <string[]> data = this.pickUp(result); reportArgs.Succeeded = true; List <OrderRecord> resultList = new List <OrderRecord>(); string dateString = DateTime.Today.ToString("yyyy-MM-dd"); for (int i = 1; i < data.Count; i++) { OrderRecord orderRecord = new OrderRecord(); orderRecord.TransactTime = DateTime.Parse(dateString + " " + data[i][0]); orderRecord.SecurityID = data[i][1]; orderRecord.OrderSide = (OrderSide)int.Parse(data[i][3]); switch (data[i][6]) { case "待报": orderRecord.OrderStatus = OrderStatus.PendingNew; break; case "已报": orderRecord.OrderStatus = OrderStatus.New; break; case "部分成交": orderRecord.OrderStatus = OrderStatus.PartiallyFilled; break; case "已成": orderRecord.OrderStatus = OrderStatus.Filled; break; case "已报待撤": orderRecord.OrderStatus = OrderStatus.PendingCancel; break; case "已撤": orderRecord.OrderStatus = OrderStatus.Cancelled; break; default: orderRecord.OrderStatus = OrderStatus.Rejected; break; } orderRecord.OrderPrice = double.Parse(data[i][7]); orderRecord.OrderQty = double.Parse(data[i][8]); orderRecord.InnerOrderID = data[i][9]; orderRecord.AvgPx = double.Parse(data[i][10]); orderRecord.CumQty = double.Parse(data[i][11]); orderRecord.OrderType = (OrderType)int.Parse(data[i][12]); resultList.Add(orderRecord); } reportArgs.Result = resultList; } } else { reportArgs.Succeeded = false; reportArgs.ErrorInfo = "交易账号未登录."; } return(reportArgs); }