CacheManager.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. //----------------------------------------------------------------
  2. //Module Name: CacheManager
  3. //Purpose:
  4. //CopyRight: Muchinfo
  5. //History:
  6. //----------------------------------------------------------------
  7. //DateTime Author Description
  8. //----------------------------------------------------------------
  9. //2014-03-19 deng.yinping Create
  10. //----------------------------------------------------------------
  11. using Muchinfo.MTPClient.Data.Enums;
  12. using Muchinfo.MTPClient.Data.Model.GoodRules;
  13. using Muchinfo.MTPClient.Data.Model.Sale;
  14. using Muchinfo.MTPClient.Data.Quote;
  15. using Muchinfo.PC.Common.Bosn;
  16. using Muchinfo.MTPClient.Data.Model;
  17. using Muchinfo.MTPClient.Data.Model.News;
  18. using Muchinfo.MTPClient.Infrastructure.Comparers;
  19. using Muchinfo.MTPClient.Infrastructure.Enums;
  20. using Muchinfo.MTPClient.Infrastructure.Utilities;
  21. using Newtonsoft.Json.Linq;
  22. using System;
  23. using System.Collections.Generic;
  24. using System.IO;
  25. using System.Linq;
  26. using System.Threading;
  27. using Muchinfo.MTPClient.Data.Model.Account;
  28. using Muchinfo.MTPClient.Data.Model;
  29. using Muchinfo.MTPClient.Data.Model.DBTableMsg;
  30. using Muchinfo.MTPClient.Data.Model.Delivery;
  31. namespace Muchinfo.MTPClient.Infrastructure.Cache
  32. {
  33. public delegate void DataDownloadingEventHandler(int process);
  34. public static class CacheManager
  35. {
  36. #region Fields
  37. private static DateTime _startTime;
  38. private static Dictionary<CacheType, CacheObject> _caches = new Dictionary<CacheType, CacheObject>();
  39. private static AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
  40. private static Dictionary<long, List<SaleGoods>> _saleGoodses = new Dictionary<long, List<SaleGoods>>();
  41. private static Dictionary<long, List<QuoteTradeTime>> _goodsTradeTimes = new Dictionary<long, List<QuoteTradeTime>>(); ///商品开收市时间
  42. private static Dictionary<ulong, List<TradePositionModel>> _holdingSummaries = new Dictionary<ulong, List<TradePositionModel>>(); ///当前资金帐号的持仓汇总信息
  43. private static Dictionary<long, QuoteTradePlan> _tradeDayPlan = new Dictionary<long, QuoteTradePlan>(); ///日结算计划
  44. #endregion Fields
  45. #region Methods
  46. #region Public Static Methods
  47. #region 挂牌点选缓存属性
  48. private static eTradeProperty _tradeProperty_Listing;
  49. /// <summary>
  50. /// 当前商品交易属性
  51. /// </summary>
  52. public static eTradeProperty TradeProperty_Listing
  53. {
  54. get { return _tradeProperty_Listing; }
  55. set { _tradeProperty_Listing = value; }
  56. }
  57. private static bool _isHasListingData =false;
  58. /// <summary>
  59. /// 当前买卖方向是否有委托数据
  60. /// </summary>
  61. public static bool IsHasListingData
  62. {
  63. get { return _isHasListingData; }
  64. set { _isHasListingData = value; }
  65. }
  66. private static decimal _orderLot_Listing;
  67. /// <summary>
  68. /// 挂牌点选-选择商品-》委托数量
  69. /// </summary>
  70. public static decimal OrderLot_Listing
  71. {
  72. get { return _orderLot_Listing; }
  73. set { _orderLot_Listing = value; }
  74. }
  75. private static long _orderId_Listing =0;
  76. /// <summary>
  77. /// 挂牌点选-选择商品-》委托单号
  78. /// </summary>
  79. public static long OrderId_Listing
  80. {
  81. get { return _orderId_Listing; }
  82. set { _orderId_Listing = value; }
  83. }
  84. private static Direction _buyOrSell_Listing = Direction.Bid;
  85. /// <summary>
  86. /// //挂牌点选-选择商品-》买卖方向
  87. /// </summary>
  88. public static Direction BuyOrSell_Listing
  89. {
  90. get { return _buyOrSell_Listing; }
  91. set { _buyOrSell_Listing = value; }
  92. }
  93. private static decimal _orderPrice_Listing =Decimal.Zero;
  94. /// <summary>
  95. /// //挂牌点选-选择商品-》委托单号
  96. /// </summary>
  97. public static decimal OrderPrice_Listing
  98. {
  99. get { return _orderPrice_Listing; }
  100. set { _orderPrice_Listing = value; }
  101. }
  102. private static eOrderFormType _fromType = eOrderFormType.Commom;
  103. /// <summary>
  104. /// 一般下单/挂牌下单
  105. /// </summary>
  106. public static eOrderFormType FromType
  107. {
  108. get { return _fromType; }
  109. set { _fromType = value; }
  110. }
  111. /// <summary>
  112. /// 重置挂牌下单属性
  113. /// </summary>
  114. public static void ResetListingDefaultData()
  115. {
  116. OrderId_Listing = 0;
  117. BuyOrSell_Listing = Direction.Bid;
  118. OrderPrice_Listing = Decimal.Zero;
  119. FromType = eOrderFormType.Commom;
  120. }
  121. #endregion
  122. #region 本地缓存数据属性
  123. /// <summary>
  124. /// 平仓使用资金账号ID
  125. /// </summary>
  126. public static ulong FundsAccountId { get; set; }
  127. /// <summary>
  128. ///缓存登陆后可用的市场列表 MTP2.0
  129. /// </summary>
  130. public static List<uint> CacheAvailableMarketList { get; set; }
  131. public static List<DeliveryGoodsInfoModel> CacheDeliveryGoodsInfo { get; set; }
  132. /// <summary>
  133. ///缓存最后更新时间戳 MTP2.0
  134. /// </summary>
  135. public static List<LastUpdateTimeKeyValueModel> CacheLastUpdateTimeList { get; set; }
  136. /// <summary>
  137. /// 缓存资金账户列表信息
  138. /// </summary>
  139. public static List<TAAccountAllModel> CacheTAAcountList { get; set; }
  140. /// <summary>
  141. /// 缓存商品个性化列表信息
  142. /// </summary>
  143. public static List<TradeGoodsFeeRule> CacheGoodsRuleAndFeeList { get; set; }
  144. /// <summary>
  145. /// 缓存实物持仓列表【全额持仓】 MTP2.0
  146. /// </summary>
  147. public static List<HoldingOrder> CacheRealGoodsPositionList { get; set; }
  148. /// <summary>
  149. /// 缓存持仓头寸列表【保证金持仓】 MTP2.0
  150. /// </summary>
  151. public static List<HoldingOrder> CacheGoodsPositionList { get; set; }
  152. /// <summary>
  153. /// 缓存买/卖可用持仓头寸数量 MTP2.0
  154. /// </summary>
  155. /// <returns></returns>
  156. public static uint GetGoodsPositionAvailableQty(Direction dir, uint goodsId, eTradeProperty TradeProperty)
  157. {
  158. switch (TradeProperty)
  159. {
  160. case eTradeProperty.TRADEPROPERTY_NOSHORT://全额:
  161. if (CacheRealGoodsPositionList != null)
  162. {
  163. return CacheRealGoodsPositionList.Where(x => x.GoodsId == goodsId).Select(x => x.HolderQty - x.FreezeQty-x.limitCount).FirstOrDefault();
  164. }
  165. return 0;
  166. default://保证金[查询相反方向的持仓数量]
  167. if (CacheGoodsPositionList != null && dir == Direction.Bid)
  168. {
  169. return CacheGoodsPositionList.Where(x => x.GoodsId == goodsId).Select(x => x.BuyCurPositionQty - x.BuyFrozenQty - x.BuyOtherFrozenQty).FirstOrDefault();
  170. }
  171. else if (CacheGoodsPositionList != null && dir == Direction.Ask)
  172. {
  173. return CacheGoodsPositionList.Where(x => x.GoodsId == goodsId).Select(x => x.SellCurPositionQty - x.SellFrozenQty - x.SellOtherFrozenQty).FirstOrDefault();
  174. }
  175. return 0;
  176. }
  177. }
  178. /// <summary>
  179. /// 获取缓存持仓全额、保证金列表 MTP2.0
  180. /// </summary>
  181. /// <returns></returns>
  182. public static List<HoldingOrder> GetGoodsPositionList(Direction buyOrSell, uint goodsId, eTradeMode tradeMode)
  183. {
  184. return CacheGoodsPositionList.Where(x => x.GoodsId == goodsId).ToList();
  185. //switch (tradeMode)
  186. //{
  187. // case eTradeMode.Full_Transfer://全额:
  188. // if (CacheRealGoodsPositionList != null)
  189. // {
  190. // return CacheRealGoodsPositionList.Where(x => x.GoodsId == goodsId).ToList();
  191. // }
  192. // return null;
  193. // default://保证金
  194. // if (CacheGoodsPositionList != null)
  195. // {
  196. // return CacheGoodsPositionList.Where(x => x.GoodsId == goodsId).ToList();
  197. // }
  198. // return null;
  199. //}
  200. }
  201. /// <summary>
  202. /// 获取缓存持仓全额、保证金列表 MTP2.0
  203. /// </summary>
  204. /// <returns></returns>
  205. public static TradePositionModel GetHoldingSummary(uint goodsId, string currentFundId)
  206. {
  207. return HoldingSummaries[UInt64.Parse(currentFundId)].Where(x => x.GoodsId == goodsId).FirstOrDefault();
  208. }
  209. ///缓存最大通知id MTP2.0
  210. public static long CacheServerLastNoticeId { get; set; }
  211. public static List<Exchange> CacheExchanges
  212. {
  213. get
  214. {
  215. var emptyResult = new List<Exchange>();
  216. if (!_caches.ContainsKey(CacheType.Exchange) || _caches[CacheType.Exchange].CacheList == null) return emptyResult;
  217. var result = _caches[CacheType.Exchange].CacheList.OfType<Exchange>().Where(z => z != null).Distinct(new ExchangeDataModelComparer());
  218. return result.ToList();
  219. }
  220. }
  221. public static List<GoodsGroup> CacheGoodsGroups
  222. {
  223. get
  224. {
  225. var emptyResult = new List<GoodsGroup>();
  226. if (!_caches.ContainsKey(CacheType.GoodsGroup) || _caches[CacheType.GoodsGroup].CacheList == null) return emptyResult;
  227. var result = _caches[CacheType.GoodsGroup].CacheList.OfType<GoodsGroup>().Where(z => z != null);
  228. return result.ToList();
  229. }
  230. }
  231. /// <summary>
  232. /// 缓存市场组MTP2.0
  233. /// </summary>
  234. public static List<MarketsInfoModel> CacheMarketsGroups
  235. {
  236. get
  237. {
  238. var emptyResult = new List<MarketsInfoModel>();
  239. if (!_caches.ContainsKey(CacheType.MarketGroup) || _caches[CacheType.MarketGroup].CacheList == null) return emptyResult;
  240. var result = _caches[CacheType.MarketGroup].CacheList.OfType<MarketsInfoModel>().Where(z => z != null);
  241. return result.ToList();
  242. }
  243. }
  244. /// <summary>
  245. /// 缓存商品信息MTP2.0
  246. /// </summary>
  247. public static List<QuoteGoods> CacheGoodsBaseInfos
  248. {
  249. get
  250. {
  251. var emptyResult = new List<QuoteGoods>();
  252. if (!_caches.ContainsKey(CacheType.GoodsBaseInfo) || _caches[CacheType.GoodsBaseInfo].CacheList == null) return emptyResult;
  253. //var result = _caches[CacheType.GoodsBaseInfo].CacheList.OfType<Goods>().Where(z => z != null && z.IsValid);
  254. var result = _caches[CacheType.GoodsBaseInfo].CacheList.OfType<QuoteGoods>().Where(z => z != null);
  255. return result.ToList();
  256. }
  257. }
  258. /// <summary>
  259. /// 商品开收市时间
  260. /// </summary>
  261. public static Dictionary<long, List<QuoteTradeTime>> GoodsTradeTimes
  262. {
  263. get
  264. {
  265. return _goodsTradeTimes;
  266. }
  267. }
  268. /// <summary>
  269. /// 日结算计划
  270. /// </summary>
  271. public static Dictionary<long, QuoteTradePlan> TradeDayPlan
  272. {
  273. get
  274. {
  275. return _tradeDayPlan;
  276. }
  277. }
  278. /// <summary>
  279. /// 资金账户对应的持仓信息-MTP2.0无用
  280. /// </summary>
  281. public static Dictionary<ulong, List<TradePositionModel>> HoldingSummaries
  282. {
  283. get
  284. {
  285. return _holdingSummaries;
  286. }
  287. }
  288. /// <summary>
  289. /// 发售商品组,商品
  290. /// </summary>
  291. public static Dictionary<long, List<SaleGoods>> SaleGoodses
  292. {
  293. get { return _saleGoodses; }
  294. }
  295. public static List<NewsCategory> CacheNewsCategory
  296. {
  297. get
  298. {
  299. var emptyResult = new List<NewsCategory>();
  300. if (!_caches.ContainsKey(CacheType.NewsCategory) || _caches[CacheType.NewsCategory].CacheList == null) return emptyResult;
  301. var result = _caches[CacheType.NewsCategory].CacheList.OfType<NewsCategory>().Where(z => z != null);
  302. return result.ToList();
  303. }
  304. }
  305. private static Dictionary<int, TradeGoodsFeeRule> _tradeGoodsFeeRules=new Dictionary<int, TradeGoodsFeeRule>();
  306. /// <summary>
  307. /// /交易商品的费用计算方式,与交易规则
  308. /// </summary>
  309. public static Dictionary<int, TradeGoodsFeeRule> TradeGoodsFeeRules
  310. {
  311. get
  312. {
  313. return _tradeGoodsFeeRules;
  314. }
  315. set
  316. {
  317. _tradeGoodsFeeRules = value;
  318. }
  319. }
  320. private static Dictionary<int, int> _marketStatus = new Dictionary<int, int>();
  321. /// <summary>
  322. /// 保存市场类型状态
  323. /// </summary>
  324. public static Dictionary<int, int> MarketStatus
  325. {
  326. get
  327. {
  328. return _marketStatus;
  329. }
  330. set
  331. {
  332. _marketStatus = value;
  333. }
  334. }
  335. private static List<MarketRunModelNew> _marketRunsNew = new List<MarketRunModelNew>();
  336. /// <summary>
  337. /// 缓存市场状态
  338. /// </summary>
  339. /// <value>The market runs.</value>
  340. public static List<MarketRunModelNew> MarketRuns
  341. {
  342. get
  343. {
  344. return _marketRunsNew;
  345. }
  346. set
  347. {
  348. _marketRunsNew = value;
  349. }
  350. }
  351. #region 获取服务交易日
  352. /// <summary>
  353. /// 获取服务运行状态
  354. /// </summary>
  355. /// <param name="marketid">The marketid.</param>
  356. /// <returns>MarketRunModelNew.</returns>
  357. public static MarketRunModelNew GetMarketRunById(int marketid)
  358. {
  359. if (MarketRuns == null || !MarketRuns.Any()) return null;
  360. var model = MarketRuns.FirstOrDefault(z => z.MarketId == marketid);
  361. return model;
  362. }
  363. /// <summary>
  364. /// 更新服务运行状态
  365. /// </summary>
  366. /// <param name="models">The models.</param>
  367. public static void UpdateMarketRun(List<MarketRunModelNew> models)
  368. {
  369. if (models == null || !models.Any()) return;
  370. foreach (var model in models)
  371. {
  372. var item = GetMarketRunById(model.MarketId);
  373. if (item != null)MarketRuns.Remove(item);
  374. MarketRuns.Add(model);
  375. }
  376. }
  377. #endregion
  378. #region 交易商品的合约单位缓存
  379. private static List<GoodsUnit> _tradeGoodsUnit = new List<GoodsUnit>();
  380. /// <summary>
  381. /// 交易商品的合约单位
  382. /// </summary>
  383. public static List<GoodsUnit> TradeGoodsUnit
  384. {
  385. get
  386. {
  387. return _tradeGoodsUnit;
  388. }
  389. set
  390. {
  391. _tradeGoodsUnit = value;
  392. }
  393. }
  394. #endregion
  395. #region p+x交割商品信息LIST缓存
  396. private static List<RelationPAndXGoodsInfoModel> _allDeliveryRelationList = new List<RelationPAndXGoodsInfoModel>();
  397. /// <summary>
  398. /// p+x交割商品信息LIST缓存
  399. /// </summary>
  400. public static List<RelationPAndXGoodsInfoModel> AllDeliveryRelationList
  401. {
  402. get
  403. {
  404. return _allDeliveryRelationList;
  405. }
  406. set
  407. {
  408. _allDeliveryRelationList = value;
  409. }
  410. }
  411. #endregion
  412. /// <summary>
  413. /// 获取指定的更新时间戳
  414. /// </summary>
  415. /// <returns></returns>
  416. public static ulong GetLastUpdateTimeBy(LastUpdateTimeType currentType)
  417. {
  418. ulong defalutValue = 0;
  419. if (CacheLastUpdateTimeList != null && CacheLastUpdateTimeList.Any())
  420. {
  421. string currentValue =CacheLastUpdateTimeList.Where(x => x.TimeKey == currentType).Select(x => x.TimeValue).FirstOrDefault();
  422. UInt64.TryParse(currentValue,out defalutValue);
  423. }
  424. return defalutValue;
  425. }
  426. /// <summary>
  427. ///获取交易规则,优先使用个人的,可能返回空
  428. /// </summary>
  429. /// <param name="goodId"></param>
  430. /// <param name="ruleId"></param>
  431. /// <returns></returns>
  432. public static GoodsFeeType GetTradeRule(int goodId, int ruleId)
  433. {
  434. GoodsFeeType resultRule = null;
  435. if (TradeGoodsFeeRules!=null&&TradeGoodsFeeRules.ContainsKey(goodId))
  436. {
  437. if (TradeGoodsFeeRules[goodId].AccountGoodsRules.ContainsKey(ruleId))
  438. {
  439. resultRule= TradeGoodsFeeRules[goodId].AccountGoodsRules[ruleId];
  440. }
  441. else if (TradeGoodsFeeRules[goodId].GoodsRules.ContainsKey(ruleId))
  442. {
  443. resultRule = TradeGoodsFeeRules[goodId].GoodsRules[ruleId];
  444. }
  445. }
  446. return resultRule;
  447. }
  448. /// <summary>
  449. /// 获取商品费用信息
  450. /// </summary>
  451. /// <param name="goodsId">商品ID</param>
  452. /// <param name="feeId">费用类型</param>
  453. /// <param name="isGoods">是否商品的</param>
  454. /// <returns></returns>
  455. public static GoodsFeeType GetGoodsTradeFeeType(int goodsId, int feeId, bool isGoods = true)
  456. {
  457. GoodsFeeType feeRule = null;
  458. if (TradeGoodsFeeRules != null && TradeGoodsFeeRules.ContainsKey(goodsId))
  459. {
  460. if (isGoods)
  461. {
  462. if (TradeGoodsFeeRules[goodsId].GoodsFees.ContainsKey(feeId))
  463. {
  464. feeRule = TradeGoodsFeeRules[goodsId].GoodsFees[feeId];
  465. }
  466. }
  467. else
  468. {
  469. if (TradeGoodsFeeRules[goodsId].AccountGoodsFees.ContainsKey(feeId))
  470. {
  471. feeRule = TradeGoodsFeeRules[goodsId].AccountGoodsFees[feeId];
  472. }
  473. }
  474. }
  475. return feeRule;
  476. }
  477. #endregion
  478. ///// <summary>
  479. ///// 开多任务 加载交易信息
  480. ///// </summary>
  481. //public static void LoadBaseInfo()
  482. //{
  483. // TaskSuppleTable();
  484. // Task.Factory.TryStartNew(GetExchangeListAndMerage, () => { });
  485. // Task.Factory.TryStartNew(GetMarketDetailListAndMerage, () => { });
  486. //}
  487. /// <summary>
  488. /// 缓存登陆后基本信息MTP2.0
  489. /// </summary>
  490. /// <param name="accountInfoEntity"></param>
  491. public static void LoadLoginBaseInfo(AccountBaseInfoModel accountInfoEntity)
  492. {
  493. if (null != accountInfoEntity && accountInfoEntity.ServerLastNoticeId !=0) ////最后更新时间列表
  494. {
  495. //登录取到的ID为最后的ID,注释此代码-dyp
  496. //CacheServerLastNoticeId = accountInfoEntity.ServerLastNoticeId;
  497. }
  498. if (null != accountInfoEntity && accountInfoEntity.LastUpdateTimeList.Any() && accountInfoEntity.LastUpdateTimeList.Count > 0) ////最后更新时间列表
  499. {
  500. CacheLastUpdateTimeList = accountInfoEntity.LastUpdateTimeList;
  501. }
  502. if (null != accountInfoEntity && accountInfoEntity.TAAccountList.Any() && accountInfoEntity.TAAccountList.Count > 0) ////用户资金账户列表信息
  503. {
  504. CacheTAAcountList = accountInfoEntity.TAAccountList;
  505. if (CacheAvailableMarketList == null)
  506. CacheAvailableMarketList = new List<uint>();
  507. else
  508. CacheAvailableMarketList.Clear();
  509. HoldingSummaries.Clear();
  510. foreach (var account in accountInfoEntity.TAAccountList)
  511. {
  512. HoldingSummaries.Add(account.FundsAccounts.AccountId, account.GoodsPositionList);
  513. CacheAvailableMarketList.AddRange(account.MarketsIdList);
  514. }
  515. CacheAvailableMarketList = CacheAvailableMarketList.Distinct().ToList();
  516. }
  517. if (null != accountInfoEntity && accountInfoEntity.GoodsRuleAndFeeList.Any() && accountInfoEntity.GoodsRuleAndFeeList.Count > 0)
  518. {
  519. CacheGoodsRuleAndFeeList = accountInfoEntity.GoodsRuleAndFeeList;
  520. }
  521. }
  522. /// <summary>
  523. /// 缓存市场信息MTP2.0
  524. /// </summary>
  525. /// <param name="accountInfoEntity"></param>
  526. public static void LoadMarketInfoList(List<MarketsInfoModel> marketsEntity)
  527. {
  528. TaskSuppleTable();
  529. if (null != marketsEntity && marketsEntity.Any()) ////市场信息
  530. {
  531. marketsEntity = UpdateMarketsGroup(marketsEntity, GoodsFromScr.Trade); ////更新市场组
  532. var lastModifyTime = ApplicationParameter.BasicDateTime;
  533. UpdateTable(CacheType.MarketGroup, lastModifyTime, marketsEntity.ToArray());
  534. }
  535. }
  536. /// <summary>
  537. /// 缓存商品GOODS信息MTP2.0
  538. /// </summary>
  539. /// <param name="accountInfoEntity"></param>
  540. public static void LoadGoodsInfoList(List<QuoteGoods> goodsEntity, GoodsFromScr goodsScr)
  541. {
  542. TaskSuppleTable();
  543. if (null != goodsEntity && goodsEntity.Any() && CacheAvailableMarketList != null) ////交易商品
  544. {
  545. //商品市场权限过滤,MTP2.0NEW
  546. var result = goodsEntity.Distinct(new QuoteGoodsComparer()).Where(x => CacheAvailableMarketList.Contains(x.MarketID)).ToList();
  547. result = UpdateGoods(result, goodsScr); ////设置商品来源
  548. var lastModifyTime = ApplicationParameter.BasicDateTime;
  549. UpdateTable(CacheType.GoodsBaseInfo, lastModifyTime, result.ToArray());
  550. }
  551. }
  552. /// <summary>
  553. /// 商品、市场,交易所信息缓存
  554. /// </summary>
  555. /// <param name="accountInfoEntity">用户有权限的交易信息</param>
  556. public static void LoadGoodsBaseInfo(AccountInfoEntity accountInfoEntity)
  557. {
  558. LoadGoodsBaseInfo(accountInfoEntity.QuoteGoodses, accountInfoEntity.GoodsGroups, GoodsFromScr.Trade);
  559. }
  560. public static void LoadExchangeInfo(List<Exchange> Exchanges)
  561. {
  562. if (null != Exchanges && Exchanges.Any()) ////交易所信息
  563. {
  564. var lastModifyTime = ApplicationParameter.BasicDateTime;// allExchanges.Max(z => z.LastModifiedTime);
  565. UpdateTable(CacheType.Exchange, lastModifyTime, Exchanges.ToArray());
  566. }
  567. }
  568. /// <summary>
  569. /// 缓存商品组
  570. /// </summary>
  571. /// <param name="goodsGroupsEntity"></param>
  572. public static void LoadGoodsGroupList(List<GoodsGroup> goodsGroupsEntity)
  573. {
  574. TaskSuppleTable();
  575. if (null != goodsGroupsEntity && goodsGroupsEntity.Any()) ////市场信息
  576. {
  577. var newEntity = UpdateGoodsGroup(goodsGroupsEntity, GoodsFromScr.Trade); ////更新市场组
  578. var lastModifyTime = ApplicationParameter.BasicDateTime;
  579. UpdateTable(CacheType.GoodsGroup, lastModifyTime, newEntity.ToArray());
  580. }
  581. }
  582. /// <summary>
  583. /// 商品、市场,交易所信息缓存
  584. /// </summary>
  585. public static void LoadGoodsBaseInfo(List<QuoteGoods> goodses, List<GoodsGroup> goodsGroups, GoodsFromScr goodsScr)
  586. {
  587. TaskSuppleTable();
  588. //if (null != Exchanges && Exchanges.Any()) ////交易所信息
  589. //{
  590. // var lastModifyTime = ApplicationParameter.BasicDateTime;// allExchanges.Max(z => z.LastModifiedTime);
  591. // UpdateTable(CacheType.Exchange, lastModifyTime, Exchanges.ToArray());
  592. //}
  593. if (null != goodsGroups && goodsGroups.Any()) ////市场信息
  594. {
  595. goodsGroups = UpdateGoodsGroup(goodsGroups, goodsScr); ////更新商品组
  596. var lastModifyTime = ApplicationParameter.BasicDateTime;//allExchanges.Max(z => z.LastModifiedTime);
  597. UpdateTable(CacheType.GoodsGroup, lastModifyTime, goodsGroups.ToArray());
  598. }
  599. if (null != goodses && goodses.Any()) ////交易商品
  600. {
  601. var result = goodses.Distinct(new QuoteGoodsComparer()).ToList();
  602. result = UpdateGoods(result, goodsScr); ////设置商品来源
  603. var lastModifyTime = ApplicationParameter.BasicDateTime; //allExchanges.Max(z => z.LastModifiedTime);
  604. UpdateTable(CacheType.GoodsBaseInfo, lastModifyTime, result.ToArray());
  605. }
  606. }
  607. /// <summary>
  608. /// 更新商品并设置商品来源
  609. /// </summary>
  610. /// <param name="goodses">商品列表</param>
  611. /// <param name="goodsScr">商品来源</param>
  612. /// <returns></returns>
  613. private static List<QuoteGoods> UpdateGoods(List<QuoteGoods> goodses, GoodsFromScr goodsScr)
  614. {
  615. if (CacheGoodsBaseInfos == null || !CacheGoodsBaseInfos.Any()) ////当前没有商品添加
  616. {
  617. foreach (var quoteGoodse in goodses)
  618. {
  619. quoteGoodse.ContainsGoodsSrc = (int) goodsScr; ////设置商品来源
  620. quoteGoodse.TradeMode = CacheMarketsGroups.Where(x => x.MarketID == quoteGoodse.MarketID).Select(x=>x.TradeMode).FirstOrDefault();
  621. quoteGoodse.TradeProperty = CacheMarketsGroups.Where(x => x.MarketID == quoteGoodse.MarketID).Select(x => x.TradeProperty).FirstOrDefault();
  622. }
  623. return goodses;
  624. }
  625. else
  626. {
  627. var temGoodses = new List<QuoteGoods>();
  628. var list = CacheGoodsBaseInfos;
  629. foreach (var quoteGoodse in goodses)
  630. {
  631. var existGoods = CacheGoodsBaseInfos.FirstOrDefault((goods) => goods.Symbol == quoteGoodse.Symbol);
  632. quoteGoodse.TradeMode = CacheMarketsGroups.Where(x => x.MarketID == quoteGoodse.MarketID).Select(x => x.TradeMode).FirstOrDefault();
  633. if (existGoods == null) ////商品不存在需添加
  634. {
  635. quoteGoodse.ContainsGoodsSrc = (int) goodsScr;
  636. temGoodses.Add(quoteGoodse);
  637. }
  638. else
  639. {
  640. if (goodsScr == GoodsFromScr.Trade) ////如果存在更新从交易更新的。则先移除旧的
  641. {
  642. list.Remove(existGoods);
  643. quoteGoodse.ContainsGoodsSrc = (int) GoodsFromScr.Trade | (int) existGoods.ContainsGoodsSrc; ////或运算
  644. temGoodses.Add(quoteGoodse);
  645. }
  646. else
  647. {
  648. existGoods.ContainsGoodsSrc = existGoods.ContainsGoodsSrc | (int)goodsScr; //// 商品包括多个来源 ////或运算
  649. }
  650. }
  651. }
  652. list.AddRange(temGoodses);
  653. return list;
  654. }
  655. }
  656. /// <summary>
  657. /// 更新商品组
  658. /// </summary>
  659. /// <param name="goodsGroups">商品组列表</param>
  660. /// <param name="GoodsFromScr">商品组更新来源</param>
  661. /// <returns></returns>
  662. private static List<GoodsGroup> UpdateGoodsGroup(List<GoodsGroup> goodsGroups, GoodsFromScr goodsScr)
  663. {
  664. if (CacheGoodsGroups == null || !CacheGoodsGroups.Any()) ////当前没有商品添加
  665. {
  666. foreach (var goodsGroup in goodsGroups)
  667. {
  668. MarketStatus[goodsGroup.MarketTypeID] = 0;
  669. }
  670. return goodsGroups;
  671. }
  672. else
  673. {
  674. var temGroups = new List<GoodsGroup>();
  675. var cacheGroups = CacheGoodsGroups;
  676. foreach (var goodsGroup in goodsGroups)
  677. {
  678. var groupItem= cacheGroups.FirstOrDefault((item) => item.GoodsGroupid == goodsGroup.GoodsGroupid);
  679. if (groupItem != null)
  680. {
  681. if (goodsScr == GoodsFromScr.Trade) ////如果存在更新从交易更新的。则先移除旧的
  682. {
  683. cacheGroups.Remove(groupItem);
  684. temGroups.Add(goodsGroup);
  685. MarketStatus[goodsGroup.MarketTypeID] = 0;
  686. }
  687. }
  688. else
  689. {
  690. temGroups.Add(goodsGroup);
  691. }
  692. }
  693. cacheGroups.AddRange(temGroups);
  694. return cacheGroups;
  695. }
  696. }
  697. /// <summary>
  698. /// 更新市场组MTP2.0
  699. /// </summary>
  700. /// <param name="marketsGroups">市场组列表</param>
  701. /// <param name="GoodsFromScr">市场组更新来源</param>
  702. /// <returns></returns>
  703. private static List<MarketsInfoModel> UpdateMarketsGroup(List<MarketsInfoModel> marketGroups, GoodsFromScr goodsScr)
  704. {
  705. if (CacheMarketsGroups == null || !CacheMarketsGroups.Any()) ////当前没有市场添加
  706. {
  707. foreach (var marketGroup in marketGroups)
  708. {
  709. MarketStatus[(int)marketGroup.MarketID] = 0;
  710. }
  711. return marketGroups;
  712. }
  713. else
  714. {
  715. var temGroups = new List<MarketsInfoModel>();
  716. var cacheGroups = CacheMarketsGroups;
  717. foreach (var marketGroup in marketGroups)
  718. {
  719. var groupItem = cacheGroups.FirstOrDefault((item) => item.MarketID == marketGroup.MarketID);
  720. if (groupItem != null)
  721. {
  722. if (goodsScr == GoodsFromScr.Trade) ////如果存在更新从交易更新的。则先移除旧的
  723. {
  724. cacheGroups.Remove(groupItem);
  725. temGroups.Add(marketGroup);
  726. MarketStatus[(int)marketGroup.MarketID] = 0;
  727. }
  728. }
  729. else
  730. {
  731. temGroups.Add(marketGroup);
  732. }
  733. }
  734. cacheGroups.AddRange(temGroups);
  735. return cacheGroups;
  736. }
  737. }
  738. #endregion Public Static Methods
  739. #region Private Static Methods
  740. private static List<CacheType> GetAllCacheTypes()
  741. {
  742. var result = new List<CacheType>();
  743. var values = Enum.GetValues(typeof(CacheType));
  744. foreach (var value in values)
  745. {
  746. result.Add((CacheType)value);
  747. }
  748. return result;
  749. }
  750. ///// <summary>
  751. ///// 多任务使用查询交易所信息
  752. ///// </summary>
  753. //private static void GetExchangeListAndMerage()
  754. //{
  755. // int errorCode = 0;
  756. // var tradeAccount = UserManager.CurrentTradeAccount;
  757. // if (tradeAccount == null) return;
  758. // var allExchanges = new List<Exchange>();
  759. // var basicDataService = SimpleIoc.Default.GetInstance<IBasicDataService>();
  760. // try
  761. // {
  762. // var exchanges = basicDataService.GetExchanges(new List<string>() { tradeAccount.ExchangeId.ToString() });
  763. // if (exchanges == null || !exchanges.Any())
  764. // {
  765. // throw new Exception(Client_Resource.Infrastructure_TradingFailurePleaseTryAgain);
  766. // }
  767. // allExchanges.AddRange(exchanges);
  768. // foreach (var exchange in allExchanges)
  769. // {
  770. // //等待服务联调
  771. // basicDataService.GetExchangesParamer(exchange);
  772. // }
  773. // }
  774. // catch (MuchinfoException muchinfo)
  775. // {
  776. // errorCode = muchinfo.ReturnCode;
  777. // }
  778. // catch (Exception ex)
  779. // {
  780. // errorCode = ExceptionManager.QueryExchangeError;
  781. // }
  782. // MessengerHelper.DefaultSend(new DisplayMessage()
  783. // {
  784. // ErrorCode = errorCode,
  785. // Result = errorCode == 0,
  786. // QueryType = QueryType.Exchange,
  787. // }, MessengerTokens.LoadBaseInfo);
  788. // if (allExchanges.Any())
  789. // {
  790. // var lastModifyTime = ApplicationParameter.BasicDateTime;// allExchanges.Max(z => z.LastModifiedTime);
  791. // UpdateTable(CacheType.Exchange, lastModifyTime, allExchanges.ToArray());
  792. // }
  793. //}
  794. ///// <summary>
  795. ///// 多任务使用查询市场信息
  796. ///// </summary>
  797. ///// <exception cref="System.Exception"></exception>
  798. //private static void GetMarketDetailListAndMerage()
  799. //{
  800. // int errorCode = 0;
  801. // var tradeAccount = UserManager.CurrentTradeAccount;
  802. // if (tradeAccount == null) return;
  803. // var allMarkets = new List<Market>();
  804. // var basicDataService = SimpleIoc.Default.GetInstance<IBasicDataService>();
  805. // try
  806. // {
  807. // var markets = basicDataService.GetMarkets(tradeAccount.TradeCode);
  808. // if (markets == null || !markets.Any())
  809. // {
  810. // throw new Exception(Client_Resource.Infrastructure_MatketFailurePleaseTrayAgain);
  811. // }
  812. // allMarkets.AddRange(markets);
  813. // }
  814. // catch (MuchinfoException muchinfo)
  815. // {
  816. // errorCode = muchinfo.ReturnCode;
  817. // }
  818. // catch (Exception ex)
  819. // {
  820. // errorCode = ExceptionManager.QueryMarketsError;
  821. // }
  822. // MessengerHelper.DefaultSend(new DisplayMessage()
  823. // {
  824. // ErrorCode = errorCode,
  825. // Result = errorCode == 0,
  826. // QueryType = QueryType.Markets,
  827. // }, MessengerTokens.LoadBaseInfo);
  828. // if (allMarkets.Any())
  829. // {
  830. // var lastModifyTime = ApplicationParameter.BasicDateTime;//allExchanges.Max(z => z.LastModifiedTime);
  831. // UpdateTable(CacheType.MarketDetail, lastModifyTime, allMarkets.ToArray());
  832. // }
  833. // _autoResetEvent.Set();
  834. //}
  835. private static List<object> ConvertCacheList<T>(CacheObject cacheObject) where T : class
  836. {
  837. if (cacheObject == null || cacheObject.CacheList == null || !cacheObject.CacheList.Any()) return null;
  838. var models = cacheObject.CacheList.Select(z =>
  839. {
  840. var jObject = z as JObject;
  841. return jObject != null ? jObject.ToObject<T>() : default(T);
  842. });
  843. return models.ToList<object>();
  844. }
  845. /// <summary>
  846. /// Loads the table.
  847. /// </summary>
  848. /// <param name="cacheType">Type of the cache.</param>
  849. private static void LoadTable(CacheType cacheType)
  850. {
  851. if (!_caches.ContainsKey(cacheType))
  852. {
  853. var cacheObject = LoadCacheObject(cacheType);
  854. if (_caches.ContainsKey(cacheObject.CacheType))
  855. {
  856. _caches.Remove(cacheObject.CacheType);
  857. }
  858. _caches.Add(cacheObject.CacheType, cacheObject);
  859. }
  860. }
  861. private static CacheObject LoadCacheObject(CacheType cacheType)
  862. {
  863. string cacheObjectFile = Path.Combine(UserManager.UserDataFolder, cacheType.ToString() + UserManager.LocalDataExtensionName);
  864. var cacheObject = BsonHelper.LoadData<CacheObject>(cacheObjectFile).FirstOrDefault();
  865. if (cacheObject == null) cacheObject = new CacheObject(cacheType) { CacheTime = DateTime.MinValue };
  866. if (cacheObject.CacheList != null && cacheObject.CacheList.Count > 0)
  867. {
  868. switch (cacheObject.CacheType)
  869. {
  870. case CacheType.Exchange:
  871. cacheObject.CacheList = ConvertCacheList<Exchange>(cacheObject);
  872. break;
  873. //case CacheType.ExchangeChange:
  874. // cacheObject.CacheList = ConvertCacheList<ExchangeChangeDataModel>(cacheObject);
  875. // break;
  876. case CacheType.GoodsBaseInfo:
  877. cacheObject.CacheList = ConvertCacheList<QuoteGoods>(cacheObject);
  878. break;
  879. case CacheType.MarketGroup:
  880. cacheObject.CacheList = ConvertCacheList<MarketsInfoModel>(cacheObject);
  881. break;
  882. case CacheType.GoodsGroup:
  883. cacheObject.CacheList = ConvertCacheList<Market>(cacheObject);
  884. break;
  885. //case CacheType.QuoteHead:
  886. // cacheObject.CacheList = ConvertCacheList<QuoteHeadStyleDataModel>(cacheObject);
  887. // break;
  888. //case CacheType.QuoteHeadDetail:
  889. // cacheObject.CacheList = ConvertCacheList<QuoteHeadDetailDataModel>(cacheObject);
  890. // break;
  891. //case CacheType.Sector:
  892. // cacheObject.CacheList = ConvertCacheList<SectorDataModel>(cacheObject);
  893. // break;
  894. //case CacheType.Warning:
  895. // cacheObject.CacheList = ConvertCacheList<Warning>(cacheObject);
  896. // break;
  897. case CacheType.NewsCategory:
  898. cacheObject.CacheList = ConvertCacheList<NewsCategory>(cacheObject);
  899. break;
  900. }
  901. }
  902. return cacheObject;
  903. }
  904. ///// <summary>
  905. ///// Saves the table.
  906. ///// </summary>
  907. ///// <param name="cacheType">Type of the cache.</param>
  908. //private static void SaveTable(CacheType cacheType)
  909. //{
  910. // var tableFile = Path.Combine(UserManager.UserDataFolder, cacheType.ToString() + UserManager.LocalDataExtensionName);
  911. // var table = _caches[cacheType];
  912. // BsonHelper.SaveData(tableFile, table, null, true);
  913. //}
  914. /// <summary>
  915. /// 多任务添加缓存类型
  916. /// </summary>
  917. private static void TaskSuppleTable()
  918. {
  919. var typeList = GetAllCacheTypes();
  920. foreach (CacheType type in typeList)
  921. {
  922. switch (type)
  923. {
  924. case CacheType.Other:
  925. case CacheType.Finished:
  926. break;
  927. //case CacheType.Warning:
  928. // LoadTable(CacheType.Warning);
  929. // break;
  930. default:
  931. LoadTable(type);
  932. break;
  933. }
  934. }
  935. }
  936. private static void UpdateTable<T>(CacheType cacheType, DateTime lastModifyTime, T[] newRecords, bool isSave = true)
  937. {
  938. if (!_caches.ContainsKey(cacheType))
  939. return;
  940. if (null == newRecords || newRecords.Length == 0) return;
  941. var data = _caches[cacheType] ?? new CacheObject(cacheType);
  942. if (data.CacheList == null) data.CacheList = new List<object>();
  943. var newList = new List<object>();
  944. foreach (var newRecord in newRecords)
  945. {
  946. newList.Add(newRecord);
  947. }
  948. //test
  949. data.CacheList.Clear();
  950. //end
  951. data.CacheList.AddRange(newList);
  952. //更新缓存时间
  953. data.CacheTime = lastModifyTime;
  954. _caches[cacheType] = data;
  955. }
  956. #endregion Private Static Methods
  957. #endregion Methods
  958. #region 存储外部交易所、商品组、商品的关系
  959. public static void LoadExChangeGroupGoods(ExChangeCheckModel exChangeCheckModel)
  960. {
  961. TaskSuppleTable();
  962. if (null != exChangeCheckModel) //
  963. {
  964. var lastModifyTime = ApplicationParameter.BasicDateTime;
  965. List<ExChangeCheckModel> list = new List<ExChangeCheckModel>() {exChangeCheckModel};
  966. UpdateTable(CacheType.ExChangeGroupGoods, lastModifyTime, list.ToArray());
  967. }
  968. }
  969. public static List<ExChangeCheckModel> CacheExChangeGroupGoods
  970. {
  971. get
  972. {
  973. if (!_caches.ContainsKey(CacheType.ExChangeGroupGoods) || _caches[CacheType.ExChangeGroupGoods].CacheList == null) return null;
  974. //var result = _caches[CacheType.GoodsBaseInfo].CacheList.OfType<Goods>().Where(z => z != null && z.IsValid);
  975. IEnumerable<ExChangeCheckModel> result = _caches[CacheType.ExChangeGroupGoods].CacheList.OfType<ExChangeCheckModel>().Where(z => z != null);
  976. return result.ToList();
  977. }
  978. }
  979. /// <summary>
  980. /// 终端启动时通过通用查许从quotesourcegroup表获取行情交易日
  981. /// </summary>
  982. public static List<QuoteSourceGroupMarketData> QuoteSourceGroupMarketDatas { get; set; }
  983. #endregion
  984. }
  985. }