using System.Windows.Documents;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Muchinfo.MTPClient.Data;
using Muchinfo.MTPClient.Data.Enums;
using Muchinfo.MTPClient.Data.Model;
using Muchinfo.MTPClient.Data.Model.Account;
using Muchinfo.MTPClient.Infrastructure.Cache;
using Muchinfo.MTPClient.Infrastructure.Helpers;
using Muchinfo.MTPClient.Infrastructure.MessageBox;
using Muchinfo.MTPClient.Infrastructure.Utilities;
using Muchinfo.MTPClient.IService;
using Muchinfo.MTPClient.Resources;
using Muchinfo.WPF.Controls.Windows;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using System.Windows;
using Direction = Muchinfo.MTPClient.Data.Enums.Direction;
namespace Muchinfo.MTPClient.Account.ViewModels
{
public class AccountManagerViewModel : ViewModelBase
{
#region 字段
private const int c_Interval = 5000; //定时器取数据时间
private IOrderService _orderService;
private ILoginService _loginService;
private bool _isBusyFlag = false; //是否在取会员账号信息
private int _showDialogCount = 0; //连续超过多少次超时才弹出超时对话框计数器
private const int c_showdialog = 10; //计数常量
private IGoodsService _goodsService;
private ISystemService _systemService;
private static object _lockObj=new object();
private int interval; //定时器触发间隔
private Timer _memberTimer; //会员账号信息定时器
#endregion
private bool _isMemberTrade ;
///
/// 是否是要监控会员 交易员
///
public bool IsMemberTrade
{
get
{
return _isMemberTrade;
}
}
#region 构造函数
///
///
///
public AccountManagerViewModel()
{
_systemService = SimpleIoc.Default.GetInstance();
_goodsService = SimpleIoc.Default.GetInstance();
_orderService = SimpleIoc.Default.GetInstance();
_loginService = SimpleIoc.Default.GetInstance();
interval = ApplicationParameter.MemberMonitorTick <= 0
? c_Interval
: ApplicationParameter.MemberMonitorTick * 1000;
////注册消息
InitRegisterMsg();
InitUpdateTradeInfo();
}
///
/// 初始化注册消息
///
private void InitRegisterMsg()
{
MessengerHelper.DefaultRegister(this, MessengerTokens.MemberRolesToken, (val) =>
{
_isMemberTrade = val;
lock (_lockObj)
{
if (val)
{
SimpleIoc.Default.GetInstance().QueryMarketTypeStatus(MarketTypeStatusSuccess, null);
}
}
});
////交易端的信息是否要更新
MessengerHelper.DefaultRegister(this, MessengerTokens.MemberTraderUpdate, (val) =>
{
if (IsMemberTrade&&_memberTimer!=null)
{
if (!val)
{
////所有市场收市
_memberTimer.Stop();
}
else
{
if (!_memberTimer.Enabled)
{
_memberTimer.Start();
}
}
}
});
MessengerHelper.DefaultRegister(this, MessengerTokens.UpdateAccountCommand, CalcuatePLWithoutQuote);
MessengerHelper.DefaultRegister(this, MessengerTokens.HolderUpdate, (e) =>
{
InitUpdateTradeInfo();
});
// 委托单成交通知
//MessengerHelper.DefaultUnregister(this, MessengerTokens.ShowMOOrdersByCapitalAccount);
//MessengerHelper.DefaultRegister(this, MessengerTokens.ShowMOOrdersByCapitalAccount, (e) =>
//{
// InitUpdateTradeInfo();
//});
////注册实时行情消息
MessengerHelper.QuoteRegister>(this, MessengerTokens.ReceiveRealTimeQuote, (quoteList) =>
{
if (UserManager.CurrentTradeAccount == null) return;
if (quoteList == null || !quoteList.Any()) return;
foreach (var item in quoteList)
{
if (item == null) continue;
//更新盈亏
// var goodsPips = UserManager.GetTraderGoodsPips(UserManager.CurrentTradeAccount.TradeCode, item.GoodsCode);
UpdateFloatPL(item);
}
MessengerHelper.DefaultSend(UserManager.CurrentTradeAccount, MessengerTokens.UpdateAccountFloatPL);
});
//单据成交时需重新计算盈亏
MessengerHelper.DefaultRegister(this, MessengerTokens.OrderNotify, (e) =>
{
InitUpdateTradeInfo();
});
}
void MarketTypeStatusSuccess(List marketList)
{
if (marketList != null && marketList.Any())
{
foreach (var marketTypeProperty in marketList)
{
if (CacheManager.MarketStatus.ContainsKey(marketTypeProperty.markettypeid))
{
CacheManager.MarketStatus[marketTypeProperty.markettypeid] = marketTypeProperty.Inreckon;
}
}
if (_memberTimer == null)
{
_memberTimer = new Timer();
_memberTimer.Interval = interval;
_memberTimer.Elapsed += _memberTimer_Elapsed;
}
var allMarketType = CacheManager.MarketStatus.Values.Any((status) => status == (int)MarketStatus.MarketOpen);
if (allMarketType)
{
if (!_memberTimer.Enabled)
{
_memberTimer.Start();
}
}
}
}
void _memberTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (IsMemberTrade)
{
if (!_isBusyFlag)
{
_isBusyFlag = true;
////_orderService.GetMemberAmountPosition(UserManager.CurrentTradeAccount);
//if (UserManager.CurrentTradeAccount != null && UserManager.CurrentTradeAccount.FundsAccounts.Any())
//{
// _orderService.QueryMemberMonitor(UserManager.CurrentTradeAccount.FundsAccounts[0].AccountId, QuerySuccess, QueryErrorFunc);
//}
//else
//{
// LogInfoHelper.WriteInfo("请求会员监控信息:会员资金账号不存在 ");
//}
}
}
else
{
_memberTimer.Stop();
}
}
public void QuerySuccess(List successAction)
{
_isBusyFlag = false;
_memberTimer.Interval = interval;
_showDialogCount = 0; //收到回应时重置
if (successAction != null && successAction.Count > 0)
{
UserManager.CurrentTradeAccount.MemberPositions = successAction[0].MemberPositions;
if ((AccountStatus)successAction[0].AccountStatus != AccountStatus.None) ////从风控显示数据
{
var funds = UserManager.CurrentTradeAccount.FundsAccounts[0];
successAction[0].Balance = funds.Balance;
UserManager.CurrentTradeAccount.MemberAccountInfo = successAction[0];
MessengerHelper.DefaultSend(successAction, MessengerTokens.MemberAccountUpdate);
}
else
{
////从数据库中显示资金信息
if (UserManager.CurrentTradeAccount.FundsAccounts != null &&
UserManager.CurrentTradeAccount.FundsAccounts.Any())
{
var funds = UserManager.CurrentTradeAccount.FundsAccounts[0];
var memberInfo = new MemberAccountInfo();
memberInfo.UsedMargin = funds.UsedMargin ;
memberInfo.FloatPL = funds.FloatPL ;
memberInfo.NetWorth = funds.CurrentNetWorth ;
memberInfo.AvailMargin = funds.AvailMargin;
memberInfo.MemberPositions = successAction[0].MemberPositions;
memberInfo.Balance = funds.Balance ;
memberInfo.Rate = funds.RiskRatio;
memberInfo.AccountStatus = UserManager.CurrentTradeAccount.AccountStatus;//账户状态
UserManager.CurrentTradeAccount.MemberAccountInfo = memberInfo;
memberInfo.MemberPositions = successAction[0].MemberPositions;
MessengerHelper.DefaultSend(new List() { memberInfo }, MessengerTokens.MemberAccountUpdate);
}
}
}
}
private void QueryErrorFunc(ErrorEntity error)
{
_isBusyFlag = false;
_memberTimer.Interval = interval;
LogInfoHelper.WriteInfo(string.Format("请求会员风控信息错误({0}){1}", error.ReturnCode, error.ReturnDesc));
//Application.Current.Dispatcher.BeginInvoke(new Action(() =>
//{
// ErrorManager.ShowReturnError(error, Client_Resource.UI2014_Tips, true);
//}));
}
///
/// 初始化交易数据
///
private void InitUpdateTradeInfo()
{
var queryCommonParams = new List();
var accountid = UserManager.CurrentTradeAccount.LoginID;
//if (UserManager.CurrentTradeAccount.FundsAccounts!=null && UserManager.CurrentTradeAccount.FundsAccounts.Any())
//{
// accountid = UserManager.CurrentTradeAccount.FundsAccounts[0].AccountId;
//}
queryCommonParams.Add(new QueryCommonParam() { ParamKey = "accountId", ParamValue = accountid + string.Empty });
//初始化持仓单
_loginService.LoginQuerySearch(Convert.ToUInt64(UserManager.CurrentTradeAccount.LoginID), LoginQueryType.TAAccountList, QueryHoldOrderCallBack, null);
//_orderService.QueryHoldingDetails(QueryStatement.SearchMarketHoldOrder, queryCommonParams, QueryHoldOrderCallBack, null);
}
///
/// 查询持仓成功回调
///
/// 持仓内容
private void QueryHoldOrderCallBack(AccountBaseInfoModel holdOrders)
{
////获取当前的持仓
CalcuatePLWithoutQuote("");
//MessengerHelper.DefaultSend(UserManager.CurrentTradeAccount, MessengerTokens.HolderRefresh);
MessengerHelper.DefaultSend(UserManager.CurrentTradeAccount, MessengerTokens.UpdateAccountFloatPL);
}
#endregion
#region 方法
///
/// 没有行情时计算浮盈
///
private void CalcuatePLWithoutQuote(string msg)
{
var quoteGoodses = CacheManager.CacheGoodsBaseInfos.Where((item)=>item.GoodsId!=0); //_goodsService.GetGoodsInfoListByExchangeId(UserManager.CurrentTradeAccount.ExchangeId);
if (quoteGoodses != null && quoteGoodses.Any())
{
var dicGoods = quoteGoodses.ToDictionary((good) => good.GoodsId);
UpdateFloatPL(dicGoods);
}
}
/// s
/// 更新当前持仓商品的平仓价,浮动盈亏
///
/// 行情商品
private void UpdateFloatPL(Dictionary quoteGoodsDic)
{
// holdingReports = new ObservableCollection();
if (UserManager.CurrentTradeAccount == null)
{
return;
}
var holdingReports = UserManager.CacheOpenOrders(UserManager.CurrentTradeAccount);
if (holdingReports == null) return;
foreach (var openOrder in holdingReports)
{
if (openOrder.MarketType == eTradeMode.TRADEMODE_SALE) ////发售的市值
{
openOrder.CurrentAmount = openOrder.HoldAmount;
}
if (!quoteGoodsDic.ContainsKey(openOrder.GoodsId) )
{
continue;
}
var orderGoods = quoteGoodsDic[openOrder.GoodsId];
SetHorderClosePrice(openOrder,orderGoods);
////竞价盈亏
//openOrder.ClosePrice = openOrder.QuoteGoods.GoodsParameters.TradeMode == TradeModeType.BidGoods
// ? orderGoods.CurrentPrice
// : openOrder.ClosePrice;
openOrder.PLFloat = FloatPLExpressions.OrderDetailFloatPL(openOrder, orderGoods);
openOrder.CurrentAmount = FloatPLExpressions.CalcHoldAmount(openOrder, orderGoods);
//(openOrder.ClosePrice - openOrder.HoldingPrice) * openOrder.Lot * orderFlag
//* openOrder.QuoteGoods.GoodsParameters.AgreeUnit;
if (ApplicationParameter.IsShowSumPL == 1)
{
openOrder.SumFloatPL = FloatPLExpressions.CalcOrderDetailSumPL(openOrder);
}
}
if (UserManager.CurrentTradeAccount != null && UserManager.CurrentTradeAccount.FundsAccounts != null &&
UserManager.CurrentTradeAccount.FundsAccounts.Any())
{
decimal payPL, marginPL;
FloatPLExpressions.CalcFullPayPLWithSumPL(holdingReports, out payPL, out marginPL);
UserManager.CurrentTradeAccount.FundsAccounts[0].FloatPL = Math.Round(marginPL, 2);
UserManager.CurrentTradeAccount.FundsAccounts[0].PayNetWorth =
holdingReports.Sum((item) => item.CurrentAmount);
}
}
/// s
/// 更新当前持仓商品的平仓价,浮动盈亏
///
/// 行情商品
private void UpdateFloatPL(QuoteGoods quoteGoods)
{
LogInfoHelper.WriteInfo("更新当前持仓商品的平仓价,浮动盈亏" + quoteGoods.GoodsClassName + quoteGoods.GoodsCode + DateTime.Now.ToString());
if (UserManager.CurrentTradeAccount == null)
{
return;
}
var holdingReports = UserManager.CacheOpenOrders(UserManager.CurrentTradeAccount); ;
if (holdingReports != null)
{
var openOrders = holdingReports.Where((order) => order.GoodsId == quoteGoods.GoodsId);
foreach (var openOrder in openOrders)
{
SetHorderClosePrice(openOrder, quoteGoods);
////竞价盈亏
//openOrder.ClosePrice = openOrder.QuoteGoods.GoodsParameters.TradeMode == TradeModeType.BidGoods
// ? quoteGoods.CurrentPrice
// : openOrder.ClosePrice;
// }
//todo:可计算浮动盈亏
openOrder.PLFloat = FloatPLExpressions.OrderDetailFloatPL(openOrder, quoteGoods);
openOrder.CurrentAmount = FloatPLExpressions.CalcHoldAmount(openOrder, quoteGoods);
if (ApplicationParameter.IsShowSumPL==1)
{
openOrder.SumFloatPL = FloatPLExpressions.CalcOrderDetailSumPL(openOrder);
}
//(openOrder.ClosePrice - openOrder.HoldingPrice) * openOrder.Lot * orderFlag
//* openOrder.QuoteGoods.GoodsParameters.AgreeUnit;
}
if (UserManager.CurrentTradeAccount != null && UserManager.CurrentTradeAccount.FundsAccounts != null &&
UserManager.CurrentTradeAccount.FundsAccounts.Any())
{
decimal payPL, marginPL;
FloatPLExpressions.CalcFullPayPLWithSumPL(holdingReports, out payPL, out marginPL);
UserManager.CurrentTradeAccount.FundsAccounts[0].FloatPL = Math.Round(marginPL, 2);
UserManager.CurrentTradeAccount.FundsAccounts[0].FloatPL = Math.Round(marginPL, 2);
UserManager.CurrentTradeAccount.FundsAccounts[0].PayNetWorth =
holdingReports.Sum((item) => item.CurrentAmount);
}
}
}
///
/// 设置持仓的最新价()
///
/// 持仓单
/// 持仓商品
private void SetHorderClosePrice(HoldingOrder holdingOrder, QuoteGoods orderGoods)
{
if (orderGoods != null )
{
switch (orderGoods.TradeMode)
{
case eTradeMode.TRADEMODE_MARKETMAKE:
if (holdingOrder.Direction == Direction.Ask)
{
holdingOrder.ClosePrice = orderGoods.BidPrice;
holdingOrder.ContrayClosePrice = orderGoods.AskPrice;
}
else
{
holdingOrder.ClosePrice = orderGoods.AskPrice;
holdingOrder.ContrayClosePrice = orderGoods.BidPrice;
}
break;
case eTradeMode.TRADEMODE_BIDDING:
///竞价盈亏
holdingOrder.ClosePrice = orderGoods.CurrentPrice == 0 ? orderGoods.LastClose : orderGoods.CurrentPrice;
break;
case eTradeMode.TRADEMODE_SALE:
holdingOrder.ClosePrice = holdingOrder.HoldingPrice; ////发售用持仓价来算市值
break;
case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE:
///竞价盈亏
holdingOrder.ClosePrice = orderGoods.CurrentPrice == 0 ? orderGoods.LastClose : orderGoods.CurrentPrice;
break;
default:
break;
}
}
else
{
///竞价盈亏
holdingOrder.ClosePrice = orderGoods.CurrentPrice == 0 ? orderGoods.LastClose : orderGoods.CurrentPrice;
}
}
#endregion
///
/// Cleanups this instance.
///
public override void Cleanup()
{
////取消注册消息
base.Cleanup();
MessengerHelper.QuoteUnregister(this);
}
}
}