//---------------------------------------------------------------- //Module Name: GoodsService //Purpose: //CopyRight: Muchinfo //History: //---------------------------------------------------------------- //DateTime Author Description //---------------------------------------------------------------- //2014-03-22 deng.yinping Create //---------------------------------------------------------------- using Muchinfo.MTPClient.Data; using Muchinfo.MTPClient.Data.DTO; using Muchinfo.MTPClient.Data.Enums; using Muchinfo.MTPClient.Data.Model; using Muchinfo.MTPClient.Data.Model.GoodRules; using Muchinfo.MTPClient.Infrastructure.Cache; using Muchinfo.MTPClient.Infrastructure.Utilities; using Muchinfo.MTPClient.IService; using Muchinfo.MTPClient.Resources; using Muchinfo.MTPClient.Service.Utilities; using Muchinfo.PC.Common.Extensions; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace Muchinfo.MTPClient.Service { public class GoodsService : IGoodsService { #region IGoodsService /// /// 获取交易所列表 /// /// Dictionary{System.StringSystem.String}. /// public Dictionary GetExchanges() { //todo: throw new NotImplementedException(); } /// /// 生成交易所商品树 /// /// ObservableCollection{TreeViewEntity}. /// public ObservableCollection GetExchangeTree() { //todo: throw new NotImplementedException(); } /// /// 获取商品信息By商品代码 /// /// The goods code list. /// ObservableCollection{QuoteGoods}. public ObservableCollection GetQuoteGoodsByCodes(List goodsCodeList) { var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; if (cacheGoodsList == null || !cacheGoodsList.Any()) return null; var result = new List(); //循环取以保持顺序 foreach (var goodsCode in goodsCodeList) { var goods = cacheGoodsList.FirstOrDefault(z => z.GoodsCode == goodsCode); if (goods == null) continue; result.Add(goods); } return ConvertToQuoteGoodses(result); } /// /// 获取命令行商品 /// /// Type of the command. /// The additional info. /// IEnumerable{QuoteGoods}. public ObservableCollection GetGoodsInfoList(MenuCommandType commandType, string additionalInfo) { var favoriteService = new FavoriteService(); switch (commandType) { case MenuCommandType.SelectedGoodses: uint id; if (uint.TryParse(additionalInfo, out id)) { return favoriteService.GetMyFavoriteGoodses(id); } return null; case MenuCommandType.CustomQuote: case MenuCommandType.BidQuote: return GetGoodsInfoList(additionalInfo); default: return null; } } ///// ///// 更新商品盘面信息 ///// ///// The goods list. //public void UpdateFromDayQuote(List goodsList) //{ // if (goodsList == null || !goodsList.Any()) return; // var symbols = goodsList.Select((goods) => goods.Symbol).ToList(); // if (!symbols.Any()) return; // var link = LinkManager.Instance.QuoteTcpLinkProxy; // link.QueryDayQuote(goodsList); //} public ObservableCollection GetAllGoods() { var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; if (cacheGoodsList == null) return null; var result = cacheGoodsList as IList; if (!result.Any()) return null; return result.ToObservableCollection(); } /// /// 更新的昨日结算价 /// /// 商品 /// 账号 /// public void UpdateLastReckonPrice(List goodses, MTPClient.Data.Model.Account.TradeAccount account) { //todo: throw new NotImplementedException(); } /// /// 更新的交收价 /// /// 商品 /// 账号 /// public void UpdateDeliveryPrice(List goodses, MTPClient.Data.Model.Account.TradeAccount account) { //todo: throw new NotImplementedException(); } /// /// Queries the parameter rule. /// /// The cont right code. /// The goods code. /// if set to true [is bid market]. /// The login code. /// List{ParameterRule}. /// public List QueryParameterRule(int contRightCode, string goodsCode, bool isBidMarket, string loginCode) { //todo: throw new NotImplementedException(); } /// /// 商品开市 /// /// 商品代码 /// public void MarketOpenUpdateDayQuote(string[] goodsCodes) { //todo: throw new NotImplementedException(); } #endregion #region Private Methods /// /// 获取交易所,市场商品 /// /// The market identifier string. /// ObservableCollection{QuoteGoods}. private ObservableCollection GetGoodsInfoList(string marketIdString) { if (string.IsNullOrWhiteSpace(marketIdString)) return null; int marketId = 0; int.TryParse(marketIdString, out marketId); var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; if (cacheGoodsList == null) return null; var filterList = cacheGoodsList.Where(z => z.GoodsParameters.SortId == marketId); return ConvertToQuoteGoodses(filterList); } /// /// Converts to quote goodses. /// /// The goods list. /// ObservableCollection{QuoteGoods}. private ObservableCollection ConvertToQuoteGoodses(IEnumerable goodsList) { var dataModels = goodsList as IList ?? goodsList.ToList(); if (!dataModels.Any()) return null; var result = new ObservableCollection(); var showIndex = 1; foreach (var dataModel in dataModels) { dataModel.ShowIndex = showIndex++; result.Add(dataModel); } return result; } #endregion /// /// 根据symbol获取商品 /// /// The symbol. /// QuoteGoods. public QuoteGoods GetQuoteGoodsBySymbol(string symbol) { if (string.IsNullOrWhiteSpace(symbol)) return null; return CacheManager.CacheGoodsBaseInfos.FirstOrDefault(z => z.Symbol == symbol); } /// /// 获取商品DTO对象集合 /// /// Type of the command. /// The goods group. /// IEnumerable{QuoteGoods}. public ObservableCollection GetQuoteGoodsDTOList(MenuCommandType commandType, MarketsInfoModel goodsGroup) { if (goodsGroup == null) return null; var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; if (cacheGoodsList == null) return null; var filterList = new List(); if (goodsGroup.TradeMode == eTradeMode.AllGoods || goodsGroup.TradeMode == eTradeMode.QuotePAndX) { filterList = SortByAllGoodses(); } else { //filterList = cacheGoodsList.Where(z => z != null && z.MarketID == goodsGroup.MarketID).OrderBy(p => p.GoodsCode).ToList(); //MTP2.0 资管使用外部交易所做为分组标签 filterList = GetGoodsListByExExchangeId(goodsGroup.MarketID); } var quoteGoodses = filterList as IList ?? filterList.ToList(); if (!quoteGoodses.Any()) return null; var showIndex = 1; var result = new ObservableCollection(); foreach (var quoteGoods in quoteGoodses) { if (quoteGoods == null) continue; quoteGoods.ShowIndex = showIndex++; ////取交易参数中的最小建仓数量 var minLot = GetGoodsParamerRule((int)quoteGoods.GoodsId, goodsGroup.TradeMode, GoodsTradeConts.MINOPENTRADEQTY); var dto = new QuoteGoodsDTO(quoteGoods); if (minLot != null) { dto.MinOpenNumber = minLot.FeeValue; dto.Lot = ApplicationParameter.DefaultOrderLot; ////默认下单数量 } else { dto.MinOpenNumber = 1; dto.Lot = 1; } if (ApplicationParameter.DefaultOrderLot == 0) { if (minLot != null) dto.Lot = minLot.FeeValue; ; } else { dto.Lot = ApplicationParameter.DefaultOrderLot; ////默认下单数量 } dto.AgreeUnitDisplay = quoteGoods.AgreeUnit + quoteGoods.GoodsUnit; ///合约单位 result.Add(dto); } ////P+X标签显示方式 if (goodsGroup.IsDeliveryMode) { return ToPAndXList(result); } return result; } /// /// 根据外部交易所ID获取商品列表 /// /// The ex exchange identifier. /// List{QuoteGoods}. public List GetGoodsListByExExchangeId(uint exExchangeId) { //MTP2.0 资管使用外部交易所做为分组标签 var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; if (cacheGoodsList == null) return null; var cacheGoodsGroupsList = CacheManager.CacheGoodsGroups; if (cacheGoodsGroupsList != null) { var tmp = cacheGoodsGroupsList.Where(z => z.ExChangeId == exExchangeId); if (tmp != null) { var groupIds = tmp.Select(z => z.GoodsGroupid).ToList(); return cacheGoodsList.Where(z => groupIds.Contains(z.GroupID)).OrderBy(p => p.GoodsCode).ToList(); } } return null; } /// /// 所有商品的排序 /// /// private List SortByAllGoodses() { var cacheGoodsList = CacheManager.CacheGoodsBaseInfos; // var filterList = cacheGoodsList.Where(z => z != null && z.GoodsParameters.TradeMode != eTradeMode.TRADEMODE_SALE).ToList(); List allGoodses=new List(); if (CacheManager.CacheAvailableMarketList != null) { foreach (var marketId in CacheManager.CacheAvailableMarketList) { var goodsList = cacheGoodsList.Where(z => z != null && z.MarketID == marketId).ToList(); allGoodses.AddRange(goodsList); } } allGoodses = allGoodses.OrderBy(p => p.GoodsCode).ToList(); return allGoodses; } /// /// P+X标签显示方式 /// /// The origianl list. /// ObservableCollection{QuoteGoodsDTO}. private ObservableCollection ToPAndXList(ObservableCollection origianlList) { ////P与X的关系为1:N, P为关联商品,X为交易商品,以P为主显示可以避免P出现多次。 var list = new ObservableCollection(); var index = 1; var pIdList = CacheManager.AllDeliveryRelationList.Where(z => z.RelationMode == eDeliveryContractLink.PAndX).Select(z => z.RelationGoodsId).Distinct(); foreach (var pId in pIdList) { if (pId <= 0) continue; var pGoods = origianlList.FirstOrDefault(z => z.GoodsId == pId); if (pGoods == null) continue; pGoods.ShowIndex = index++; pGoods.IsMain = true; list.Add(pGoods); var xIdList = CacheManager.AllDeliveryRelationList.Where(z => z.RelationMode == eDeliveryContractLink.PAndX && z.RelationGoodsId == pId).Select(z => z.GoodsId).Distinct(); foreach (var xId in xIdList) { if (xId <= 0) continue; var xGoods = origianlList.FirstOrDefault(z => z.GoodsId == xId); if (xGoods == null) continue; xGoods.ShowIndex = null; xGoods.IsMain = false; list.Add(xGoods); } } return list; } public Data.Model.GoodRules.GoodsFeeType GetGoodsParamerRule(int goodsId, eTradeMode tradeMode, GoodsTradeConts ruletype) { int ruleId = 1; switch (ruletype) { #region 单笔最小建仓数量 case GoodsTradeConts.MINOPENTRADEQTY: ruleId = (int)eTradeRule.TRADERULE_SINGLEMINOPENQTY; break; #endregion #region 单笔最大建仓数量 case GoodsTradeConts.MAXOPENTRADEQTY: ///单笔最大建仓数量 ruleId = (int)eTradeRule.TRADERULE_SINGLEMAXOPENQTY; break; #endregion #region 允许最大偏移点差 case GoodsTradeConts.AllowPips: ///允许最大偏移点差 ruleId = (int)eTradeRule.TRADERULE_MAXOFFSETRANGE; break; #endregion #region 单笔最小交割数量 case GoodsTradeConts.MinDeliveryQty: ruleId = (int)eTradeRule.TRADERULE_SINGLEMINDELIVERYQTY; break; #endregion #region 单笔最大交割数量 case GoodsTradeConts.MaxDeliveryQty: ruleId = (int)eTradeRule.TRADERULE_SINGLEMAXDELIVERYQTY; break; #endregion #region 最大买持仓量 case GoodsTradeConts.MaxTotalBuyHolderQty: ruleId = (int)eTradeRule.TRADERULE_MAXBUYHOLDERQTY; break; #endregion #region 最大卖持仓量 case GoodsTradeConts.MaxTotalSellHolderQty: ruleId = (int)eTradeRule.TRADERULE_MAXSELLHOLDERQTY; break; #endregion #region 手续费交易规则 case GoodsTradeConts.TradeChargeRule: ruleId = (int)eTradeRule.TRADERULE_TRADECHARGERULE; break; #endregion } return CacheManager.GetTradeRule(goodsId, ruleId); } //public eTradeFee GetTradeFee(eTradeMode tradeMode) //{ // eTradeFee tradeFeeType = 0; // switch (tradeMode) // { // case eTradeMode.TRADEMODE_MARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_MOPENTRADEMARGIN; // break; // case eTradeMode.TRADEMODE_BIDDING: // tradeFeeType = eTradeFee.TRADECOST_BOPENTRADEMARGIN; // break; // case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_XOPENTRADEMARGIN; // break; // } // return tradeFeeType; //} /// /// 获取指定【交易模式】和【交易费用类型】的费用 /// /// /// /// public eTradeFee GetTradeFee(eTradeMode tradeMode, eTradeFeeType feeType) { eTradeFee tradeFeeType = 0; switch (feeType) { //#region 建仓保证金 ////建仓保证金 //case eTradeFeeType.TRADECOST_OPENTRADEMARGIN: // switch (tradeMode) // { // case eTradeMode.TRADEMODE_MARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_MOPENTRADEMARGIN; // break; // case eTradeMode.TRADEMODE_BIDDING: // tradeFeeType = eTradeFee.TRADECOST_BOPENTRADEMARGIN; // break; // case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_XOPENTRADEMARGIN; // break; // case eTradeMode.TRADEMODE_SALE: // tradeFeeType = eTradeFee.TRADECOST_IOPENTRADEMARGIN; // break; // } // break; //#endregion //#region 买建仓手续费 ////买建仓手续费 //case eTradeFeeType.TRADECOST_BUYOPENTRADECHARGE: // switch (tradeMode) // { // case eTradeMode.TRADEMODE_MARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_MBUYOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_BIDDING: // tradeFeeType = eTradeFee.TRADECOST_BBUYOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_XBUYOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_SALE: // tradeFeeType = eTradeFee.TRADECOST_ISSUESUBSCRIBECHARGESET; // break; // } // break; //#endregion //#region 卖建仓手续费 ////卖建仓手续费 //case eTradeFeeType.TRADECOST_SELLOPENTRADECHARGE: // switch (tradeMode) // { // case eTradeMode.TRADEMODE_MARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_MSELLOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_BIDDING: // tradeFeeType = eTradeFee.TRADECOST_BSELLOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE: // tradeFeeType = eTradeFee.TRADECOST_XSELLOPENTRADECHARGE; // break; // case eTradeMode.TRADEMODE_SALE: // tradeFeeType = eTradeFee.TRADECOST_ISSUESUBSCRIBECHARGESET; // break; // } // break; //#endregion } return tradeFeeType; } /// /// 转换商品类型 /// /// 交易商品 /// public ObservableCollection ConvertGoodsDtos(List goodses) { var result = new ObservableCollection(); var quoteGoodses = goodses as IList ?? goodses.ToList(); if (!quoteGoodses.Any()) return result; var showIndex = 1; foreach (var quoteGoods in quoteGoodses) { if (quoteGoods == null) continue; quoteGoods.ShowIndex = showIndex++; ////取交易参数中的最小建仓数量 var minLot = GetGoodsParamerRule((int)quoteGoods.GoodsId, quoteGoods.TradeMode,GoodsTradeConts.MINOPENTRADEQTY); var dto = new QuoteGoodsDTO(quoteGoods); if (minLot != null) { dto.MinOpenNumber = minLot.FeeValue; } else if (ApplicationParameter.DefaultOrderLot > 0) { dto.MinOpenNumber = ApplicationParameter.DefaultOrderLot; } else { dto.MinOpenNumber = 1; } dto.Lot = dto.MinOpenNumber; dto.DeliveryGoodsName = quoteGoods.DeliveryGoodsName; ////交割商品 dto.AgreeUnitDisplay = quoteGoods.AgreeUnitDisplay; ///合约单位 result.Add(dto); } return result; } public void QueryMarketReckonInfo(int MarkerTypeID, Action> successAction, Action errorAction) { List queryCommonParams = new List(); queryCommonParams.Add(new QueryCommonParam() { ParamKey = "markettypeid", ParamValue = MarkerTypeID + string.Empty }); QueryCommonHelper.QueryCommon(QueryStatement.QueryMarketReckon, queryCommonParams, new Action>((marketReckons) => { if (successAction != null) { successAction(marketReckons); } }), (error) => { if (errorAction != null) { //RequestFunc = string.Format("查询结算信息({0})" error.RequestFunc = string.Format(Client_Resource.Resources_Service_QueryMarketReckonInfo, MarkerTypeID); errorAction(error); } }); } /// /// 委托预埋单数量查询 /// /// /// /// public void QueryPrePostDetailQty(ulong AccountId, Action> successAction, Action errorAction) { var queryCommonParams = new List(); queryCommonParams.Add(new QueryCommonParam() { ParamKey = "accountId", ParamValue = AccountId + string.Empty }); QueryCommonHelper.QueryCommon(QueryStatement.SearchPrePostDetailQty, queryCommonParams, new Action>((orderDetails) => { if (successAction != null) { successAction(orderDetails); } }), (error) => { if (errorAction != null) { //RequestFunc = 委托单参数查询 error.RequestFunc = Client_Resource.Resources_Service_QueryPreOrderParameter; errorAction(error); } }); } } }