Beispiel #1
0
        private void SwitchMessage(ZMessage zMsgReply, string message, string[] info)
        {
            string traderName = info[1];
            ShareLimitGroupItem shareLimitGroup = ShareLimitAdapter.Instance.GetLimitGroup(traderName);

            switch (info[0])
            {
            case "1":     // 策略端发送指令格式:        1|交易员id|股票编码|开/平|开仓价格|股数  .     开/平:OPEN\CLOSE;  code:股票编码
                SendOrderMessageInit(zMsgReply, info, traderName, shareLimitGroup);
                break;

            case "2":
                CancelOrderMessageInit(zMsgReply, info, traderName);
                break;

            case "3":     // 查询 额度分配,订单,委托 3|交易员id|订单json|委托json
                QueryOrderMessageInit(zMsgReply, traderName);
                break;

            case "5":
                LimitQueryMessageInit(zMsgReply, traderName, shareLimitGroup);
                break;

            default:
                zMsgReply.Add(new ZFrame("Invalid Message, Not Implement branch, branch Value:" + info[0] + "\r\n  Total Message:" + message));
                break;
            }
        }
Beispiel #2
0
        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.AddConsignmentCache(UserName, 证券代码, 买卖方向, 委托数量, 委托价格, 委托编号, limitItem.GroupAccount, limitItem.StockName, market);
                            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());
        }
Beispiel #3
0
        private void SendOrderMessageInit(ZMessage zMsgReply, string[] infos, string traderName, ShareLimitGroupItem shareLimitGroup)
        {
            //Program.logger.LogInfoDetail("自动下单接口1 订单发送:收到消息时间{0}", DateTime.Now.ToString("HH:mm:ss:fff"));
            string buySaleFlag = infos[3].ToUpper() == "OPEN" ? "0" : "1";
            string strSend     = string.Empty;

            if (shareLimitGroup == null)
            {
                strSend = string.Format("1|{0}|0|7|对应共享额度组不存在!", traderName);
            }
            else
            {
                strSend = SendSharedLimitOrder(traderName, infos[2], buySaleFlag, infos[5], infos[4], shareLimitGroup);
            }
            zMsgReply.Add(new ZFrame(strSend));
            //Program.logger.LogInfoDetail("自动下单接口1 订单发送:返回下单结果时间{0}", DateTime.Now.ToString("HH:mm:ss:fff"));
        }
Beispiel #4
0
        private static void LimitQueryMessageInit(ZMessage zMsgReply, string traderName, ShareLimitGroupItem shareLimitGroup)
        {
            var dict = new Dictionary <string, decimal>();

            if (shareLimitGroup == null)
            {
                Program.logger.LogInfoDetail("{0}额度共享组为空,将返回额度分配表对应配置。", traderName);
                Program.db.额度分配.Where(_ => _.交易员 == traderName).ToList().ForEach(_ => dict.Add(_.证券代码, _.交易额度));
                zMsgReply.Add(new ZFrame(string.Format("5|{0}|{1}", traderName, dict.ToJson())));
            }
            else
            {
                foreach (var item in shareLimitGroup.GroupStockList)
                {
                    var           limit = decimal.Parse(item.LimitCount);
                    decimal       buyCount, saleCount;
                    List <string> lstOrderID = new List <string>();

                    var dictStockBuySaleList = shareLimitGroup.GetShareGroupBuySaleList(item.StockID);
                    shareLimitGroup.GetShareGroupHasBuyCount(item.StockID, out buyCount, out saleCount);

                    decimal needPlaceBuyCount  = 0;
                    decimal needPlaceSaleCount = 0;
                    foreach (var TraderBuySaleItem in dictStockBuySaleList)
                    {
                        if (TraderBuySaleItem.Key != traderName)
                        {
                            if (TraderBuySaleItem.Value.SoldCount > TraderBuySaleItem.Value.BuyCount)
                            {
                                needPlaceBuyCount += TraderBuySaleItem.Value.SoldCount - TraderBuySaleItem.Value.BuyCount;
                            }
                            else
                            {
                                needPlaceSaleCount += TraderBuySaleItem.Value.BuyCount - TraderBuySaleItem.Value.SoldCount;
                            }
                        }
                    }
                    if (dict.ContainsKey(item.StockID))
                    {
                        Program.logger.LogInfoDetail("已存在股票{0}的配置项,股票代码重复", item.StockID);
                    }
                    else
                    {
                        dict.Add(item.StockID, Math.Min(limit - buyCount - needPlaceBuyCount, limit - saleCount - needPlaceSaleCount));
                    }
                }
            }


            zMsgReply.Add(new ZFrame(string.Format("5|{0}|{1}", traderName, dict.ToJson())));
        }