using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using Muchinfo.MTPClient.Data;
using Muchinfo.MTPClient.Data.DTO;
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.Linq;
//----------------------------------------------------------------
//Module Name: $safeprojectname$
//Purpose:
//CopyRight: Muchinfo
//History:
//----------------------------------------------------------------
//DateTime 2016/2/2 16:45:23
//Author
//Description Create
//----------------------------------------------------------------
using System.Timers;
using System.Windows;
namespace Muchinfo.MTPClient.Trade.ViewModels
{
public class QuickOrderViewModel : ViewModelBase
{
private QuoteGoods _currentGoods;
private IGoodsService _igoodsService;
///
/// 当前商品
///
public QuoteGoods CurrentGoods
{
get { return _currentGoods; }
set
{
Set(() => CurrentGoods, ref _currentGoods, value);
}
}
public QuickOrderViewModel()
{
////todo:注册改变当前商品消息
MessengerHelper.DefaultRegister(this, MessengerTokens.SelectGoodsChange, SelectGoodsChange);
MessengerHelper.DefaultRegister(this, MessengerTokens.QuickSell, QuickSellCommand);
MessengerHelper.DefaultRegister(this, MessengerTokens.QuickBuy, QuickBuyCommand);
_igoodsService = SimpleIoc.Default.GetInstance();
}
private const decimal c_LotBit = 0.01m; //数量的小数位数
///
/// 正在加载中
///
private bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
Set(() => IsBusy, ref _isBusy, value);
}
}
private bool _canOpenMarket;
public bool CanOpenMarket
{
get
{
return _canOpenMarket;
}
set
{
Set(() => CanOpenMarket, ref _canOpenMarket, value);
}
}
private decimal _lot;
///
/// 建仓手数
///
public decimal Lot
{
get { return _lot; }
set
{
Set(() => Lot, ref _lot, value);
RaisePropertyChanged(() => ShowMessage);
}
}
public string ShowMessage
{
get
{
var returnString = "";
if (Lot % c_LotBit != 0)
returnString = Client_Resource.Trade_OnlyTwoDecimalPlaces;
if (this._currentGoods != null)
{
var minLots = _igoodsService.GetGoodsParamerRule((int)_currentGoods.GoodsId,
_currentGoods.TradeMode, GoodsTradeConts.MINOPENTRADEQTY);
var maxLots = _igoodsService.GetGoodsParamerRule((int)_currentGoods.GoodsId,
_currentGoods.TradeMode, GoodsTradeConts.MAXOPENTRADEQTY);
if (minLots != null && Lot < minLots.FeeValue)
{
returnString = string.Format(Client_Resource.Lot_Open_UpOfMinOpenLot,
minLots.FeeValue);
}
else if (maxLots != null && Lot > maxLots.FeeValue)
{
returnString = string.Format(Client_Resource.Lot_Open_DownOfMaxOpenLot,
maxLots.FeeValue);
}
else if (minLots != null && minLots.FeeValue != 0 && Lot % minLots.FeeValue != 0)
{
returnString = string.Format(Client_Resource.Trade_LotCountIncorrect, minLots.FeeValue);
}
}
else
{
returnString = Client_Resource.Select_Goods_Error;
}
if (Lot <= 0)
{
returnString = Client_Resource.Lot_Vailed_MustUpOfZero;
}
return returnString;
}
}
private Visibility _market_AllownPubsVisiable = Visibility.Collapsed;
public Visibility Market_AllownPubsVisiable
{
get
{
return _market_AllownPubsVisiable;
}
set
{
Set(() => Market_AllownPubsVisiable, ref _market_AllownPubsVisiable, value);
}
}
private decimal _maxLost;
///
/// 单笔建仓最大数量
///
public decimal MaxLot
{
get { return _maxLost; }
set { Set(() => MaxLot, ref _maxLost, value); }
}
///
/// 市价建买
///
public RelayCommand BuyCommand
{
get
{
return new RelayCommand(() =>
{
QuickBuy();
});
}
}
///
/// 市价建卖
///
public RelayCommand SellCommand
{
get
{
return new RelayCommand(QuickSell);
}
}
///
/// 快捷卖单消息
///
/// The goods.
private void QuickSellCommand(QuoteGoodsDTO goods)
{
//改变当前商品
SelectGoodsChange(goods);
//改变数量
Lot = goods.Lot;
//内部卖逻辑
QuickSell();
}
///
/// 快捷下买单消息
///
/// The goods.
private void QuickBuyCommand(QuoteGoodsDTO goods)
{
//改变当前商品
SelectGoodsChange(goods);
//改变数量
Lot = goods.Lot;
//内部买逻辑
QuickBuy();
}
///
/// 选择商品改变
///
/// The goods.
private void SelectGoodsChange(QuoteGoodsDTO goods)
{
var quoteGoods = CacheManager.CacheGoodsBaseInfos.FirstOrDefault((item) => item.Symbol == goods.Symbol);
CurrentGoods = quoteGoods;
if (goods != null)
{
//todo:赋值MaxLot
//MaxLot = goods.GoodsParameters.MaxOpenNumber;
Lot = goods.Lot;
}
CanOpenMarket = true;
}
///
/// 内部卖逻辑
///
private void QuickSell()
{
// OpenCloseMode = OpenCloseMode.BUILDTYPE_CLOSE;
CanOpenMarket = false;
string errorMsg = "";
if (VailedFormData(out errorMsg, Direction.Ask))
{
string preViewMessage = Client_Resource.Warning_Order_confirm + Environment.NewLine + "\r\n";
//if (_currentGoods.GoodsParameters.TradeMode != eTradeMode.TRADEMODE_MARKETMAKE)
//{
// preViewMessage = @"您确认要限价下单吗?" + Environment.NewLine + "\r\n";
//}
preViewMessage += Client_Resource.QuickOrderViewModel_Goods + _currentGoods.GoodsParameters.GoodsName + Environment.NewLine;
preViewMessage += Client_Resource.QuickOrderViewModel_Direction + Client_Resource.Content_SellOut + Environment.NewLine;
if (_currentGoods.TradeMode == eTradeMode.TRADEMODE_MARKETMAKE)
{
preViewMessage += Client_Resource.QuickOrderViewModel_Price + _currentGoods.AskPrice + Environment.NewLine;
}
//else
//{
// var currentPrice = decimal.Zero;
// //竞价、混合=》默认限价下单【取值:最新价OR昨结算价】20160725-Idea from qiang
// if (_currentGoods.CurrentPrice != decimal.Zero)
// {
// currentPrice = _currentGoods.CurrentPrice;
// }
// else
// {
// currentPrice = _currentGoods.LastSettlement;
// }
// preViewMessage += "价 格:" + currentPrice + Environment.NewLine;
//}
preViewMessage += Client_Resource.QuickOrderViewModel_Qty + Lot + Environment.NewLine;
if (MessageBoxHelper.ShowQuestion(preViewMessage, Client_Resource.APP_Tips) == MessageBoxResult.Yes)
//if (MessageBoxHelper.ShowQuestion(Client_Resource.Warning_Order_confirm, Client_Resource.APP_Tips) == MessageBoxResult.Yes)
{
try
{
InitTimer();
PostOrder(Direction.Ask);
CanOpenMarket = true;
}
finally
{
CanOpenMarket = true;
DisposeTimer();
}
}
else
{
CanOpenMarket = true;
}
}
else
{
MessageBoxHelper.ShowInfo(errorMsg, Client_Resource.MessageBox_Error_Title);
CanOpenMarket = true;
}
}
///
/// 内部买逻辑
///
private void QuickBuy()
{
CanOpenMarket = false;
string errorMsg = "";
if (VailedFormData(out errorMsg, Direction.Bid))
{
string preViewMessage = Client_Resource.WarningOpen + Environment.NewLine + "\r\n";
//if (_currentGoods.GoodsParameters.TradeMode != eTradeMode.TRADEMODE_MARKETMAKE)
//{
// preViewMessage = @"您确认要限价{0}建仓吗?" + Environment.NewLine + "\r\n";
//}
preViewMessage += Client_Resource.QuickOrderViewModel_Goods + _currentGoods.GoodsParameters.GoodsName + Environment.NewLine;
preViewMessage += Client_Resource.QuickOrderViewModel_Direction + Client_Resource.Content_Purchase + Environment.NewLine;
if (_currentGoods.TradeMode == eTradeMode.TRADEMODE_MARKETMAKE)
{
preViewMessage += Client_Resource.QuickOrderViewModel_Price + _currentGoods.BidPrice + Environment.NewLine;
}
//else
//{
// var currentPrice = decimal.Zero;
// //竞价、混合=》默认限价下单【取值:最新价OR昨结算价】20160725-Idea from qiang
// if (_currentGoods.CurrentPrice!=decimal.Zero)
// {
// currentPrice = _currentGoods.CurrentPrice;
// }
// else
// {
// currentPrice = _currentGoods.LastSettlement;
// }
// preViewMessage += "价 格:" + currentPrice + Environment.NewLine;
//}
preViewMessage += Client_Resource.QuickOrderViewModel_Qty + Lot + Environment.NewLine;
//if (MessageBoxHelper.ShowQuestion(string.Format(Client_Resource.WarningOpen, Client_Resource.Content_Purchase), Client_Resource.WarningOpenPrompt) == MessageBoxResult.Yes)
if (MessageBoxHelper.ShowQuestion(string.Format(preViewMessage, Client_Resource.Content_Purchase), Client_Resource.WarningOpenPrompt) == MessageBoxResult.Yes)
{
try
{
InitTimer();
PostOrder(Direction.Bid);
}
finally
{
CanOpenMarket = true;
DisposeTimer();
}
}
else
{
CanOpenMarket = true;
}
}
else
{
MessageBoxHelper.ShowInfo(errorMsg, Client_Resource.MessageBox_Error_Title);
CanOpenMarket = true;
}
}
///
/// 验证表单数据是否正确
///
///
///
private bool VailedFormData(out string errorMsg, Direction direction)
{
if (CurrentGoods == null ||string.IsNullOrWhiteSpace((_currentGoods.Name)))
{
errorMsg = Client_Resource.Select_Goods_Error; ;
return false;
}
if ((CurrentGoods.ContainsGoodsSrc & (int)GoodsFromScr.Trade) != (int)GoodsFromScr.Trade) ////浏览的商品
{
errorMsg = string.Format(Client_Resource.Goods_WithOutTrade_Power, CurrentGoods.Name);
return false;
}
#region MyRegion
if (Lot % c_LotBit != 0)
{
errorMsg = Client_Resource.Trade_OnlyTwoDecimalPlaces;
return false;
}
if (this._currentGoods != null)
{
var minLots = _igoodsService.GetGoodsParamerRule((int)_currentGoods.GoodsId,
_currentGoods.TradeMode, GoodsTradeConts.MINOPENTRADEQTY);
var maxLots = _igoodsService.GetGoodsParamerRule((int)_currentGoods.GoodsId,
_currentGoods.TradeMode, GoodsTradeConts.MAXOPENTRADEQTY);
if (_currentGoods.GoodsParameters.MoneyMode == eMoneyMode.MONEYMODE_PAY && direction == Direction.Ask)
{
#region //全额商品区分买入卖出方向
var holdingOrders = UserManager.GetCacheOrders();
if (holdingOrders == null || !holdingOrders.Any())
{
errorMsg = Client_Resource.Quick_OrderHasNoHolds;
return false;
}
var holds = holdingOrders.Where((item) => item.GoodsId == CurrentGoods.GoodsParameters.GoodsId && item.Direction == Direction.Bid).ToList();
if (holds == null || !holds.Any())
{
errorMsg = Client_Resource.Quick_OrderHasNoHolds;
return false;
}
else
{
//最大数量=持仓汇总-冻结寸头
var tempMaxLot = (int)(holds.Sum((item) => item.Lot-item.LockQty) - holds.FirstOrDefault().PositionFzQty);
//全额商品-下单数量是否大于持仓数量
if (Lot > tempMaxLot)
{
errorMsg =string.Format( Client_Resource.Lot_Close_DownOfMaxOpenLot,tempMaxLot);
return false;
}
}
#endregion
}
else
{
#region //非全额商品 买入卖出都只有建仓模式
if (minLots != null && Lot < minLots.FeeValue)
{
errorMsg = string.Format(Client_Resource.Lot_Open_UpOfMinOpenLot,
minLots.FeeValue);
return false;
}
else if (maxLots != null && Lot > maxLots.FeeValue)
{
errorMsg = string.Format(Client_Resource.Lot_Open_DownOfMaxOpenLot,
maxLots.FeeValue);
return false;
}
#endregion
}
if (minLots != null && minLots.FeeValue != 0 && Lot % minLots.FeeValue != 0)
{
errorMsg = string.Format(Client_Resource.Trade_LotCountIncorrect, minLots.FeeValue);
return false;
}
}
else
{
errorMsg = Client_Resource.Select_Goods_Error;
return false;
}
if (Lot <= 0)
{
errorMsg = Client_Resource.Lot_Vailed_MustUpOfZero;
return false;
}
#endregion
errorMsg = string.Empty;
return true;
}
///
/// 发送下单消息
///
/// 返回下单错误码
private void PostOrder(Direction direction)
{
var entrustOrder = new NewEntrustOrder()
{
GoodsId = (uint)this._currentGoods.GoodsParameters.GoodsId,
AccountType = UserManager.CurrentTradeAccount.AccountType,
BuyOrSell = direction,
EntrustQuantity = Lot,
OperaterId = UserManager.CurrentTradeAccount.AccountId,
BuildType = OpenCloseMode.BUILDTYPE_OPEN,
EntrurstTime = ApplicationParameter.ServerTimeNow,
PriceMode = ePriceMode.PRICEMODE_MARKET,
CurrentGoods = this.CurrentGoods,
GoodsCode = this.CurrentGoods.GoodsCode,
MemberAreaId = UserManager.CurrentTradeAccount.MemberAreaId,
ValidType = ExpirationType.Today,
MarketId = this.CurrentGoods.MarketID,
TradeMode = CurrentGoods.TradeMode,
LoginID = UserManager.CurrentTradeAccount.AccountId,
AccountId = UserManager.CurrentTradeAccount.FundsAccountId,
OrderFlag = (uint)OrderMethods.NormalOrder,
OrderFormType = eOrderFormType.Commom,
};
var allowPips = _igoodsService.GetGoodsParamerRule((int)_currentGoods.GoodsId,
_currentGoods.TradeMode, GoodsTradeConts.AllowPips);
if (_currentGoods.GoodsParameters.MoneyMode == eMoneyMode.MONEYMODE_PAY && direction == Direction.Ask)
{
entrustOrder.BuildType = OpenCloseMode.BUILDTYPE_CLOSE;
}
//Edit by DK 20160725 //竞价、混合=》默认限价下单【取值:最新价OR昨结算价】-Idea from qiang
//if (_currentGoods.GoodsParameters.TradeMode != eTradeMode.TRADEMODE_MARKETMAKE)
//{
// entrustOrder.PriceMode = ePriceMode.PRICEMODE_LIMIT;
// if (_currentGoods.CurrentPrice != decimal.Zero)
// {
// entrustOrder.EntrustPrice = _currentGoods.CurrentPrice;
// }
// else
// {
// entrustOrder.EntrustPrice = _currentGoods.LastSettlement;
// }
//}
//todo:默认点差
entrustOrder.AllowTradeSub = allowPips == null ? 0 : allowPips.FeeValue;//ApplicationParameter.AllowTradeSub; //点差只能设置整数
var orderService = SimpleIoc.Default.GetInstance();
//if (UserManager.CurrentTradeAccount.FundsAccounts.Any() &&
// UserManager.CurrentTradeAccount.FundsAccounts[0] != null)
//{
// entrustOrder.AccountId = UserManager.CurrentTradeAccount.FundsAccounts[0].AccountId;
//}
//else
//{
// entrustOrder.AccountId = UserManager.CurrentTradeAccount.AccountId;
//}
if (_currentGoods.GoodsParameters == null)
{
MessageBoxHelper.ShowInfo(Client_Resource.APP_Tips, Client_Resource.QuickOrder_ParamersError);
}
else
{
switch (_currentGoods.TradeMode)
{
case eTradeMode.TRADEMODE_MARKETMAKE:
entrustOrder.EntrustPrice = direction == Direction.Bid
? _currentGoods.BidPrice
: _currentGoods.AskPrice;
entrustOrder.OrderMode = OrderMode.InValid;
entrustOrder.CurtQuotePrice = entrustOrder.EntrustPrice;
orderService.MakeMarketEntrustOrder(entrustOrder, EntrurstSuccessCallBack, EntrurstErrorCallBack);
break;
case eTradeMode.TRADEMODE_BIDDING:
entrustOrder.EntrustPrice = 0;
entrustOrder.OrderMode = OrderMode.STD;
entrustOrder.CurtQuotePrice = entrustOrder.EntrustPrice;
// entrustOrder.TradeCloseMode = TradeCloseMode.IsVailed;
orderService.BidMarketEntrustOrder(entrustOrder, EntrurstSuccessCallBack, EntrurstErrorCallBack);
break;
case eTradeMode.TRADEMODE_BIDDINGMARKETMAKE:
entrustOrder.EntrustPrice = 0;
entrustOrder.OrderMode = OrderMode.InValid;
entrustOrder.CurtQuotePrice = entrustOrder.EntrustPrice;
// entrustOrder.TradeCloseMode = TradeCloseMode.IsVailed;
orderService.MixMarketEntrustOrder(entrustOrder, EntrurstSuccessCallBack, EntrurstErrorCallBack);
break;
case eTradeMode.TRADEMODE_ENTRUST_HEDGE:
entrustOrder.CurtQuotePrice = direction == Direction.Ask ? _currentGoods.BidPrice : _currentGoods.AskPrice;
entrustOrder.ChannelPriceMode = ChannelPriceMode.MarketPrice;
orderService.ChannelEntrustOrder(entrustOrder, EntrurstSuccessCallBack, EntrurstErrorCallBack);
break;
default:
var message = string.Format(Client_Resource.QuickOrder_TradeModeError, _currentGoods.TradeMode);
MessageBoxHelper.ShowInfo(Client_Resource.APP_Tips, message);
break;
}
}
}
///
/// 提交成功返回
///
///
private void EntrurstSuccessCallBack(OrderDetail order)
{
//更新相应的单据
MessengerHelper.DefaultSend(UserManager.CurrentTradeAccount, MessengerTokens.OrderNoticeToken);
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
MessageBoxHelper.ShowSuccess(Client_Resource.Order_Success_Result,
Client_Resource.Open_MessageBox_Title);
IsBusy = false;
}));
}
///
/// 委托失败返回
///
///
private void EntrurstErrorCallBack(ErrorEntity errorEntity)
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
ErrorManager.ShowReturnError(errorEntity, Client_Resource.UI2014_Tips, true);
IsBusy = false;
}));
}
#region 设置下单倒数定时器
private string _busyTips;
///
/// 服务忙提示
///
public string BusyTips
{
get
{
return _busyTips;
}
set
{
Set(() => BusyTips, ref _busyTips, value);
}
}
private Timer _timer; //下单计时
private int _countTime; //倒计时时间
private bool _isOrderVisible = false;
///
/// 是否显示快速下单
///
public bool IsOrderVisible
{
get { return _isOrderVisible; }
set { Set(() => IsOrderVisible, ref _isOrderVisible, value); }
}
///
/// 初始化下单计时时间
///
private void InitTimer()
{
_countTime = ApplicationParameter.ServerTimeOut;
this._timer = new Timer(1000);
this._timer.AutoReset = true;
this._timer.Elapsed += _timer_Elapsed;
this._timer.Start();
IsOrderVisible = true;
BusyTips = string.Format(Client_Resource.Busy_Summit_Wait, _countTime);
}
///
///
///
///
///
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_countTime--;
BusyTips = string.Format(Client_Resource.Busy_Summit_Wait, _countTime);
}
///
/// 清除计时器
///
private void DisposeTimer()
{
this._timer.Stop();
this._timer.Elapsed -= _timer_Elapsed;
this._timer.Close();
IsOrderVisible = false;
}
#endregion
}
}