public string SendSharedLimitOrder(string UserName, string 证券代码, string tradeDirection, string quatity, string price, ShareLimitGroupItem shareLimitGroup) { StringBuilder sb = new StringBuilder(128); lock (Sync) { try { sb.Append("1|").Append(UserName).Append('|'); int 买卖方向 = int.Parse(tradeDirection); decimal 委托数量 = decimal.Parse(quatity); decimal 委托价格 = decimal.Parse(price); var market = 证券代码.GetCodeMarket(); var limitItem = shareLimitGroup.GroupStockList.FirstOrDefault(_ => _.StockID == 证券代码); if (limitItem == null) { sb.AppendFormat("0|1|该股票没有额度|0"); return(sb.ToString()); } decimal commissionCharge = decimal.Parse(limitItem.Commission); string zqName = limitItem.StockName; List <string> lstSendedOrderID = new List <string>(); decimal 已买股数, 已卖股数, traderBuy, traderSale; shareLimitGroup.GetShareGroupHasBuyCount(证券代码, UserName, lstSendedOrderID, out 已买股数, out 已卖股数, out traderBuy, out traderSale); decimal 开仓数量 = Tool.Get开仓数量From已买卖数量(买卖方向, 委托数量, 已买股数, 已卖股数); #region 仓位,亏损,买数量,卖数量,限制判定 #region 仓位亏损限制 if (开仓数量 > 0) { DbDataSet.平台用户Row AASUser1 = Program.db.平台用户.Get平台用户(UserName); //仓位限制 decimal 欲下仓位 = 委托价格 * 开仓数量; decimal 已用仓位 = Program.db.已发委托.Get已用仓位(UserName); if (已用仓位 + 欲下仓位 > AASUser1.仓位限制) { sb.AppendFormat("0|1|仓位超限, 已用仓位{0:f2},欲下仓位{1:f2}, 超过设定值{2:f2}|0", 已用仓位, 欲下仓位, AASUser1.仓位限制); return(sb.ToString()); } //亏损限制 decimal 当日委托交易费用 = Program.db.已发委托.Get交易费用(UserName, commissionCharge); decimal 当日亏损 = Program.db.已平仓订单.Get当日已平仓亏损(UserName) + 当日委托交易费用; if (当日亏损 >= AASUser1.亏损限制) { sb.AppendFormat("0|2|用户亏损{0:f2}超过设定值{1:f2}|0", 当日亏损, AASUser1.亏损限制); return(sb.ToString()); } } #endregion #region 买卖数量限制 // //将缓存数量加上。 if (CommonUtils.OrderCacheQueue.Count > 0) { var cache = CommonUtils.OrderCacheQueue.Where(_ => _.Trader == UserName && _.Zqdm == 证券代码 && !lstSendedOrderID.Contains(_.OrderID) && (DateTime.Now - _.SendTime).TotalSeconds < 10).ToList(); if (cache.Count > 0) { var buy = cache.Where(_ => _.Category % 2 == 0).Sum(_ => _.Quantity); var sale = cache.Where(_ => _.Category % 2 == 1).Sum(_ => _.Quantity); 已买股数 += buy; 已卖股数 += sale; } } var dict = shareLimitGroup.GetShareGroupBuySaleList(证券代码); decimal needPlaceBuyCount = 0; if (买卖方向 == 0) {//如已反方向下了大于等于委托数的单子,则可以跳过判断 if (traderSale - traderBuy < 委托数量) { foreach (var item in dict) { if (item.Key != UserName && item.Value.SoldCount > item.Value.BuyCount) { needPlaceBuyCount += item.Value.SoldCount - item.Value.BuyCount; } } if (needPlaceBuyCount + 已买股数 + 委托数量 > decimal.Parse(limitItem.LimitCount)) { var wt = Program.帐户委托DataTable[limitItem.GroupAccount].Where(_ => _.证券代码 == 证券代码); sb.AppendFormat("0|3|额度不足,总额度{0},已买股数{1},需保留仓位{2}|{3}", limitItem.LimitCount, 已买股数, needPlaceBuyCount, decimal.Parse(limitItem.LimitCount) - needPlaceBuyCount - 已买股数); Program.logger.LogInfoDetail("买数量超限!交易员买卖此股票数量:{0},总额度{1},已买股数{2},需保留仓位{3},该交易员买数{4} 卖数{5}", dict.ToJson(), limitItem.LimitCount, 已买股数, needPlaceBuyCount, traderBuy, traderSale); return(sb.ToString()); } } } else { if (traderBuy - traderSale < 委托数量) { foreach (var item in dict) { if (item.Key != UserName && item.Value.BuyCount > item.Value.SoldCount) { needPlaceBuyCount += item.Value.BuyCount - item.Value.SoldCount; } } if (needPlaceBuyCount + 已卖股数 + 委托数量 > decimal.Parse(limitItem.LimitCount)) { var wt = Program.帐户委托DataTable[limitItem.GroupAccount].Where(_ => _.证券代码 == 证券代码); sb.AppendFormat("0|4|额度不足,总额度{0},已卖股数{1},需保留仓位{2}|{3}", limitItem.LimitCount, 已卖股数, needPlaceBuyCount, decimal.Parse(limitItem.LimitCount) - needPlaceBuyCount - 已卖股数); Program.logger.LogInfoDetail("卖数量超限!交易员买卖此股票数量:{0},总额度{1},已卖股数{2},需保留仓位{3},该股票相关委托{4}", dict.ToJson(), limitItem.LimitCount, 已卖股数, needPlaceBuyCount, wt.ToJson()); return(sb.ToString()); } } } #endregion #endregion string 委托编号; string ErrInfo; var orderCacheObj = new OrderCacheEntity() { Category = 买卖方向, Zqdm = 证券代码, ZqName = zqName, Price = 委托价格, Quantity = 委托数量, Trader = UserName, Sender = UserName, SendTime = DateTime.Now, }; CommonUtils.OrderCacheQueue.Enqueue(orderCacheObj); bool hasOrderNo; if (Program.db.券商帐户.Exists(limitItem.GroupAccount)) { var bsFlag = limitItem.GetTradeType(买卖方向); Program.logger.LogInfo("额度共享策略:组合号{0}, 买卖方向原始值{1},买卖方向最终值{2}, 股票代码{3}", limitItem.GroupAccount, 买卖方向, bsFlag, 证券代码); Program.db.券商帐户.SendOrder(limitItem.GroupAccount, bsFlag, market, 证券代码, 委托价格, 委托数量, orderCacheObj, out 委托编号, out ErrInfo, out hasOrderNo); } else { sb.Append("0|5|帐户不存在|0"); return(sb.ToString()); } if (ErrInfo == string.Empty) { if (hasOrderNo) { orderCacheObj.OrderID = 委托编号; Program.db.已发委托.Add(DateTime.Today, limitItem.GroupAccount, 委托编号, UserName, "程序自动委托下单成功", market, 证券代码, limitItem.StockName, 买卖方向, 0m, 0m, (decimal)委托价格, (decimal)委托数量, 0m); string Msg = UserName + " 程序自动下单成功"; Program.db.交易日志.Add(DateTime.Today, DateTime.Now.ToString("HH:mm:ss"), UserName, limitItem.GroupAccount, 证券代码, limitItem.StockName, 委托编号, 买卖方向, 委托数量, 委托价格, Msg); sb.AppendFormat("{0}||{1}", limitItem.GroupAccount + '_' + 委托编号, Msg); BagNewOrderTraderStock.Add(new KeyValuePair <string, string>(UserName, 证券代码)); } else { sb.AppendFormat("0|6|已报,等待接口处理"); } } else { sb.AppendFormat("0|6|{0}|0", ErrInfo); } } catch (Exception ex) { Program.logger.LogInfoDetail("服务器下单异常:{0} {1}", ex.Message, ex.StackTrace); sb.AppendFormat("0|7|程序自动下单接口异常\r\n 交易员账号:{0}\r\n 证券代码{1}\r\n ExceptionMessage:{2}|0", UserName, 证券代码, ex.Message); } } return(sb.ToString()); }
public string SendOrder(string UserName, string 证券代码, string tradeDirection, string quatity, string price) { // 交易端返回消息格式: 1|交易员id|委托编号|错误码id|错误信息. 委托编号:非0表示成功。0表示失败; 错误码id|错误信息:对应的错误信息 // 策略端发送指令格式: 1|交易员id|股票编码|开/平|开仓价格|股数 . 开/平:OPEN\CLOSE; // 交易端返回消息格式: 1|交易员id|委托编号|错误码id|错误信息. 委托编号:非0表示成功。0表示失败; 错误码id|错误信息:对应的错误信息 StringBuilder sb = new StringBuilder(128); try { sb.Append("1|").Append(UserName).Append('|'); int 买卖方向 = int.Parse(tradeDirection); decimal 委托数量 = decimal.Parse(quatity); decimal 委托价格 = decimal.Parse(price); DbDataSet.平台用户Row AASUser1 = Program.db.平台用户.Get平台用户(UserName); DbDataSet.额度分配Row TradeLimit1 = Program.db.额度分配.Get额度分配(UserName, 证券代码); var shareLimitGroup = ShareLimitAdapter.Instance.GetLimitGroup(UserName); if (TradeLimit1 == null) { sb.Append("0|0|无此证券交易额度"); return(sb.ToString()); } decimal commissionCharge = TradeLimit1.手续费率; string zqName = TradeLimit1.证券名称; decimal 已用仓位 = Program.db.已发委托.Get已用仓位(UserName); decimal 当日委托交易费用 = Program.db.已发委托.Get交易费用(UserName, commissionCharge); List <string> lstSendedID = new List <string>(); decimal 已买股数 = 0; decimal 已卖股数 = 0; Program.db.已发委托.Get已买卖股票(UserName, 证券代码, lstSendedID, out 已买股数, out 已卖股数); decimal 开仓数量 = Tool.Get开仓数量From已买卖数量(买卖方向, 委托数量, 已买股数, 已卖股数); #region 仓位,亏损,买数量,卖数量,限制判定 if (开仓数量 > 0) { //仓位限制 decimal 欲下仓位 = 委托价格 * 开仓数量; if (已用仓位 + 欲下仓位 > AASUser1.仓位限制) { sb.AppendFormat("0|1|仓位超限, 已用仓位{0:f2},欲下仓位{1:f2}, 超过设定值{2:f2}", 已用仓位, 欲下仓位, AASUser1.仓位限制); return(sb.ToString()); } //亏损限制 decimal 当日亏损 = Program.db.已平仓订单.Get当日已平仓亏损(UserName) + 当日委托交易费用; if (当日亏损 >= AASUser1.亏损限制) { sb.AppendFormat("0|2|用户亏损{0:f2}超过设定值{1:f2}", 当日亏损, AASUser1.亏损限制); return(sb.ToString()); } } //将缓存数量加上。 if (CommonUtils.OrderCacheQueue.Count > 0) { var cache = CommonUtils.OrderCacheQueue.Where(_ => _.Trader == UserName && _.Zqdm == 证券代码 && !lstSendedID.Contains(_.OrderID) && (DateTime.Now - _.SendTime).TotalSeconds < 10).ToList(); if (cache.Count > 0) { var buy = cache.Where(_ => _.Category % 2 == 0).Sum(_ => _.Quantity); var sale = cache.Where(_ => _.Category % 2 == 1).Sum(_ => _.Quantity); 已买股数 += buy; 已卖股数 += sale; } } if (买卖方向 == 0) { if (已买股数 + 委托数量 > TradeLimit1.交易额度) { sb.AppendFormat("0|3|买数量超限, 已买数量{0:f0}, 欲买数量{1:f0}, 超过设定值{2:f0}", 已买股数, 委托数量, TradeLimit1.交易额度); return(sb.ToString()); } } else { if (已卖股数 + 委托数量 > TradeLimit1.交易额度) { sb.AppendFormat("0|4|卖数量超限, 已卖数量{0:f0}, 欲卖数量{1:f0}, 超过设定值{2:f0}", 已卖股数, 委托数量, TradeLimit1.交易额度); return(sb.ToString()); } } #endregion string 委托编号; string ErrInfo; var orderCacheObj = new OrderCacheEntity() { Category = 买卖方向, Zqdm = 证券代码, ZqName = zqName, Price = 委托价格, Quantity = 委托数量, Trader = UserName, Sender = UserName, SendTime = DateTime.Now, }; CommonUtils.OrderCacheQueue.Enqueue(orderCacheObj); bool hasOrderNo; if (Program.db.券商帐户.Exists(TradeLimit1.组合号)) { Program.db.券商帐户.SendOrder(TradeLimit1.组合号, TradeLimit1.Get券商帐户买卖类别(买卖方向), TradeLimit1.市场, 证券代码, 委托价格, 委托数量, orderCacheObj, out 委托编号, out ErrInfo, out hasOrderNo); } else { sb.Append("0|5|帐户不存在"); return(sb.ToString()); } if (ErrInfo == string.Empty) { if (hasOrderNo) { orderCacheObj.OrderID = 委托编号; Program.db.已发委托.Add(DateTime.Today, TradeLimit1.组合号, 委托编号, UserName, "程序自动委托下单成功", TradeLimit1.市场, 证券代码, TradeLimit1.证券名称, 买卖方向, 0m, 0m, (decimal)委托价格, (decimal)委托数量, 0m); string Msg = UserName + " 程序自动下单成功"; Program.db.交易日志.Add(DateTime.Today, DateTime.Now.ToString("HH:mm:ss"), UserName, TradeLimit1.组合号, 证券代码, TradeLimit1.证券名称, 委托编号, 买卖方向, 委托数量, 委托价格, Msg); sb.AppendFormat("{0}||{1}", TradeLimit1.组合号 + '_' + 委托编号, Msg); } sb.AppendFormat("{0}|6|已报,等待接口处理"); } else { sb.AppendFormat("0|6|{0}", ErrInfo); } } catch (Exception ex) { Program.logger.LogInfoDetail("服务器下单异常:{0} {1}", ex.Message, ex.StackTrace); sb.AppendFormat("0|7|程序自动下单接口异常\r\n 交易员账号:{0}\r\n 证券代码{1}\r\n ExceptionMessage:{2}", UserName, 证券代码, ex.Message); } return(sb.ToString()); }