MakeCloseViewModel.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. //----------------------------------------------------------------
  2. //Module Name: $safeprojectname$
  3. //Purpose:
  4. //CopyRight: Muchinfo
  5. //History:
  6. //----------------------------------------------------------------
  7. //DateTime 2016/1/16 16:31:15
  8. //Author
  9. //Description Create
  10. //----------------------------------------------------------------
  11. using GalaSoft.MvvmLight.Ioc;
  12. using Muchinfo.MTPClient.Data.Enums;
  13. using Muchinfo.MTPClient.Data.Model;
  14. using Muchinfo.MTPClient.Data.Model.Account;
  15. using Muchinfo.MTPClient.Infrastructure.Utilities;
  16. using Muchinfo.MTPClient.IService;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Threading.Tasks;
  21. namespace Muchinfo.MTPClient.Trade.ViewModels
  22. {
  23. public class MakeCloseViewModel : CloseOrderBase
  24. {
  25. /// <summary>
  26. /// 按单平仓
  27. /// </summary>
  28. /// <param name="holdOrder"></param>
  29. /// <param name="goods"></param>
  30. /// <param name="orderType"></param>
  31. public MakeCloseViewModel(HoldingOrder holdOrder, QuoteGoods goods, OrderType orderType = OrderType.MarketCloseOrder)
  32. : base(holdOrder, goods, orderType)
  33. {
  34. if (HoldOrder.RelateOrderID > 0)
  35. {
  36. IsOrderTypeEnable = false;
  37. Task.Factory.StartNew(() =>
  38. {
  39. var limitItems = UserManager.GetCacheOrders<OrderDetail>();
  40. if (limitItems != null)
  41. {
  42. var entrurstOrder = limitItems.FirstOrDefault((item) => item.OrderID == HoldOrder.RelateOrderID);
  43. if (entrurstOrder != null)
  44. {
  45. CurrentExpirationType = entrurstOrder.VailType;
  46. IsExpiration = false;
  47. }
  48. }
  49. });
  50. }
  51. SetQuotePrice();
  52. IsBidMarket = false;
  53. IsOrderTypeEnable = true;
  54. }
  55. /// <summary>
  56. /// 汇总平仓
  57. /// </summary>
  58. /// <param name="holdingSummary"></param>
  59. /// <param name="goods"></param>
  60. public MakeCloseViewModel(HoldingSummary holdingSummary, QuoteGoods goods)
  61. : base(holdingSummary, goods)
  62. {
  63. IsBidMarket = false;
  64. this._holdingSummary = holdingSummary;
  65. CurrentOrderType = OrderType.MarketCloseOrder;
  66. SetQuotePrice();
  67. }
  68. /// <summary>
  69. /// 按商品平仓
  70. /// </summary>
  71. /// <param name="goods"></param>
  72. public MakeCloseViewModel(QuoteGoods goods, List<HoldingSummary> holdingSummaries, bool isDirection)
  73. : base(goods)
  74. {
  75. CurrentOrderType = OrderType.MarketCloseOrder;
  76. IsDirectionEnable = isDirection;
  77. _holdingSummaries = holdingSummaries;
  78. var holdingSummary = holdingSummaries.FirstOrDefault();
  79. if (holdingSummary != null)
  80. {
  81. IsBidDirection = holdingSummary.Direction == Direction.Ask;
  82. SetHoldingSummay(holdingSummary);
  83. IsAskDirection = !IsBidDirection;
  84. SetQuotePrice();
  85. }
  86. }
  87. private double _priceMinUnit;
  88. /// <summary>
  89. /// 可输入小数位数
  90. /// </summary>
  91. public double PriceMinUnit
  92. {
  93. get { return _priceMinUnit; }
  94. set { Set(() => PriceMinUnit, ref _priceMinUnit, value); }
  95. }
  96. #region 止盈止损
  97. private int _countRow = 8;
  98. /// <summary>
  99. /// 设置数量控件位置
  100. /// </summary>
  101. public int CountRow
  102. {
  103. get { return _countRow; }
  104. set { Set(() => CountRow, ref _countRow, value); }
  105. }
  106. private decimal _stopLoss;
  107. private decimal _stopProfit;
  108. /// <summary>
  109. /// StopLossChecked
  110. /// </summary>
  111. private bool _stopLossChecked;
  112. /// <summary>
  113. /// StopProfitChecked
  114. /// </summary>
  115. private bool _stopProfitChecked;
  116. /// <summary>
  117. /// 设置止损价
  118. /// </summary>
  119. public decimal StopLoss
  120. {
  121. get
  122. {
  123. return _stopLoss;
  124. }
  125. set
  126. {
  127. Set(() => StopLoss, ref _stopLoss, value);
  128. // RaisePropertyChanged(() => ProfitLossPipsVailed);
  129. }
  130. }
  131. /// <summary>
  132. /// 设置止盈价
  133. /// </summary>
  134. public decimal StopProfit
  135. {
  136. get
  137. {
  138. return _stopProfit;
  139. }
  140. set
  141. {
  142. Set(() => StopProfit, ref _stopProfit, value);
  143. // RaisePropertyChanged(() => ProfitLossPipsVailed);
  144. }
  145. }
  146. /// <summary>
  147. /// Sets and gets the StopLossChecked property.
  148. /// Changes to that property's value raise the PropertyChanged event.
  149. /// </summary>
  150. public bool StopLossChecked
  151. {
  152. get
  153. {
  154. return _stopLossChecked;
  155. }
  156. set
  157. {
  158. Set(() => StopLossChecked, ref _stopLossChecked, value);
  159. switch (this.OpenDirection)
  160. {
  161. case Direction.Ask:
  162. StopLoss = MaxLoss + (decimal)PriceMinUnit;
  163. break;
  164. case Direction.Bid:
  165. StopLoss = MaxLoss - (decimal)PriceMinUnit;
  166. break;
  167. }
  168. // StopLoss = _stopLossChecked ? QuotePrice : 0;
  169. // StopLoss = _stopLossChecked ? 0 : 0;
  170. SetUpdateProfitLossPrice();
  171. }
  172. }
  173. /// <summary>
  174. /// Sets and gets the StopProfitChecked property.
  175. /// Changes to that property's value raise the PropertyChanged event.
  176. /// </summary>
  177. public bool StopProfitChecked
  178. {
  179. get
  180. {
  181. return _stopProfitChecked;
  182. }
  183. set
  184. {
  185. Set(() => StopProfitChecked, ref _stopProfitChecked, value);
  186. switch (this.OpenDirection)
  187. {
  188. case Direction.Ask:
  189. StopProfit = MaxProfit - (decimal)PriceMinUnit;
  190. break;
  191. case Direction.Bid:
  192. StopProfit = MaxProfit + (decimal)PriceMinUnit;
  193. break;
  194. }
  195. //StopProfit = _stopProfitChecked ? QuotePrice : 0;
  196. // StopLoss = _stopLossChecked ? 0 : 0;
  197. SetUpdateProfitLossPrice();
  198. }
  199. }
  200. /// <summary>
  201. /// 设置最大止损价
  202. /// </summary>
  203. public decimal MaxLoss
  204. {
  205. get
  206. {
  207. if (this.HoldOrder == null)
  208. {
  209. return decimal.Zero;
  210. }
  211. if (CurrentGoods == null || CurrentGoods.GoodsParameters == null)
  212. {
  213. return decimal.Zero;
  214. }
  215. bool flag = CurrentGoods.GoodsParameters.HqExchFigures < 20 &&
  216. CurrentGoods.GoodsParameters.HqExchFigures > -20;
  217. if (this.HoldOrder.Direction == Direction.Bid)
  218. {
  219. //止损价 < 卖价 - (止损点差 * 最小变动单位)
  220. //||_orderQuoteGoods.GoodsParameters.GoodsStatus != GoodsStatusType.Open
  221. return (CurrentGoods.AskPrice -
  222. (flag
  223. ? CurrentGoods.GoodsParameters.LimitslSellptSub /
  224. (decimal)Math.Pow(10, CurrentGoods.GoodsParameters.HqExchFigures)
  225. : 0));
  226. }
  227. else
  228. {
  229. //止损价 > 买价 + (止损点差 * 最小变动单位)
  230. //||_orderQuoteGoods.GoodsParameters.GoodsStatus != GoodsStatusType.Open
  231. return (CurrentGoods.BidPrice +
  232. (flag
  233. ? CurrentGoods.GoodsParameters.LimitslBuyptSub /
  234. (decimal)Math.Pow(10, CurrentGoods.GoodsParameters.HqExchFigures)
  235. : 0));
  236. }
  237. }
  238. }
  239. /// <summary>
  240. /// 设置最大止盈价
  241. /// </summary>
  242. public decimal MaxProfit
  243. {
  244. get
  245. {
  246. if (this.HoldOrder == null)
  247. {
  248. return decimal.Zero;
  249. }
  250. if (CurrentGoods == null || CurrentGoods.GoodsParameters == null)
  251. {
  252. return decimal.Zero;
  253. }
  254. bool flag = CurrentGoods.GoodsParameters.HqExchFigures < 20 &&
  255. CurrentGoods.GoodsParameters.HqExchFigures > -20;
  256. if (this.HoldOrder.Direction == Direction.Bid)
  257. {
  258. //止盈价 > 买价 + (止盈点差 * 最小变动单位)
  259. // ||_orderQuoteGoods.GoodsParameters.GoodsStatus != GoodsStatusType.Open
  260. return CurrentGoods.BidPrice +
  261. (flag
  262. ? CurrentGoods.GoodsParameters.LimittpBuyptSub /
  263. (decimal)Math.Pow(10, CurrentGoods.GoodsParameters.HqExchFigures)
  264. : 0);
  265. }
  266. else
  267. {
  268. //止盈价 < 卖价 - (止盈点差 * 最小变动单位)
  269. //||_orderQuoteGoods.GoodsParameters.GoodsStatus != GoodsStatusType.Open
  270. return CurrentGoods.AskPrice - (flag
  271. ? CurrentGoods.GoodsParameters.LimittpSellptSub / (decimal)
  272. Math.Pow(10, CurrentGoods.GoodsParameters.HqExchFigures)
  273. : 0);
  274. }
  275. }
  276. }
  277. /// <summary>
  278. /// 止盈 格式化
  279. /// </summary>
  280. public string DisplayMaxProfit
  281. {
  282. get
  283. {
  284. return MaxProfit.ToString(DisplayFormat);
  285. }
  286. }
  287. /// <summary>
  288. /// 止损 格式化
  289. /// </summary>
  290. public string DisplayMaxLoss
  291. {
  292. get
  293. {
  294. return MaxLoss.ToString(DisplayFormat);
  295. }
  296. }
  297. /// <summary>
  298. /// 止盈跟据买卖设置符号方向
  299. /// </summary>
  300. public string ProfitChar
  301. {
  302. get
  303. {
  304. switch (this.OpenDirection)
  305. {
  306. case Direction.Ask:
  307. {
  308. //if(canProfitCharChange)
  309. //{
  310. // StopProfit = (decimal)(MaxProfit - (decimal)PriceMinUnit);
  311. //}
  312. //if(canLossCharChange)
  313. //{
  314. // StopLoss = (decimal)(MaxLoss + (decimal)PriceMinUnit);
  315. //}
  316. return "<";
  317. }
  318. case Direction.Bid:
  319. {
  320. //if(canProfitCharChange)
  321. //{
  322. // StopProfit = (decimal)(MaxProfit + (decimal)PriceMinUnit);
  323. //}
  324. //if(canLossCharChange)
  325. //{
  326. // StopLoss = (decimal)(MaxLoss - (decimal)PriceMinUnit);
  327. //}
  328. return ">";
  329. }
  330. default:
  331. {
  332. return string.Empty;
  333. }
  334. }
  335. }
  336. }
  337. /// <summary>
  338. /// 止损跟据买卖设置符号方向
  339. /// </summary>
  340. public string LossChar
  341. {
  342. get
  343. {
  344. switch (OpenDirection)
  345. {
  346. case Direction.Ask:
  347. {
  348. return ">";
  349. }
  350. case Direction.Bid:
  351. {
  352. return "<";
  353. }
  354. default:
  355. {
  356. return string.Empty;
  357. }
  358. }
  359. }
  360. }
  361. /// <summary>
  362. /// 更新止盈止损
  363. /// </summary>
  364. private void SetUpdateProfitLossPrice()
  365. {
  366. if (CurrentOrderType == OrderType.LimitCloseOrder && CurrentGoods != null && CurrentGoods.GoodsParameters != null)
  367. {
  368. //if (OpenDirection == Direction.Bid)
  369. //{
  370. // MaxLimit = _currentGoods.GoodsParameters.LimitslBuyptSub + _currentGoods.AskPrice;
  371. // MinLimit = _currentGoods.AskPrice - _currentGoods.GoodsParameters.LimitslBuyptSub;
  372. //}
  373. //else
  374. //{
  375. // MaxLimit = _currentGoods.GoodsParameters.LimitslSellptSub + _currentGoods.BidPrice;
  376. // MinLimit = _currentGoods.BidPrice - _currentGoods.GoodsParameters.LimitslSellptSub;
  377. //}
  378. RaisePropertyChanged(() => DisplayMaxProfit);
  379. RaisePropertyChanged(() => DisplayMaxLoss);
  380. }
  381. }
  382. /// <summary>
  383. ///
  384. /// </summary>
  385. private void SetQuotePrice()
  386. {
  387. QuotePrice = (IsBidDirection ? CurrentGoods.BidPrice : CurrentGoods.AskPrice);
  388. //todo:暂时设置默认值
  389. ////注册实时行情消息
  390. ApplicationParameter.QuotationMessenger.Register<List<QuoteGoods>>(this, MessengerTokens.ReceiveRealTimeQuote, (quoteList) =>
  391. {
  392. if (CurrentGoods != null)
  393. {
  394. QuotePrice = (IsBidDirection ? CurrentGoods.BidPrice : CurrentGoods.AskPrice);
  395. }
  396. });
  397. }
  398. #endregion
  399. #region 虚函数
  400. public override NewEntrustOrder BuildEntrustOrder()
  401. {
  402. var entrustOrder = base.BuildEntrustOrder();
  403. entrustOrder.EntrustPrice = (CurrentOrderType == OrderType.LimitCloseOrder) ? ExecutePrice : QuotePrice;
  404. entrustOrder.PriceMode = OrderPriceMode.MarketPrice;
  405. if (CurrentOrderType == OrderType.LimitCloseOrder)
  406. {
  407. entrustOrder.PriceMode = OrderPriceMode.LimitPrice;
  408. entrustOrder.SLPrice = StopLossChecked ? this.StopLoss : 0;
  409. entrustOrder.SPPrice = StopProfitChecked ? this.StopProfit : 0;
  410. entrustOrder.ValidType = CurrentExpirationType;
  411. if (this.HoldOrder != null && this.HoldOrder.RelateOrderID > 0) //修改止盈止损
  412. {
  413. // entrustOrder.OrderType = OrderType.AlterProtfitLoss;
  414. entrustOrder.RelationTicket = HoldOrder.RelateOrderID;
  415. }
  416. else
  417. {
  418. entrustOrder.RelationTicket = HoldOrder.OrderID;
  419. }
  420. }
  421. ////if (this._openOrder != null && CurrentOrderType == OrderType.MarketCloseOrder)
  422. ////{
  423. ////}
  424. if ((CurrentOrderType == OrderType.MarketCloseOrder) && IsAllowPips)
  425. {
  426. entrustOrder.AllowTradeSub = (int)Pips;
  427. }
  428. //var goodsPips = UserManager.GetTraderGoodsPips(
  429. // UserManager.CurrentTradeAccount.TradeCode,
  430. // CurrentGoods.GoodsCode);
  431. if (this.HoldOrder != null)
  432. {
  433. entrustOrder.SpecialAccount = HoldOrder.SettlementMember;
  434. }
  435. else if (UserManager.CurrentTradeAccount.AccountType == eAccountType.ACCOUNTTYPE_TRADER)
  436. {
  437. //会员交易员按商品平仓时,委托服务需校验特别会员账号,与委托服务确认客户端传任意一特别会员账号,服务端不使用这个账号
  438. var holdingDetials = UserManager.CacheOpenOrders(UserManager.CurrentTradeAccount);
  439. var holdingDetial = holdingDetials.FirstOrDefault(
  440. (holder) => holder.GoodsCode == CurrentGoods.GoodsCode && holder.Direction == OpenDirection);
  441. if (holdingDetial != null)
  442. {
  443. entrustOrder.SpecialAccount = holdingDetial.SettlementMember;
  444. }
  445. }
  446. if (OpenDirection == Direction.Ask)
  447. {
  448. entrustOrder.BuyOrSell = Direction.Bid;
  449. ////委托单点差=商品点差+商品增量点差
  450. //entrustOrder.PtSub = goodsPips.BidPips + CurrentGoods.GoodsParameters.BuyptSub;
  451. entrustOrder.CurtQuotePrice = CurrentGoods.BidPrice;
  452. }
  453. else
  454. {
  455. entrustOrder.BuyOrSell = Direction.Ask;
  456. // entrustOrder.PtSub = goodsPips.AskPips + CurrentGoods.GoodsParameters.SellptSub; //委托单点差=商品点差+商品增量点差
  457. entrustOrder.CurtQuotePrice = CurrentGoods.AskPrice;
  458. }
  459. return entrustOrder;
  460. }
  461. public override void PostOrder(Action<OrderDetail> successAction, Action<Data.ErrorEntity> errorAction)
  462. {
  463. var entrustOrder = BuildEntrustOrder();
  464. var orderService = SimpleIoc.Default.GetInstance<IOrderService>();
  465. orderService.MakeMarketEntrustOrder(entrustOrder, successAction, errorAction);
  466. }
  467. #endregion
  468. }
  469. }