Files
zszq-trs/YLErpDAL/Modules/TradeModule/SwapModule/SwapTradeFlowImportService.cs
T

1454 lines
68 KiB
C#

using System.Data;
using System.Globalization;
using System.Text.RegularExpressions;
using YLErp.BLL;
using YLErp.Commons;
using YLErp.CustomizedBizLogic;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
using YLErp.DBModels.Helpers;
using YLErp.Enums;
using YLErp.Model.Enum;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.EodModule;
using YLErp.Modules.TradeModule.OrderModule;
namespace YLErp.Modules.TradeModule.SwapModule
{
/// <summary>
/// 场外期权交易导入服务
/// </summary>
public class SwapTradeFlowImportService : TradeServiceBase
{
public SwapTradeFlowImportService(OptUserInfo userInfo) : base(userInfo)
{
}
public SwapTradeFlowImportService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
/// 导入交易
/// </summary>
/// <param name="streamIn"></param>
/// <param name="totalNum">当前文件中的目标期权总条数</param>
/// <param name="successNum">成功入库的数量</param>
public void ImportSwapTradeFlowFromExcel(Stream streamIn, out int totalNum, out int successNum)
{
totalNum = 0;
successNum = 0;
var rowIndex = 0;
var tradeFlowIds = new List<int>();
try
{
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
var reader = new DataRowReader(table);
rowIndex = 1;
totalNum = table.Rows.Count - rowIndex;
using (var trans = BeginTransaction())
{
foreach (var row in table.Rows.Cast<DataRow>().Skip(1))
{
rowIndex++;
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
totalNum--;
continue;
}
reader.SetDataRow(row);
//映射导入数据到交易对象
var tradeFlow = MapSwapTradeFlow(reader);
tradeFlowIds.Add(tradeFlow.id);
HandleSwapTrade(tradeFlow);
tradeFlow.Status = "已完成";
DbContext.SaveChanges();
successNum++;
}
trans.Commit();
}
//generateSettleDocument(trade_Cashes);
//生成确认书
//new ConfirmationGenerateService(this).Generate(tradeIds, "PDF");
}
catch (ServiceException se)
{
if (se.Tag != null)
{
throw;
}
throw new ServiceException($"第{rowIndex}行,{se.Message}");
}
catch (Exception ex)
{
LogFactory.GetLogger("导入互换交易").Error(ex);
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
}
}
/// <summary>
/// 导入交易
/// </summary>
/// <param name="streamIn"></param>
/// <param name="totalNum">当前文件中的目标期权总条数</param>
/// <param name="successNum">成功入库的数量</param>
public void ImportSwapTradeFlowGroupFromExcel(Stream streamIn, out int totalNum, out int successNum)
{
totalNum = 0;
successNum = 0;
var rowIndex = 0;
try
{
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
var reader = new DataRowReader(table);
rowIndex = 1;
totalNum = table.Rows.Count - rowIndex;
using (var trans = BeginTransaction())
{
foreach (var row in table.Rows.Cast<DataRow>().Skip(1))
{
rowIndex++;
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
totalNum--;
continue;
}
reader.SetDataRow(row);
//映射导入数据到交易对象
MapSwapTradeFlowGroup(reader);
successNum++;
}
trans.Commit();
}
}
catch (ServiceException se)
{
if (se.Tag != null)
{
throw;
}
throw new ServiceException($"第{rowIndex}行,{se.Message}");
}
catch (Exception ex)
{
LogFactory.GetLogger("导入互换交易").Error(ex);
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
}
}
/// <summary>
/// 导入交易
/// </summary>
/// <param name="streamIn"></param>
/// <param name="totalNum">当前文件中的目标期权总条数</param>
/// <param name="successNum">成功入库的数量</param>
public void ImportTradeFlowHistoryFromExcel(Stream streamIn, out int totalNum, out int successNum)
{
totalNum = 0;
successNum = 0;
var rowIndex = 0;
try
{
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0);
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2)
{
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
}
var table = ds.Tables[0];
var reader = new DataRowReader(table);
rowIndex = 1;
totalNum = table.Rows.Count - rowIndex;
using (var trans = BeginTransaction())
{
foreach (var row in table.Rows.Cast<DataRow>().Skip(1))
{
rowIndex++;
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
{
totalNum--;
continue;
}
reader.SetDataRow(row);
var clientName = reader.GetString("客户名称");
var client = ClientModule.ClientDataQueryService.GetClient(clientName);
if (client == null)
{
throw new ServiceException($"客户{clientName}不存在");
}
var tradeFlowHistory = new trade_flow_history()
{
ClientId = client.id,
ContractId = reader.GetString("交易编码"),
FlagExpired = reader.GetString("是否到期"),
QuoteCurrency = reader.GetString("计价货币"),
SettleCurrency = reader.GetString("结算货币"),
TradeDate = reader.GetDate("交易日"),
ExpireDate = reader.GetDate("到期日"),
SettleDate = reader.GetDate("交割日(LME Prompt)"),
Direction = reader.GetString("客户买/卖"),
PremiumDate = reader.GetDate("权利金日"),
PremiumCNY = reader.GetDouble("期权费¥"),
TradeType = reader.GetString("衍生品类型"),
UnderlyingCode = reader.GetString("标的代码"),
InitialLots = reader.GetDouble("初始开仓手数"),
Lots = reader.GetDouble("剩余手数"),
Size = reader.GetDouble("合约乘数"),
InitialSpotPrice = reader.GetDouble("初始价格"),
InitialRate = reader.GetDouble("初始汇率"),
SpotPrice = reader.GetDouble("最新价格"),
Rate = reader.GetDouble("最新汇率"),
CommissionRate = reader.GetString("佣金费率"),
EstimateCommision = reader.GetDouble("预估佣金¥"),
AnnualRate = reader.GetPercent("年化手续费率"),//
EstimateAnnualFee = reader.GetDouble("预估年化手续费¥"),
FloatingWinLossQuote = reader.GetDouble("浮动收益(计价货币)"),
FloatingWinLoss = reader.GetDouble("浮动收益(结算货币)"),//
UnRealizedPnl = reader.GetDouble("未实现收益(结算货币)"),
RealizedPnl = reader.GetDouble("已实现收益(结算货币)"),
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now
};
checkFlowHis(tradeFlowHistory);
DbContext.trade_flow_history.Add(tradeFlowHistory);
DbContext.SaveChanges();
successNum++;
}
trans.Commit();
}
}
catch (ServiceException se)
{
if (se.Tag != null)
{
throw;
}
throw new ServiceException($"第{rowIndex}行,{se.Message}");
}
catch (Exception ex)
{
LogFactory.GetLogger("导入历史交易流水").Error(ex);
throw new ServiceException($"第{rowIndex}行,发生错误:{ex.Message}", ex);
}
}
public bool checkFlowHis(trade_flow_history req)
{
if (DbContext.trade_flow_history.Any(o => o.ContractId == req.ContractId))
{
throw new ServiceException($"历史交易已存在{req.ContractId}");
}
return true;
}
public void HandleSwapTrade(trade_swap_flow tradeFlow)
{
var importTrade = MapSwapTradeHandle(tradeFlow);
var tradeSwapPositionsOtherSide = (from td in DbContext.trade
join ts in DbContext.trade_swap
on td.id equals ts.TradeId
where td.ClientId == importTrade.ClientId && td.UnderlyingId == importTrade.UnderlyingId && td.TradeStatus == ConsTrade.确认成交 && td.ParentTradeId == 0 && td.ValidState != "InValid" && ts.SwapType != "多空组合" && ts.PayLongShort != importTrade.trade_swap.PayLongShort && td.TradeDate <= importTrade.TradeDate
select new { td, ts }).ToList().OrderBy(x => x.td.TradeDate);
if (tradeSwapPositionsOtherSide.Any())
{
//按时间顺序一次平仓
foreach (var item in tradeSwapPositionsOtherSide)
{
if (importTrade.Notional > 0)
{
item.td.trade_swap = item.ts;
UnwindSwapTrade(item.td, importTrade);
}
}
//如果存续反向交易均被平仓,新增交易还有剩余部分,需要重新开仓
if (importTrade.Notional > 0)
{
InnerSaveSwapTrade(importTrade);
}
}
else
{
//无反向存续交易,则直接开仓
InnerSaveSwapTrade(importTrade);
}
}
private void InnerSaveSwapTrade(trade importTrade)
{
var varitey = DataCacheProvider.GetVariety(importTrade.UnderlyingCode);
double marginRate = 0d;
if (PS.Config.Company == Configuration.CompanyEnum.中金)
{
var credit = DbContext.credit.FirstOrDefault(x => x.CreditStartDate <= importTrade.TradeDate && x.CreditDeadLine >= importTrade.TradeDate && x.ClientId == importTrade.ClientId && x.ProcessStatus == "已审批");
var hasCredit = credit != null && credit.PFECredit > 0;
var clientVarietyMarginRate = DbContext.client_variety_marginrate.Where(x => x.ClientId == importTrade.ClientId && x.VarietyId == varitey.id && x.ValueDate <= importTrade.TradeDate).OrderByDescending(x => x.ValueDate).FirstOrDefault();
if (clientVarietyMarginRate == null)
{
clientVarietyMarginRate = DbContext.client_variety_marginrate.Where(x => x.ClientId == 0 && x.VarietyId == varitey.id && x.ValueDate <= importTrade.TradeDate).OrderByDescending(x => x.ValueDate).FirstOrDefault();
}
if (clientVarietyMarginRate == null)
{
throw new ServiceException($"该客户[{importTrade.ClientName}]需要维护品种[{varitey.VarietyCode}]在[{importTrade.TradeDate}]相关的预付金率配置");
}
marginRate = hasCredit ? clientVarietyMarginRate.LowMarginRate : clientVarietyMarginRate.HighMarginRate;
}
else
{
var clientMarginRate = DbContext.client_marginrate.Where(x => x.ClientId == importTrade.ClientId && x.VarietyId == varitey.id && x.ValueDate <= importTrade.TradeDate).OrderByDescending(x => x.ValueDate).FirstOrDefault();
if (clientMarginRate == null)
{
clientMarginRate = DbContext.client_marginrate.Where(x => x.ClientId == 0 && x.VarietyId == varitey.id && x.ValueDate <= importTrade.TradeDate).OrderByDescending(x => x.ValueDate).FirstOrDefault();
}
if (clientMarginRate == null)
{
throw new ServiceException($"该客户[{importTrade.ClientName}]需要维护品种[{varitey.VarietyCode}]在[{importTrade.TradeDate}]相关的预付金率配置");
}
marginRate = clientMarginRate.InitMarginRate;
}
importTrade.TradeStatus = ConsTrade.确认成交;
importTrade.TradeNumber = BizLogicSingleton.Instance.GenerateTradeNumberBeforeConfirm(importTrade, DbContext);
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(importTrade.QuoteCurrency, importTrade.SettlementCurrency, importTrade.TradeDate.Value, seekPreday: importTrade.TradeDate.Value == valuedateBLL.ValueDate);
var tradePriceQuote = 0.0;
if (importTrade.trade_swap.IsTradePriceWhenOpen)
{
tradePriceQuote = ((importTrade.trade_swap.GetSingleFee ?? 0) * (importTrade.Lots ?? 0) + importTrade.StockEqvNotional * (importTrade.trade_swap.GetUnAnnualRate ?? 0)).FormatValue(2);
importTrade.TradePrice = (tradePriceQuote * currencyRate).FormatValue(2);
}
importTrade.InitialMargin = marginRate * importTrade.StockEqvNotional;
importTrade.OriginalNotional = importTrade.Notional;
importTrade.OriginalStockEqvNotional = importTrade.StockEqvNotional;
importTrade.StockEqvNotionalReal = importTrade.StockEqvNotionalReal;
importTrade.trade_swap.RateCalcMode = "01";
importTrade.IsUsePremiumRate = true;
importTrade.MarginTemplateName = null;
importTrade.MarginType = MarginTypeEnum.DEFAULT;
importTrade.IsTradePricePayType = true;
importTrade.TradeSource = TradeSourceEnum.导入交易.ToString();
importTrade.OptId = UserId;
importTrade.OptName = UserName;
importTrade.OptDate = DateTime.Now;
SetDBModelCreator(importTrade);
DbContext.trade.Add(importTrade);
DbContext.SaveChanges();
importTrade.trade_swap.GetTradePrice = (importTrade.trade_swap.GetSingleFee ?? 0) * (importTrade.Lots ?? 0) + (importTrade.trade_swap.GetUnAnnualRate ?? 0) * importTrade.StockEqvNotional;
importTrade.trade_swap.GetMarginRate = marginRate;
importTrade.trade_swap.TradeId = importTrade.id;
importTrade.trade_swap.PaySpotPrice = importTrade.SpotPrice;
importTrade.trade_swap.PayUnderlyingId = importTrade.UnderlyingId;
importTrade.trade_swap.PayUnderlyingCode = importTrade.UnderlyingCode;
importTrade.trade_swap.PayNotional = importTrade.Notional;
importTrade.trade_swap.PayTradeAmount = importTrade.TradeAmount;
importTrade.trade_swap.IsPayFloatingProfit = true;
importTrade.trade_swap.SwapType = "普通";
importTrade.trade_swap.OptId = UserId;
importTrade.trade_swap.OptName = UserName;
importTrade.trade_swap.OptDate = DateTime.Now;
DbContext.trade_swap.Add(importTrade.trade_swap);
SaveTradeMeta(importTrade);
var tc = new trade_cash
{
ValidState = "Valid"
};
DbContext.trade_cash.Add(tc);
tc.OptId = UserId;
tc.OptName = UserName;
tc.OptDate = DateTime.Now;
tc.Action = ClientCashInCashOut.系统操作_期权费;
tc.Amount = (importTrade.TradePrice ?? 0) * (importTrade.BuySell == "买入" ? -1 : 1);
tc.QuoteAmount = tradePriceQuote * (importTrade.BuySell == "买入" ? -1 : 1);
tc.CurrencyRate = currencyRate;
tc.ExceciseType = "现金";
tc.TradeId = importTrade.id;
tc.ValueDate = importTrade.TradeDate.Value;
tc.Notional = importTrade.Notional;
tc.TradeAmount = importTrade.TradeAmount;
tc.Status = TradeCashStatusEnum.已执行;
tc.TradeType = importTrade.BuySell;
DbContext.SaveChanges();
new ClientCashinCashoutBLL(this).CloseTrade_ClientCashInCashOutSave(importTrade, tc, tc.ValueDate);
var tcdGet = new trade_cash_detail
{
TradeId = tc.TradeId,
TradeCashId = tc.id,
Action = tc.Action,
Amount = tc.Amount,
QuoteAmount = tc.QuoteAmount,
TradeCashType = TradeCashTypeEnum.开仓手续费.ToString(),
ValueDate = tc.ValueDate,
IsForGet = true,
OptId = tc.OptId,
OptName = tc.OptName,
OptDate = DateTime.Now
};
DbContext.trade_cash_detail.Add(tcdGet);
DbContext.SaveChanges();
}
private void UnwindSwapTrade(trade tradePosition, trade tradeImport)
{
var unwindType = tradePosition.Notional > tradeImport.Notional ? "部分平仓" : "全部平仓";
if (tradePosition.trade_swap.SettlementPayType == 0)
{
UnwindSwapTradeCashHandle(tradePosition, tradeImport, unwindType);
}
else if (tradePosition.trade_swap.SettlementPayType == 1)
{
UnwindSwapTradeCashPreHandle(tradePosition, tradeImport, unwindType);
}
SaveTradeOperationHistory(tradePosition, "互换导入平仓");
//删除E/Bod数据
RemoveEodTradeAndFutureInfo(true, tradePosition.id, tradeImport.TradeDate.Value);
}
private void UnwindSwapTradeCashHandle(trade tradePosition, trade tradeImport, string unwindType)
{
var tradeCashs = DbContext.trade_cash.Where(x => x.TradeId == tradePosition.id && x.ValidState != "InValid");
var num = tradeCashs.Where(x => x.Action != ClientCashInCashOut.系统操作_期权费).Count() + 1;
var tradeCashList = tradeCashs.Where(y => y.Action == "系统操作-互换" && y.ValidState != "InValid" && !y.IsDeleted && y.ValueDate <= tradeImport.TradeDate.Value);
var tradeCashIds = tradeCashList.Select(x => x.id);
var client = DataCacheProvider.GetClientDataSource().GetData(tradePosition.ClientId);
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(tradePosition.QuoteCurrency, tradePosition.SettlementCurrency, tradeImport.TradeDate.Value, seekPreday: tradeImport.TradeDate.Value == valuedateBLL.ValueDate);
var currencyRateTradeDate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(tradePosition.QuoteCurrency, tradePosition.SettlementCurrency, tradePosition.TradeDate.Value, seekPreday: tradePosition.TradeDate.Value == valuedateBLL.ValueDate);
//增加现金交割交易记录
var tc = new trade_cash();
DbContext.trade_cash.Add(tc);
tc.OptId = UserId;
tc.OptName = UserName;
tc.OptDate = OptDate;
tc.ExceciseType = "现金";
tc.TradeType = tradePosition.BuySell;
tc.CallPut = tradePosition.CallPut;
tc.Notional = tradePosition.Notional;
tc.TradeAmount = tradePosition.TradeAmount;
tc.IsLastAction = unwindType == "全部平仓";
tc.TradeId = tradePosition.id;
tc.FinalPrice = tradeImport.SpotPrice;
tc.UnwindType = unwindType;
if (tc.UnwindType == "全部平仓")
{
tc.UnwindNotional = tradePosition.Notional;
tc.UnwindTradeAmount = tradePosition.TradeAmount;
tc.UnwindPercentRate = tradePosition.Notional / tradePosition.OriginalNotional;
}
else
{
tc.UnwindNotional = tradeImport.Notional;
tc.UnwindTradeAmount = tradeImport.TradeAmount;
tc.UnwindPercentRate = tradeImport.Notional / tradePosition.OriginalNotional;
}
tc.NotionalPercentRate = tc.UnwindPercentRate;
tradeBLL.SetFieldsByTradeType(tradePosition);
var initialAmountPayQuote = PayoffSwapCalcService.GetInitialAmountSwapPay(tradePosition, tradePosition.trade_swap, tradePosition.trade_swap.PaySpotPrice ?? 0
, tradeImport.SpotPrice ?? 0, (tradePosition.OriginalStockEqvNotional ?? 0) * (tc.UnwindPercentRate ?? 0), tradeImport.TradeDate.Value, null);
var initialAmountPay = (initialAmountPayQuote * currencyRate).FormatValue(2);
var cashSwaps = DbContext.trade_cash_swap.Where(x => x.TradeId == tradePosition.id && tradeCashIds.Contains(x.TradeCashId)).ToArray();
//取最后一次手动收益;
var lastManualCashSwap = cashSwaps.OrderByDescending(o => o.StartDate).FirstOrDefault(x => !x.IsAuto);
var lastManualCash = lastManualCashSwap != null ? tradeCashList.FirstOrDefault(x => x.id == lastManualCashSwap.TradeCashId) : null;
DateTime endDate;
var preSwapDate = PayoffSwapCalcService.GetSwapRateStartDate(tradePosition, tradePosition.trade_swap, tradeImport.TradeDate.Value, null, lastManualCash, tradePosition.trade_swap.IsGetFloatingProfit, out endDate);
var extraAmountGetQuote = PayoffSwapCalcService.GetExtraAmountBySwapRate(tradePosition.ClientId, tradePosition.TradeDate, tradePosition.trade_swap.GetSwapTimeAndRate, preSwapDate, endDate, tradePosition.trade_swap.AnnualDays ?? 0, (tradePosition.OriginalStockEqvNotional ?? 0) * (tc.UnwindPercentRate ?? 0));
var extraAmountGet = extraAmountGetQuote * (PS.Config.Company == Configuration.CompanyEnum.中金 && client.BoundSide == BoundSideEnum.南向 ? currencyRateTradeDate : currencyRate);
var costFeeGetQuote = PayoffSwapCalcService.GetCostFee(tradePosition, tradeImport, tc, true, false);
var costFeeGet = (costFeeGetQuote * currencyRate).FormatValue(2);
var costTradePriceGetQuote = 0.0;
var costTradePriceGet = 0.0;
if (!tradePosition.trade_swap.IsTradePriceWhenOpen)
{
costTradePriceGetQuote = PayoffSwapCalcService.GetCostFee(tradePosition, tradePosition, tc, true, true);
costTradePriceGet = (costTradePriceGetQuote * currencyRate).FormatValue(2);
}
tc.Amount = extraAmountGet + costFeeGet + costTradePriceGet - initialAmountPay;
tc.QuoteAmount = extraAmountGetQuote + costFeeGetQuote + costTradePriceGetQuote - initialAmountPayQuote;
tc.CurrencyRate = currencyRate;
tc.Action = ClientCashInCashOut.系统操作_平仓费;
tc.Status = TradeCashStatusEnum.已执行;
tc.ValueDate = tradeImport.TradeDate.Value;
tc.ValidState = "Valid";
tc.ExerciseWay = tradeImport.TradeDate == tradePosition.ExerciseDate ? TradeCashExerciseWayEnum.到期行权 : TradeCashExerciseWayEnum.提前终止行权;
if (client.BoundSide == BoundSideEnum.北向)
{
tc.Number = tradePosition.TradeNumber + "_UW_" + num;
}
DbContext.SaveChanges();
if (unwindType == "全部平仓")
{
tradePosition.TradeStatus = "已平仓";
}
else
{
tradePosition.HasPartialUnWind = 1;
}
tradePosition.UnWindDate = tc.ValueDate;
tradePosition.StockEqvNotional -= (tradePosition.SpotPrice ?? 0) * (tc.UnwindNotional ?? 0);
tradePosition.Notional -= tc.UnwindNotional ?? 0;
tradePosition.TradeAmount -= tc.UnwindTradeAmount ?? 0;
tradePosition.UnWindNotional = tc.UnwindNotional;
//增加出入金记录
new ClientCashinCashoutBLL(this).CloseTrade_ClientCashInCashOutSave(tradePosition, tc, tc.ValueDate);
var trade_swap = DbContext.trade_swap.FirstOrDefault(x => x.TradeId == tc.TradeId);
var trade_cash_swap = new trade_cash_swap();
trade_cash_swap.StartDate = tradePosition.StartDate.Value;
trade_cash_swap.PayStartPrice = trade_swap.PayFinalPrice ?? trade_swap.PaySpotPrice;
trade_cash_swap.PayFinalPrice = tc.FinalPrice;
trade_cash_swap.PayInitialAmount = initialAmountPay;
trade_cash_swap.PayAmount = initialAmountPay;
trade_cash_swap.PaySwapRate = PayoffSwapCalcService.GetSwapRateByDate(tradePosition.trade_swap.PaySwapTimeAndRate, tradePosition.UnWindDate.Value);
trade_cash_swap.GetExtraAmount = extraAmountGet;
trade_cash_swap.GetCostFee = costFeeGet + costTradePriceGet;
trade_cash_swap.GetAmount = extraAmountGet + costFeeGet + costTradePriceGet;
trade_cash_swap.GetSwapRate = PayoffSwapCalcService.GetSwapRateByDate(tradePosition.trade_swap.GetSwapTimeAndRate, tradePosition.UnWindDate.Value);
trade_cash_swap.TradeId = tc.TradeId;
trade_cash_swap.TradeCashId = tc.id;
trade_cash_swap.FlowId = tradeImport.trade_swap.FlowId;
trade_cash_swap.OptId = tc.OptId;
trade_cash_swap.OptName = tc.OptName;
trade_cash_swap.OptDate = DateTime.Now;
DbContext.trade_cash_swap.Add(trade_cash_swap);
var tcdGet = new trade_cash_detail
{
TradeId = tc.TradeId,
TradeCashId = tc.id,
Action = tc.Action,
Amount = extraAmountGet,
QuoteAmount = extraAmountGetQuote,
ValueDate = tc.ValueDate,
IsForGet = true,
OptId = tc.OptId,
OptName = tc.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.利息.ToString()
};
DbContext.trade_cash_detail.Add(tcdGet);
var tcdCostFeeGet = new trade_cash_detail
{
TradeId = tc.TradeId,
TradeCashId = tc.id,
Action = tc.Action,
Amount = costFeeGet,
QuoteAmount = costFeeGetQuote,
ValueDate = tc.ValueDate,
IsForGet = true,
OptId = tc.OptId,
OptName = tc.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.了结手续费.ToString()
};
DbContext.trade_cash_detail.Add(tcdCostFeeGet);
var tcdCostTradePriceGet = new trade_cash_detail
{
TradeId = tc.TradeId,
TradeCashId = tc.id,
Action = tc.Action,
Amount = costTradePriceGet,
QuoteAmount = costTradePriceGetQuote,
ValueDate = tc.ValueDate,
IsForGet = true,
OptId = tc.OptId,
OptName = tc.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.开仓手续费.ToString()
};
DbContext.trade_cash_detail.Add(tcdCostTradePriceGet);
var tcdPay = new trade_cash_detail
{
TradeId = tc.TradeId,
TradeCashId = tc.id,
Action = tc.Action,
Amount = -initialAmountPay,
QuoteAmount = -initialAmountPayQuote,
ValueDate = tc.ValueDate,
IsForGet = false,
OptId = tc.OptId,
OptName = tc.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.浮动收益.ToString()
};
DbContext.trade_cash_detail.Add(tcdPay);
tradeImport.Notional -= tc.UnwindNotional ?? 0;
tradeImport.TradeAmount -= tc.UnwindTradeAmount ?? 0;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeImport.UnderlyingCode);
tradeImport.Lots -= tc.UnwindNotional / underlying.ContractSize;
tradeImport.StockEqvNotional -= (tc.UnwindNotional ?? 0) * (tradeImport.SpotPrice ?? 0);
DbContext.SaveChanges();
}
private void UnwindSwapTradeCashPreHandle(trade tradePosition, trade tradeImport, string unwindType)
{
var tradeCashPres = DbContext.trade_cash_pre.Where(x => x.TradeId == tradePosition.id && x.ValidState != "InValid");
var tradeCashPreList= tradeCashPres.Where(y => y.Action == "系统操作-互换" && y.ValidState != "InValid" && !y.IsDeleted && y.ValueDate <= tradeImport.TradeDate.Value);
var num = tradeCashPres.Where(x => x.Action != ClientCashInCashOut.系统操作_期权费).Count() + 1;
var client = DataCacheProvider.GetClientDataSource().GetData(tradePosition.ClientId);
//增加Pre现金交割交易记录
var tcPre = new trade_cash_pre();
DbContext.trade_cash_pre.Add(tcPre);
tcPre.OptId = UserId;
tcPre.OptName = UserName;
tcPre.OptDate = OptDate;
tcPre.ExceciseType = "现金";
tcPre.TradeType = tradePosition.BuySell;
tcPre.CallPut = tradePosition.CallPut;
tcPre.Notional = tradePosition.Notional;
tcPre.TradeAmount = tradePosition.TradeAmount;
tcPre.IsLastAction = unwindType == "全部平仓";
tcPre.TradeId = tradePosition.id;
tcPre.FinalPrice = tradeImport.SpotPrice;
tcPre.UnwindType = unwindType;
if (tcPre.UnwindType == "全部平仓")
{
tcPre.UnwindNotional = tradePosition.Notional;
tcPre.UnwindTradeAmount = tradePosition.TradeAmount;
tcPre.UnwindPercentRate = tradePosition.Notional / tradePosition.OriginalNotional;
}
else
{
tcPre.UnwindNotional = tradeImport.Notional;
tcPre.UnwindTradeAmount = tradeImport.TradeAmount;
tcPre.UnwindPercentRate = tradeImport.Notional / tradePosition.OriginalNotional;
}
tcPre.NotionalPercentRate = tcPre.UnwindPercentRate;
tradeBLL.SetFieldsByTradeType(tradePosition);
var initialAmountPayQuote = PayoffSwapCalcService.GetInitialAmountSwapPay(tradePosition, tradePosition.trade_swap, tradePosition.trade_swap.PaySpotPrice ?? 0
, tradeImport.SpotPrice ?? 0, (tradePosition.OriginalStockEqvNotional ?? 0) * (tcPre.UnwindPercentRate ?? 0), tradeImport.TradeDate.Value, null);
var cashSwaps = DbContext.trade_cash_swap.Where(x => x.TradeId == tradePosition.id).ToArray();
//取最后一次手动收益;
var lastManualCashSwap = cashSwaps.OrderByDescending(o => o.StartDate).FirstOrDefault(x => !x.IsAuto);
var lastManualCash = lastManualCashSwap != null ? tradeCashPreList.FirstOrDefault(x => x.id == lastManualCashSwap.TradeCashId) : null;
DateTime endDate;
var preSwapDate = PayoffSwapCalcService.GetSwapRateStartDatePre(tradePosition, tradePosition.trade_swap, tradeImport.TradeDate.Value, null, lastManualCash, tradePosition.trade_swap.IsGetFloatingProfit, out endDate);
var extraAmountGetQuote = PayoffSwapCalcService.GetExtraAmountBySwapRate(tradePosition.ClientId, tradePosition.TradeDate, tradePosition.trade_swap.GetSwapTimeAndRate, preSwapDate, endDate, tradePosition.trade_swap.AnnualDays ?? 0, (tradePosition.OriginalStockEqvNotional ?? 0) * (tcPre.UnwindPercentRate ?? 0));
var tradeCash = new trade_cash() { UnwindNotional = tcPre.UnwindNotional, UnwindTradeAmount = tcPre.UnwindTradeAmount, UnwindPercentRate = tcPre.UnwindPercentRate, FinalPrice = tcPre.FinalPrice };
var costFeeGetQuote = PayoffSwapCalcService.GetCostFee(tradePosition, tradeImport, tradeCash, true, false);
var costTradePriceGetQuote = 0.0;
if (!tradePosition.trade_swap.IsTradePriceWhenOpen)
{
costTradePriceGetQuote = PayoffSwapCalcService.GetCostFee(tradePosition, tradePosition, tradeCash, true, true);
}
tcPre.Amount = extraAmountGetQuote + costFeeGetQuote + costTradePriceGetQuote - initialAmountPayQuote;
tcPre.Action = ClientCashInCashOut.系统操作_平仓费;
tcPre.Status = TradeCashStatusEnum.已执行;
tcPre.ValueDate = tradePosition.SettlementDate.Value;
tcPre.HappenedDate = tradeImport.TradeDate.Value;
tcPre.ValidState = "Valid";
tcPre.ExerciseWay = TradeCashExerciseWayEnum.到期行权;
tcPre.IsFinished = false;
if (client.BoundSide == BoundSideEnum.北向)
{
tcPre.Number = tradePosition.TradeNumber + "_UW_" + num;
}
DbContext.SaveChanges();
if (unwindType == "全部平仓")
{
tradePosition.TradeStatus = "已平仓";
}
else
{
tradePosition.HasPartialUnWind = 1;
}
tradePosition.UnWindDate = tcPre.HappenedDate;
tradePosition.StockEqvNotional -= (tradePosition.SpotPrice ?? 0) * (tcPre.UnwindNotional ?? 0);
tradePosition.Notional -= tcPre.UnwindNotional ?? 0;
tradePosition.TradeAmount -= tcPre.UnwindTradeAmount ?? 0;
tradePosition.UnWindNotional = tcPre.UnwindNotional;
var trade_swap = DbContext.trade_swap.FirstOrDefault(x => x.TradeId == tcPre.TradeId);
var trade_cash_swap = new trade_cash_swap();
trade_cash_swap.StartDate = tradePosition.StartDate.Value;
trade_cash_swap.PayStartPrice = trade_swap.PayFinalPrice ?? trade_swap.PaySpotPrice;
trade_cash_swap.PayFinalPrice = tcPre.FinalPrice;
trade_cash_swap.PayInitialAmount = initialAmountPayQuote;
trade_cash_swap.PayAmount = initialAmountPayQuote;
trade_cash_swap.PaySwapRate = PayoffSwapCalcService.GetSwapRateByDate(tradePosition.trade_swap.PaySwapTimeAndRate, tradePosition.UnWindDate.Value);
trade_cash_swap.GetExtraAmount = extraAmountGetQuote;
trade_cash_swap.GetCostFee = costFeeGetQuote + costTradePriceGetQuote;
trade_cash_swap.GetAmount = extraAmountGetQuote + costFeeGetQuote + costTradePriceGetQuote;
trade_cash_swap.GetSwapRate = PayoffSwapCalcService.GetSwapRateByDate(tradePosition.trade_swap.GetSwapTimeAndRate, tradePosition.UnWindDate.Value);
trade_cash_swap.TradeId = tcPre.TradeId;
trade_cash_swap.TradeCashPreId = tcPre.id;
trade_cash_swap.FlowId = tradeImport.trade_swap.FlowId;
trade_cash_swap.OptId = tcPre.OptId;
trade_cash_swap.OptName = tcPre.OptName;
trade_cash_swap.OptDate = DateTime.Now;
DbContext.trade_cash_swap.Add(trade_cash_swap);
var tcdGet = new trade_cash_detail
{
TradeId = tcPre.TradeId,
TradeCashPreId = tcPre.id,
Action = tcPre.Action,
QuoteAmount = extraAmountGetQuote,
ValueDate = tcPre.ValueDate,
IsForGet = true,
OptId = tcPre.OptId,
OptName = tcPre.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.利息.ToString()
};
DbContext.trade_cash_detail.Add(tcdGet);
var tcdCostFeeGet = new trade_cash_detail
{
TradeId = tcPre.TradeId,
TradeCashPreId = tcPre.id,
Action = tcPre.Action,
QuoteAmount = costFeeGetQuote,
ValueDate = tcPre.ValueDate,
IsForGet = true,
OptId = tcPre.OptId,
OptName = tcPre.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.了结手续费.ToString()
};
DbContext.trade_cash_detail.Add(tcdCostFeeGet);
var tcdCostTradePriceGet = new trade_cash_detail
{
TradeId = tcPre.TradeId,
TradeCashPreId = tcPre.id,
Action = tcPre.Action,
QuoteAmount = costTradePriceGetQuote,
ValueDate = tcPre.ValueDate,
IsForGet = true,
OptId = tcPre.OptId,
OptName = tcPre.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.开仓手续费.ToString()
};
DbContext.trade_cash_detail.Add(tcdCostTradePriceGet);
var tcdPay = new trade_cash_detail
{
TradeId = tcPre.TradeId,
TradeCashPreId = tcPre.id,
Action = tcPre.Action,
QuoteAmount = -initialAmountPayQuote,
ValueDate = tcPre.ValueDate,
IsForGet = false,
OptId = tcPre.OptId,
OptName = tcPre.OptName,
OptDate = DateTime.Now,
TradeCashType = TradeCashTypeEnum.浮动收益.ToString()
};
DbContext.trade_cash_detail.Add(tcdPay);
DbContext.SaveChanges();
tradeImport.Notional -= tcPre.UnwindNotional ?? 0;
tradeImport.TradeAmount -= tcPre.UnwindTradeAmount ?? 0;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeImport.UnderlyingCode);
tradeImport.Lots -= tcPre.UnwindNotional / underlying.ContractSize;
DbContext.SaveChanges();
}
private trade_swap_flow MapSwapTradeFlow(DataRowReader reader)
{
var needCostFee = reader.GetString("是否收取手续费");
var isTradePriceWhenOpen = reader.GetString("是否开仓时收取手续费");
var isNight = reader.GetString("是否夜盘");
var swapFlow = new trade_swap_flow()
{
TradeDate = reader.GetDate("交易日", true),
StartDate = reader.GetDate("北京时间自然日", true),
ExerciseDate = reader.GetDate("到期日"),
SettlementDate = reader.GetDate("结算日"),
BuySell = reader.GetString("买卖方向", true),
AssetUnitName = reader.GetString("簿记账户"),
ClientNumber = reader.GetString("客户编号", true),
ClientShortName = reader.GetString("客户简称"),
UnderlyingCode = reader.GetString("标的全称", true),
Lots = reader.GetDouble("手数", true).Value,
SpotPrice = reader.GetDouble("价格", true),
SingleFee = reader.GetDouble("按手数收费", false),
UnAnnualRate = reader.GetDouble("按名义本金收费", false),
ClearingAgency = reader.GetString("清算机构"),
NeedCostFee = needCostFee == "否" || needCostFee == "N" ? false : true,
IsTradePriceWhenOpen = isTradePriceWhenOpen == "是" || isTradePriceWhenOpen == "Y" ? true : false,
IsNight = isNight == "是" || isNight == "Y" ? true : false,
Comments = reader.GetString("备注"),
Number = "",
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now
};
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlow.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的[{swapFlow.UnderlyingCode}]在系统中不存在");
}
else
{
if (swapFlow.ExerciseDate == null)
{
swapFlow.ExerciseDate = underlying.MaturityDate;
}
if (swapFlow.ExerciseDate == null)
{
throw new ServiceException($"客户编号[{swapFlow.ClientNumber}]标的代码[{swapFlow.UnderlyingCode}]到期日不能为空");
}
if (swapFlow.SettlementDate == null)
{
swapFlow.SettlementDate = underlying.CloseDate;
}
if (swapFlow.AssetUnitName == null)
{
swapFlow.AssetUnitName = string.Empty;
}
if (swapFlow.SettlementDate != null && swapFlow.SettlementDate < swapFlow.ExerciseDate)
{
throw new ServiceException($"客户编号[{swapFlow.ClientNumber}]标的代码[{swapFlow.UnderlyingCode}]的结算日期不应该小于到期日");
}
}
var variety = DataCacheProvider.GetVariety(swapFlow.UnderlyingCode);
if (variety == null)
{
throw new ServiceException($"该标的[{swapFlow.UnderlyingCode}]对应的品种在系统中不存在");
}
else
{
if (string.IsNullOrWhiteSpace(variety.QuoteCurrency) && DbContext.currency.Any())
{
throw new ServiceException($"标的代码[{swapFlow.UnderlyingCode}]对应的品种币种不能为空");
}
else
{
swapFlow.QuoteCurrency = variety.QuoteCurrency;
}
}
swapFlow.Number = new BizLogicZJ().GenerateFlowNumber(swapFlow, DbContext);
SetDBModelCreator(swapFlow);
DbContext.trade_swap_flow.Add(swapFlow);
DbContext.SaveChanges();
return swapFlow;
}
private trade_swap_flow MapSwapTradeFlowGroup(DataRowReader reader)
{
var tradeAmount = reader.GetDouble("数量", false);
var lots = reader.GetDouble("手数", false);
var stockEqvNotional = reader.GetDouble("名义本金", false);
var swapFlow = new trade_swap_flow()
{
TradeNumber = reader.GetString("交易编号", true),
TradeDate = reader.GetDate("交易日", true),
UnderlyingCode = reader.GetString("标的代码", true),
BuySell = reader.GetString("买卖方向", true),
SpotPrice = reader.GetDouble("价格", true),
SingleFee = reader.GetDouble("按手数收费", false),
UnAnnualRate = reader.GetDouble("按名义本金收费", false),
NeedCostFee = true,
IsTradePriceWhenOpen = true,
OptId = UserId,
OptName = UserName,
OptDate = DateTime.Now,
CreatorId = UserId,
CreatorName = UserName,
CreateDate = DateTime.Now
};
swapFlow.StartDate = swapFlow.TradeDate;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlow.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的[{swapFlow.UnderlyingCode}]在系统中不存在");
}
else
{
if (stockEqvNotional != null && swapFlow.SpotPrice != 0)
{
tradeAmount = stockEqvNotional / swapFlow.SpotPrice;
}
if (tradeAmount != null)
{
lots = tradeAmount * underlying.CountRatio / underlying.ContractSize;
}
if (lots == null)
{
throw new ServiceException($"数量手数名义本金不能同时为空");
}
else
{
swapFlow.Lots = lots.Value;
}
}
var variety = DataCacheProvider.GetVariety(swapFlow.UnderlyingCode);
if (variety == null)
{
throw new ServiceException($"该标的[{swapFlow.UnderlyingCode}]对应的品种在系统中不存在");
}
else
{
if (string.IsNullOrWhiteSpace(variety.QuoteCurrency) && DbContext.currency.Any())
{
throw new ServiceException($"标的代码[{swapFlow.UnderlyingCode}]对应的品种币种不能为空");
}
else
{
swapFlow.QuoteCurrency = variety.QuoteCurrency;
}
}
DbContext.trade_swap_flow.Add(swapFlow);
DbContext.SaveChanges();
return swapFlow;
}
private trade MapSwapTradeHandle(trade_swap_flow swapFlow)
{
var client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(n => swapFlow.ClientNumber.Equals(n.Number, StringComparison.OrdinalIgnoreCase));
if (client == null)
{
throw new ServiceException($"该客户编号[{swapFlow.ClientNumber}]在系统中不存在");
}
if (!client.DerivativesInvestmentVarieties.Contains((int)DerivativesInvestmentVarietiesEnum.场外互换 + ""))
{
throw new ServiceException($"客户:{client.Name}未设置交易种类“场外互换”,无法生成互换交易!");
}
if (swapFlow.Lots <= 0)
{
throw new ServiceException($"客户[{swapFlow.ClientNumber}]对应的流水手数[{swapFlow.Lots}]需要为正数");
}
var td = new trade
{
TradeDate = swapFlow.TradeDate,
StartDate = swapFlow.StartDate,
ExerciseDate = swapFlow.ExerciseDate,
SettlementDate = swapFlow.SettlementDate == null ? swapFlow.ExerciseDate : swapFlow.SettlementDate,
BuySell = "卖出",
TradeType = "收益互换",
StructureType = "收益互换",
ClientId = client.id,
ClientName = client.Name,
QuoteCurrency = swapFlow.QuoteCurrency,
SettlementCurrency = client.SettlementCurrency,
UnderlyingCode = swapFlow.UnderlyingCode,
SpotPrice = swapFlow.SpotPrice,
Lots = swapFlow.Lots,
IsNight = swapFlow.IsNight,
OpponentRole = "甲方",
MarginType = MarginTypeEnum.DEFAULT,
trade_swap = new trade_swap()
{
FlowId = swapFlow.id
}
};
td.MetaDic["交易场所"] = "柜台市场";
if (string.IsNullOrWhiteSpace(swapFlow.ClearingAgency) && string.IsNullOrWhiteSpace(client.ClearingAgency))
{
throw new ServiceException($"该流水需要维护清算机构信息或该客户[{td.ClientName}]需要维护清算机构信息");
}
td.MetaDic["清算机构"] = string.IsNullOrWhiteSpace(swapFlow.ClearingAgency) ? client.ClearingAgency : swapFlow.ClearingAgency;
//if (string.IsNullOrWhiteSpace(client.MainProtocolCode))
//{
// throw new ServiceException($"该客户[{td.ClientName}]需要维护主协议编号信息");
//}
td.MetaDic["主协议编号"] = client.MainProtocolCode;
//if (string.IsNullOrWhiteSpace(client.SupProtocolCode))
//{
// throw new ServiceException($"该客户[{td.ClientName}]需要维护补充协议编号信息");
//}
td.MetaDic["补充协议编号"] = client.SupProtocolCode;
var varitey = DataCacheProvider.GetVariety(td.UnderlyingCode);
var clientVarietyConfig = DbContext.client_variety_config.Where(x => x.ClientId == td.ClientId && x.VarietyId == varitey.id && x.ValueDate <= td.TradeDate).OrderByDescending(x => x.ValueDate).FirstOrDefault();
if (clientVarietyConfig == null)
{
throw new ServiceException($"该客户[{td.ClientName}]需要维护品种[{varitey.VarietyCode}]在[{td.TradeDate}]相关的收费参数配置");
}
//标的代码(必需)
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的代码[{td.UnderlyingCode}]在系统中不存在");
}
else
{
td.UnderlyingId = underlying.id;
td.UnderlyingAssetClass = underlying.UnderlyingType;
td.MaturityDate = underlying.MaturityDate;
if (td.ExerciseDate == null)
{
td.ExerciseDate = underlying.MaturityDate;
swapFlow.ExerciseDate = underlying.MaturityDate;
}
td.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType;
td.UnderlyingAssetName = underlying.UnderlyingName;
}
if (td.ExerciseDate == null)
{
throw new ServiceException($"客户编号[{swapFlow.ClientNumber}]标的代码[{swapFlow.UnderlyingCode}]到期日不能为空");
}
var variety = DataCacheProvider.GetVarietyDataSource().GetData(underlying.UnderlyingTypeId);
//交易份额
td.Notional = (td.Lots ?? 0) * underlying.ContractSize;
td.TradeAmount = td.Notional / variety.CountRatio;
td.OriginalNotional = td.Notional;
td.StockEqvNotional = (td.SpotPrice ?? 0) * td.Notional;
td.StockEqvNotionalReal = td.StockEqvNotional;
td.OriginalStockEqvNotional = td.StockEqvNotional;
td.PrincipalRate = 0;
td.ParticipationRate = 1;
var assetUnit = DataCacheProvider.GetAssetUnitDataSource().AsQueryable().FirstOrDefault(x => ("," + x.TraderIds + ",").Contains("," + UserId + ","));
if (!string.IsNullOrWhiteSpace(swapFlow.AssetUnitName))
{
assetUnit = DataCacheProvider.GetAssetUnitDataSource().AsQueryable().FirstOrDefault(x => x.Name == swapFlow.AssetUnitName);
if (assetUnit == null)
{
throw new ServiceException($"不存在该簿记账户[{swapFlow.AssetUnitName}]");
}
}
if (assetUnit == null)
{
throw new ServiceException($"不存在和交易员[{UserName}]匹配的簿记账户");
}
td.AssetId = assetUnit.id;
td.AssetBookName = assetUnit.Name;
td.TraderId = UserId;
td.TraderName = UserName;
td.trade_swap.GetSwapTimeAndRate = td.ExerciseDate.Value.ToString("yyyy-MM-dd") + ";" + (clientVarietyConfig?.AnnualRate ?? 0).ToString();
td.trade_swap.PaySwapTimeAndRate = td.ExerciseDate.Value.ToString("yyyy-MM-dd") + ";0";
//0代表了结时支付,1代表结算日支付
td.trade_swap.SettlementPayType = swapFlow.SettlementDate == null ? 0 : 1;
td.trade_swap.IsTradePriceWhenOpen = swapFlow.IsTradePriceWhenOpen;
var isAnnualSet = swapFlow.SingleFee != null || swapFlow.UnAnnualRate != null;
td.trade_swap.GetSingleFee = swapFlow.NeedCostFee ? (isAnnualSet ? (swapFlow.SingleFee ?? 0) : clientVarietyConfig?.SingleFee) : 0;
td.trade_swap.GetUnAnnualRate = swapFlow.NeedCostFee ? (isAnnualSet ? (swapFlow.UnAnnualRate ?? 0) : clientVarietyConfig?.UnAnnualRate) : 0;
td.trade_swap.AnnualDays = clientVarietyConfig?.AnnualDays;
//交易方向
var longshort = swapFlow.BuySell;
switch (longshort)
{
case "买入":
case "B":
td.trade_swap.PayLongShort = "多头";
break;
case "卖出":
case "S":
td.trade_swap.PayLongShort = "空头";
break;
default:
throw new ServiceException("买卖方向 填写错误:" + longshort);
}
return td;
}
public void BackSwapTradeByTradeFlow(trade_swap_flow flow)
{
var client = ClientModule.ClientDataQueryService.GetClientByNumber(flow.ClientNumber);
var tradeCashList = (from tradeCash in DbContext.trade_cash
join trade in DbContext.trade
on tradeCash.TradeId equals trade.id
join tradeSwap in DbContext.trade_swap
on trade.id equals tradeSwap.TradeId
join tradeCashSwap in DbContext.trade_cash_swap
on tradeCash.id equals tradeCashSwap.TradeCashId
where trade.UnderlyingCode == flow.UnderlyingCode && tradeSwap.OriginalTradeId == null && trade.ClientId == client.id && (tradeCashSwap.FlowId >= flow.id && tradeCash.ValueDate == flow.TradeDate || tradeCash.ValueDate > flow.TradeDate)
select new { tradeCash, tradeCashSwap }).OrderByDescending(x => x.tradeCash.id).ToList();
tradeCashList.ForEach(x =>
{
var trade = DbContext.trade.Find(x.tradeCash.TradeId);
trade.Notional = x.tradeCash.Notional;
var variety = DataCacheProvider.GetVarietyDataSource().GetData(trade.VarietyId ?? 0);
if (variety != null && variety.CountRatio != 0)
{
trade.TradeAmount = x.tradeCash.Notional / variety.CountRatio;
}
else
{
trade.TradeAmount = x.tradeCash.Notional;
}
trade.StockEqvNotional = TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor);
//分步回退时将倒数第二条平仓记录赋值给trade
var lastSecondTradeCash = DbContext.trade_cash.Where(y => y.TradeId == x.tradeCash.TradeId && y.id < x.tradeCash.id && y.ValidState != "InValid" && y.Action != "系统操作-期权费").OrderByDescending(y => y.id).FirstOrDefault();
if (lastSecondTradeCash != null && lastSecondTradeCash.Action == "系统操作-平仓费")
{
trade.UnWindDate = lastSecondTradeCash.ValueDate;
trade.FinalPrice = lastSecondTradeCash.FinalPrice;
trade.UnWindNotional = lastSecondTradeCash.UnwindNotional;
trade.UnWindPrice = lastSecondTradeCash.UnwindPrice;
trade.HasPartialUnWind = 1;
}
else
{
trade.UnWindDate = null;
trade.FinalPrice = null;
trade.UnWindNotional = null;
trade.UnWindPrice = null;
trade.HasPartialUnWind = null;
}
trade.CheckStatus = null;
trade.OptId = UserId;
trade.OptName = UserName;
trade.OptDate = DateTime.Now;
trade.TradeStatus = ConsTrade.确认成交;
trade.ProcessOrderId = 0;
trade.ProcessOptDate = null;
trade.ProcessStatus = null;
DbContext.SaveChanges();
RemoveEodTradeAndFutureInfo(true, trade.id, x.tradeCash.ValueDate, new List<int>() { x.tradeCash.id });
AddTradeOperationHistoryAndSetParentTradeInfo(true, trade, "修改交易流水");
});
var tradeCashPreList = (from tradeCashPre in DbContext.trade_cash_pre
join tradeCashSwap in DbContext.trade_cash_swap
on tradeCashPre.id equals tradeCashSwap.TradeCashPreId
where tradeCashSwap.FlowId == flow.id
select new { tradeCashPre, tradeCashSwap }).ToList();
tradeCashPreList.ForEach(x =>
{
var trade = DbContext.trade.Find(x.tradeCashPre.TradeId);
trade.Notional = x.tradeCashPre.Notional;
var variety = DataCacheProvider.GetVarietyDataSource().GetData(trade.VarietyId ?? 0);
if (variety != null && variety.CountRatio != 0)
{
trade.TradeAmount = x.tradeCashPre.Notional / variety.CountRatio;
}
else
{
trade.TradeAmount = x.tradeCashPre.Notional;
}
trade.StockEqvNotional = TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor);
//分步回退时将倒数第二条平仓记录赋值给trade
var lastSecondTradeCashPre = DbContext.trade_cash_pre.Where(y => y.TradeId == x.tradeCashPre.TradeId && y.id < x.tradeCashPre.id && y.ValidState != "InValid" && y.Action != "系统操作-期权费").OrderByDescending(y => y.id).FirstOrDefault();
if (lastSecondTradeCashPre != null && lastSecondTradeCashPre.Action == "系统操作-平仓费")
{
trade.UnWindDate = lastSecondTradeCashPre.HappenedDate;
trade.FinalPrice = lastSecondTradeCashPre.FinalPrice;
trade.UnWindNotional = lastSecondTradeCashPre.UnwindNotional;
trade.UnWindPrice = lastSecondTradeCashPre.UnwindPrice;
trade.HasPartialUnWind = 1;
}
else
{
trade.UnWindDate = null;
trade.FinalPrice = null;
trade.UnWindNotional = null;
trade.UnWindPrice = null;
trade.HasPartialUnWind = null;
}
trade.CheckStatus = null;
trade.OptId = UserId;
trade.OptName = UserName;
trade.OptDate = DateTime.Now;
trade.TradeStatus = ConsTrade.确认成交;
trade.ProcessOrderId = 0;
trade.ProcessOptDate = null;
trade.ProcessStatus = null;
DbContext.SaveChanges();
var tradeCashPreIds = DbContext.trade_cash_pre.Where(y => y.TradeId == x.tradeCashPre.TradeId && y.id >= x.tradeCashPre.id).Select(y => y.id).ToList();
RemoveEodTradeAndFutureInfo(true, trade.id, x.tradeCashPre.HappenedDate ?? x.tradeCashPre.ValueDate, tradeCashPreIds: tradeCashPreIds);
AddTradeOperationHistoryAndSetParentTradeInfo(true, trade, "修改交易流水");
});
var tradeList = (from trade in DbContext.trade
join swap in DbContext.trade_swap
on trade.id equals swap.TradeId
where trade.UnderlyingCode == flow.UnderlyingCode && swap.OriginalTradeId == null && trade.ClientId == client.id && (swap.FlowId >= flow.id && trade.TradeDate == flow.TradeDate || trade.TradeDate > flow.TradeDate) && trade.ValidState != "InValid"
select new { trade, swap }).ToList();
var baseService = new TradeServiceBase(UserInfo, DbContext);
tradeList.ForEach(x => new TradeInvalidService(baseService).InvalidTrade(x.trade.id, false));
}
private void SaveTradeMeta(trade t)
{
if (t != null && t.MetaDic != null && t.MetaDic.Count() > 0)
{
foreach (var kv in t.MetaDic)
{
if (!string.IsNullOrEmpty(kv.Value))
{
AddTradeMeta(false, t.id, kv.Key, kv.Value);
}
}
}
}
//public void generateSettleDocument(List<trade_cash> cashes)
//{
// if (cashes.Count() > 0)
// {
// var clientTradeDict =
// cashes.GroupBy(O => O.ClientName + "|" + O.ValueDate)
// .ToDictionary(K => K.Key, V => V.Select(O => O.id).ToList());
// foreach (var tradeCashs in clientTradeDict)
// {
// var clienName = cashes.FirstOrDefault().ClientName;
// var client = DbContextFactory.GetClientDbContext(OptUser).client.Where(o => o.Name == clienName).FirstOrDefault();
// if (client != null && client.BoundSide == BoundSideEnum.北向)
// {
// foreach (var tc in tradeCashs.Value)
// {
// new RDBatchEndBillGenerateService(OptUser)
// .Generate(new List<int> { tc }, null, "PDF", OptUser.UserId, OptUser.UserName).ToList();
// }
// }
// else
// {
// new RDBatchEndBillGenerateService(OptUser)
// .Generate(tradeCashs.Value, null, "PDF", OptUser.UserId, OptUser.UserName).ToList();
// }
// }
// }
//}
#region---内部业务类----
class DataRowReader
{
DataRow _row;
readonly Dictionary<string, int> _colMap;
public DataRowReader(DataTable table)
{
var colCount = table.Columns.Count;
_colMap = new Dictionary<string, int>(colCount, StringComparer.OrdinalIgnoreCase);
var row1 = table.Rows[0];
var preCol1 = string.Empty;
for (var index = 0; index < colCount; index++)
{
var col1 = row1[index]?.ToString()?.Trim();
if (!string.IsNullOrWhiteSpace(col1))
{
preCol1 = col1;
}
else
{
continue;
}
_colMap[preCol1] = index;
}
}
/// <summary>
/// 设置datarow
/// </summary>
public void SetDataRow(DataRow row)
{
_row = row;
}
public string GetString(string fieldName, bool required = false)
{
var str = _colMap.TryGetValue(fieldName, out var colIndex) ? _row[colIndex]?.ToString()?.Trim() : null;
if (required && string.IsNullOrWhiteSpace(str))
{
throw new ServiceException($"{fieldName} 必须填写");
}
return str;
}
public double? GetDoubleOrPercent(string fieldName, bool required, bool percent)
{
var str = GetString(fieldName, required);
if (!required && string.IsNullOrWhiteSpace(str))
{
return null;
}
if (percent && (percent = str.EndsWith("%")))
{
str = str.TrimEnd('%');
}
return double.TryParse(str, out var num) ? (percent ? num / 100 : num) : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
public double? GetDouble(string fieldName, bool required = false)
{
var str = GetString(fieldName, required);
if (!required && string.IsNullOrWhiteSpace(str))
{
return null;
}
return double.TryParse(str, out var num) ? num : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
//为了兼容模板修改导致的字段名称改变问题
public double? GetDouble(string fieldName, string fieldName2, bool required = false)
{
var str = GetString(fieldName, false) ?? GetString(fieldName2, false);
if (string.IsNullOrWhiteSpace(str))
{
return required ? throw new ServiceException($"{fieldName} 必须填写") : (double?)null;
}
return double.TryParse(str, out var num) ? num : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
public double? GetPercent(string fieldName, bool required = false)
{
var str = GetString(fieldName, required);
if (!required && string.IsNullOrWhiteSpace(str))
{
return null;
}
var percent = str.EndsWith("%");
if (percent)
{
str = str.TrimEnd('%');
}
return double.TryParse(str, out var num) ? (percent ? num / 100 : num) : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
/// <summary>
/// 获取日期(不包括时间)
/// </summary>
public DateTime? GetDate(string fieldName, bool required = false)
{
var str = GetString(fieldName, required);
if (!required && string.IsNullOrWhiteSpace(str))
{
return null;
}
if (str.Length == 8 && Regex.IsMatch(str, @"^\d+$"))
{
return DateTime.TryParseExact(str, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt2) ? dt2 : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
return DateTime.TryParse(str, out var dt) ? dt.Date : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
/// <summary>
///
/// </summary>
public int? GetInt32(string fieldName, bool required = false)
{
var str = GetString(fieldName, required);
if (!required && string.IsNullOrWhiteSpace(str))
{
return null;
}
return int.TryParse(str, out var num) ? num : throw new ServiceException($"{fieldName} 填写错误:{str}");
}
}
#endregion
}
}