Files
zszq-trs/YLErpDAL/Modules/ReportModule/SettlementReportModule/SettlementReportFotZJService.cs
T
2024-05-09 14:06:26 +08:00

1180 lines
66 KiB
C#

using Newtonsoft.Json;
using OfficeOpenXml;
using System.Text.RegularExpressions;
using YLErp.BLL;
using YLErp.BLL.Eod;
using YLErp.BLL.EodSettlement;
using YLErp.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Modules.ClientModule;
using YLErp.Modules.DataCacheModule;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.ReportModule.SettlementReportModule;
using YLErp.Office;
using YLErp.QdpModule;
namespace YLErp.Modules.ReportModule
{
/// <summary>
/// 结算报告服务
/// </summary>
public class SettlementReportForZJService : YLBaseService
{
public SettlementReportForZJService(OptUserInfo userInfo) : base(userInfo)
{
}
public ClientDingShiReport_ZJ GetReportData(DingShiReportEmail emailData, IEnumerable<int> userAssetUnits, string template = "")
{
//todo 获取模板
var report = new ClientDingShiReport_ZJ() { ReportEnd = emailData.To };
var client = report.client = DataCacheProvider.GetClientDataSource().GetData(emailData.ClientId);
if (string.IsNullOrWhiteSpace(report.client.SettlementCurrency))
{
throw new ServiceException("客户未设置结算币种!");
}
#region 合计
var clientBalance = ClientBalanceUtility.GetClientBanlances(new List<int> { emailData.ClientId }, emailData.From, emailData.To, IsClientBalanceGap: false, IsGetOuterMarginGap: false, ParentFlag: emailData.ParentFlag).FirstOrDefault();
var clientspan = DbContext.client_span.FirstOrDefault(o => o.ClientId == client.id && o.ValueDate == emailData.To);
if (clientspan == null)
{
clientspan = new ClientSpan();
}
var clientCredit = DbContext.credit.FirstOrDefault(o => o.ClientId == client.id && o.CreditStartDate <= emailData.To && o.CreditDeadLine >= emailData.To && o.ProcessOrderId == -2);
var credit = clientCredit == null ? 0 : clientCredit.Credit ?? 0;
report.summaryReportModel = new SummaryReportModel()
{
ClientName = report.client.Name,
ReportDate = report.ReportEnd,
RemainCash = clientBalance.AmountFund,
MarginRequiement = clientspan.IM ?? 0,
QuoteMarginRequiement = 0,
CashQuotaLeft = 0,
UnRealizedPnl = 0,
QuoteUnRealized = 0,
CurrencyRate = 0,
IM = clientspan.IM ?? 0,
VM = (clientspan.VM ?? 0) + (clientspan.Commission ?? 0),
Deduct = clientspan.Deduct ?? 0,
PFEUsed = clientspan.PFEUsed ?? 0,
Credit = clientCredit == null ? 0 : clientCredit.Credit ?? 0,
PFECredit = clientCredit == null ? 0 : clientCredit.PFECredit ?? 0,
PayableFund = clientBalance.PayableFundTotal,
AvailableFund = 0,
Margin = -clientBalance.Margin,
//PositionPv = clientBalance.PositionPv,
SettlementCurrency = report.client.SettlementCurrency,
};
#endregion
if (client.BoundSide == BoundSideEnum.北向)
{
if (clientBalance.FundJson == null)
{
throw new ServiceException("客户多币种资金明细为空,请重新收盘后再试");
}
var fund = JsonConvert.DeserializeObject<FundObject>(clientBalance.FundJson);
report.summaryReportModel.QuotaCurrency = "CNH";
//北向需要的是USD转CNH的汇率,所以这里倒过来了,相应的用到这个汇率是用的除
report.summaryReportModel.CurrencyRate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(report.summaryReportModel.SettlementCurrency, report.summaryReportModel.QuotaCurrency, report.ReportEnd);
report.summaryReportModel.QuoteMarginRequiement = report.summaryReportModel.MarginRequiement * report.summaryReportModel.CurrencyRate;
report.summaryReportModel.QuoteCash = fund.TodayRemainFund.ContainsKey(report.summaryReportModel.QuotaCurrency) ? fund.TodayRemainFund[report.summaryReportModel.QuotaCurrency] : 0;
report.summaryReportModel.SettleCash = fund.TodayRemainFund.ContainsKey(report.summaryReportModel.SettlementCurrency) ? fund.TodayRemainFund[report.summaryReportModel.SettlementCurrency] : 0;
}
#region 持仓明细
var spanReq = new TradeSpanReq { ClientId = emailData.ClientId, ValueDate = emailData.To, ParentFlag = emailData.ParentFlag };
report.swap_position = clientTradePositionQueryList(spanReq, userAssetUnits);
report.summaryReportModel.QuoteUnRealized = report.swap_position.Sum(o => (o.UnrealizedPnl - o.Commision - o.AnnualFee));
report.summaryReportModel.UnRealizedPnl = report.summaryReportModel.QuoteUnRealized / report.summaryReportModel.CurrencyRate;
#endregion
#region 资金明细
var req = new EntryExitReq() { ClientId = emailData.ClientId, HappenDateStart = emailData.From, HappenDateEnd = emailData.To, ParentFlag = emailData.ParentFlag };
report.cash_records = SearchListExtendOnly(req, report.summaryReportModel.SettlementCurrency, report.summaryReportModel.QuotaCurrency, client.BoundSide);
report.cash_records.SettlementCurrency = report.client.SettlementCurrency;
#endregion
report.summaryReportModel.CashQuotaLeft = report.summaryReportModel.RemainCash;
if (!(report.client.AgreementBookType ?? true))
{
report.summaryReportModel.CashQuotaLeft += (report.summaryReportModel.UnRealizedPnl - report.summaryReportModel.MarginRequiement);
//双向 = cash + UnRealized Pnl - Margin Requiement
}
else
{
report.summaryReportModel.CashQuotaLeft += Math.Min(0, report.summaryReportModel.UnRealizedPnl) - report.summaryReportModel.MarginRequiement;
//单向 = cash + Min(0 , UnRealized Pnl- Margin Requiement)
}
if (client.BoundSide == BoundSideEnum.北向)
{
#region 平仓明细
report.swap_unwind = clientTradeUnwindQueryList(emailData, userAssetUnits, BoundSideEnum.北向);
#endregion
}
else
{
#region 标的持仓
report.underlying_positon = getClientUnderlyingPosition(report.swap_position, emailData.To);
#endregion
#region 流水记录
report.summaryReportModel.swap_flow = clientTradeFlowQueryList(emailData.To, userAssetUnits, client);
report.summaryReportModel.UnRealizedPnl = report.summaryReportModel.swap_flow.Sum(o => o.UnrealizedPnl ?? 0);
report.summaryReportModel.MarginRequiement = report.summaryReportModel.VM + report.summaryReportModel.IM;
report.summaryReportModel.AvailableFund = report.summaryReportModel.RemainCash - report.summaryReportModel.MarginRequiement;
#endregion
#region 今日开平仓
report.today_swap = clientTradeUnwindQueryList(emailData, userAssetUnits, BoundSideEnum.南向);
#endregion
#region 历史交易
report = GetHistoryInfo(report);
#endregion
}
report.Title = emailData.Title;
report.downloadFilePath = emailData.DownloadFilePath;
return report;
}
public (EmailTradeConfirmResultType status, string message) SendSettlementReports(DingShiReportEmail emailData, ClientDingShiReport_ZJ report, string template, List<string> recevier = null)
{
string message = null;
var attachFiles = new List<string>();
emailData.FileTypes.ForEach(type =>
{
if (type.@checked)
{
var filepath = GenerateFileEntry(report);
if (!string.IsNullOrEmpty(filepath))
{
attachFiles.Add(filepath);
}
}
});
//刘总认为追保无需检查用户银行卡
//var bankcard = ClientDataProvider.GetBankCard(report.client.id);
//if (bankcard == null && report.FundReportModel.PayableFund > 0)
//{
// throw new Exception(report.client.Name + "未配置银行卡信息!");
//}
// 要向该客户的所有订阅了邮件通知的人员发送邮件
var emails = ClientDataQueryService.GetClientEmails(report.client.id, false, recevier);
var status = EmailTradeConfirmResultType.Succeed;
if (emails.All(o => string.IsNullOrWhiteSpace(o)))
{
status = EmailTradeConfirmResultType.NoEmailSetting;
}
else
{
emails = emails.Where(o => !string.IsNullOrWhiteSpace(o));
var title = DBCacheManager.Single.GetStr(CacheTable.ClientBalanceReportTiltle, template);
if (string.IsNullOrWhiteSpace(title))
{
throw new ServiceException(template + "模板标题设置为空,无法发送");
}
var detail = DBCacheManager.Single.GetStr(CacheTable.MarginLuoKuanDesc, template);
title = ReplaceWildcard(title, report);
detail = ReplaceWildcard(detail, report);
var mailFrom = DBCacheManager.Single.GetStr(CacheTable.TradeMarketSendUser, template);
if (string.IsNullOrWhiteSpace(mailFrom))
{
mailFrom = DBCacheManager.Single.GetStr(CacheTable.TradeMarketSendUser);
}
message = EmailHelper.SendMail(string.Join(";", emails), title, detail, true, attachFiles, emailData.CCEmail, mailFrom);
if (!string.IsNullOrEmpty(message))
{
status = EmailTradeConfirmResultType.EmailSentFailed;
}
}
return (status, message);
}
/// <summary>
/// 持仓明细
/// </summary>
/// <returns></returns>
private List<PositionTradeModel> clientTradePositionQueryList(TradeSpanReq req, IEnumerable<int> userAssetUnits)
{
if (req.ClientId == null || req.ValueDate == null)
{
return new List<PositionTradeModel>();
}
var positionList = new ClientPositionQueryService(this).SearchPositionListAll(req, userAssetUnits);
//未了结远期
var UnSettledForwards = DbContext.trade_cash_pre.Where(o => o.ValueDate > req.ValueDate && o.HappenedDate <= req.ValueDate).ToList();
var UnSettledTradeIds = UnSettledForwards.Select(o => o.TradeId).Distinct().ToList();
var queryList = (from t in DbContext.trade.Where(o => UnSettledTradeIds.Contains(o.id) && o.ClientId == req.ClientId)
select new eod_position
{
TradeId = t.id,
tradeOrigin = t,
TradeJson = "",
ValueDate = req.ValueDate,
UnderlyingCode = t.UnderlyingCode
}).ToList();
positionList.AddRange(queryList);
// eod_trade_position_swap
var underlyingPriceProvider = new EodPriceProvider(req.ValueDate ?? DateTime.Now);
var result = positionList.Select(x =>
{
if (UnSettledTradeIds.Contains(x.TradeId))
{
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(x.UnderlyingCode);
x.CountRatio = um.CountRatio;
x.ContractSize = um.ContractSize;
x.QuoteUnitSingle = um.QuoteUnitString;
x.BBGTicker = um.BBGTicker;
x.UnderlyingPrice = um.Price;
new TradeModule.TradeExtendService(this).SetTradeExtend(new List<trade> { x.tradeOrigin });
if (req.ValueDate != DateTime.Now.Date)
{
x.UnderlyingPrice = underlyingPriceProvider.GetPrice(x.UnderlyingCode, SettlementTypeEnum.ClosePrice);
}
}
var model = new PositionTradeModel()
{
trade = x.trade,
TodayPrice = x.UnderlyingPrice ?? 0,
BBGTicker = x.BBGTicker,
ContractSize = x.ContractSize,
AnnualFee = 0,
Commision = 0,
PriceDate = x.ValueDate ?? DateTime.Now,
UnrealizedPnl = 0,
BuySell = x.trade.trade_swap.PayLongShort == "多头" ? "Buy" : "Sell",
Amount = (x.Lots) ?? 0 * (x.trade.trade_swap.PayLongShort == "多头" ? 1 : -1),
UnwindLots = ((x.trade.OriginalNotional ?? 0) - x.trade.Notional) / x.ContractSize * (x.trade.trade_swap.PayLongShort == "多头" ? -1 : 1)
};
return model;
}).ToList();
foreach (var item in result)
{
item.Amount = item.Amount * (item.BuySell == "Buy" ? 1 : -1);
var eod_trade_position_swap = DbContext.eod_trade_position_swap.FirstOrDefault(o => o.TradeId == item.trade.id && o.ValueDate == req.ValueDate);
if (eod_trade_position_swap != null)
{
item.AnnualFee = eod_trade_position_swap.QuoteAnnualFee;
item.Commision = eod_trade_position_swap.QuoteCommission;
item.UnrealizedPnl = eod_trade_position_swap.QuoteFloatingWinLoss * -1;
item.StlAnnualFee = eod_trade_position_swap.AnnualFee;
item.StlCommision = eod_trade_position_swap.Commission;
item.StlUnrealizedPnl = eod_trade_position_swap.FloatingWinLoss * -1;
}
//平仓未实现
var tc_pres = DbContext.trade_cash_pre.Where(o => o.TradeId == item.trade.id && o.ValueDate > req.ValueDate && o.HappenedDate <= req.ValueDate).ToList();
if (tc_pres != null && tc_pres.Count() > 0)
{
foreach (var tc_pre in tc_pres)
{
//var rate = tradeFlow.Rate ?? 1;
var cash_details = DbContext.trade_cash_detail.Where(o => o.TradeCashPreId == tc_pre.id && o.ValueDate > req.ValueDate).ToList();
item.AnnualFee += cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0);
item.Commision += cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) + cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0);
item.UnrealizedPnl += cash_details.Where(o => o.TradeCashType == "浮动收益").Sum(o => o.QuoteAmount ?? 0) * -1;
}
}
}
return result;
}
/// <summary>
/// 平仓明细
/// </summary>
/// <returns></returns>
private List<UnwindCashModel> clientTradeUnwindQueryList(DingShiReportEmail emailData, IEnumerable<int> userAssetUnits, BoundSideEnum boundSide)
{
var actions = new List<string> { ClientCashInCashOut.系统操作_平仓费 };
var unwindData = from t in DbContext.trade
where t.ClientId == emailData.ClientId && t.TradeDate <= emailData.To && t.ValidState != "InValid"
join tc in DbContext.trade_cash
on t.id equals tc.TradeId
where ((tc.HappenedDate != null && tc.HappenedDate <= emailData.To) || (tc.HappenedDate == null && tc.ValueDate <= emailData.To))
&& tc.ValidState != ConsGlobal.InValid && !tc.IsDeleted
join um in DbContext.underlying_manager
on t.UnderlyingCode equals um.UnderlyingCode
select new UnwindCashModel
{
trade = t,
tc = tc,
BBGTicker = um.BBGTicker,
ContractSize = um.ContractSize,
RealizedPnl = 0,
Commision = 0,
AnnualFee = 0,
Amount = (t.Lots ?? 0) * (tc.UnwindPercentRate ?? 1),
TradeType = "swap",
UnderlyingCode = t.UnderlyingCode,
UnwindPrice = tc.FinalPrice ?? 0,
UnwindDate = tc.HappenedDate ?? tc.ValueDate,
Action = "unwind",
TradeDate = t.TradeDate,
SpotPrice = t.SpotPrice ?? 0,
ExerciseDate = t.ExerciseDate,
};
var tradeIds = unwindData.Select(o => o.trade.id).Distinct().ToList();
if (boundSide == BoundSideEnum.北向)
{
unwindData = unwindData.Where(o => actions.Contains(o.tc.Action));
}
if (boundSide == BoundSideEnum.南向)
{
unwindData = unwindData.Where(o => o.tc.HappenedDate == emailData.To || (o.tc.HappenedDate == null && o.tc.ValueDate == emailData.To));
}
var ret = unwindData.ToList();
if (userAssetUnits != null && userAssetUnits.Count() > 1)
{
ret = ret.Where(o => userAssetUnits.Contains(o.trade.AssetId)).ToList();
}
foreach (var item in ret)
{
var trade_cash_details = DbContext.trade_cash_detail.Where(o => o.TradeCashId == item.tc.id).ToList();
var CloseCommision = trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
var OpenCommision = trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
item.RealizedPnl = (trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Any() ? trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Sum(o => o.QuoteAmount ?? 0) : 0) * -1;
item.Commision = OpenCommision + CloseCommision;
item.AnnualFee = trade_cash_details.Where(o => o.TradeCashType == "利息").Any() ? trade_cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0) : 0;
new TradeModule.TradeExtendService(this).SetTradeExtend(new List<trade> { item.trade });
item.BuySell = item.trade.trade_swap.PayLongShort == "多头" ? "Buy" : "Sell";
item.Amount = item.Amount * (item.BuySell == "Buy" ? 1 : -1);
if (boundSide == BoundSideEnum.南向)
{
item.BuySell = item.BuySell[0].ToString();
item.Rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(item.QuoteCurrency, "CNY", emailData.To);
//var um = DataCacheProvider.GetUnderlyingDataSource().GetData(flow.UnderlyingCode);
if (item.tc.Action == ClientCashInCashOut.系统操作_期权费)
{
item.Action = "open";
var flowId = DbContext.trade_swap.FirstOrDefault(o => o.TradeId == item.tc.TradeId)?.FlowId;
var flow = DbContext.trade_swap_flow.FirstOrDefault(o => o.id == flowId);
item.flowNumber = flow.Number;
item.ExerciseDate = flow.ExerciseDate;
item.CloseDate = flow.SettlementDate;
}
else
{
var flowId = DbContext.trade_cash_swap.FirstOrDefault(o => o.TradeCashId == item.tc.id)?.FlowId;
var flow = DbContext.trade_swap_flow.FirstOrDefault(o => o.id == flowId);
item.flowNumber = flow.Number;
item.ExerciseDate = flow.ExerciseDate;
item.BuySell = item.BuySell == "B" ? "S" : "B";
item.TradeDate = item.UnwindDate;
item.Amount *= -1;
item.SpotPrice = item.tc.FinalPrice ?? 0;
item.CloseDate = flow.SettlementDate;
}
}
}
var tc_pres = DbContext.trade_cash_pre.Where(o => o.HappenedDate <= emailData.To && o.ValueDate > emailData.To && tradeIds.Contains(o.TradeId)).Distinct().ToList();
if (boundSide == BoundSideEnum.南向)
{
tc_pres = tc_pres.Where(o => o.HappenedDate == emailData.To).ToList();
}
foreach (var item in tc_pres)
{
var flowId = DbContext.trade_cash_swap.FirstOrDefault(o => o.TradeCashPreId == item.id)?.FlowId;
var flow = DbContext.trade_swap_flow.FirstOrDefault(o => o.id == flowId);
//如果收完结算日的盘,tradeCash就已经有了,这里避免重复
if (ret.Any(o => o.flowNumber == flow.Number))
{
continue;
}
var t = DbContext.trade.Find(item.TradeId);
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(t.UnderlyingCode);
var unwindCash = new UnwindCashModel
{
trade = t,
tc = null,
BBGTicker = um.BBGTicker,
ContractSize = um.ContractSize,
RealizedPnl = 0,
Commision = 0,
AnnualFee = 0,
Amount = (t.Lots ?? 0) * (item.UnwindPercentRate ?? 1),
TradeType = "swap",
UnderlyingCode = t.UnderlyingCode,
UnwindPrice = item.FinalPrice ?? 0,
UnwindDate = flow.TradeDate ?? DateTime.MinValue,
Action = "unwind",
TradeDate = t.TradeDate,
SpotPrice = t.SpotPrice ?? 0,
ExerciseDate = t.ExerciseDate,
};
var trade_cash_details = DbContext.trade_cash_detail.Where(o => o.TradeCashPreId == item.id).ToList();
var CloseCommision = trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
var OpenCommision = trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
unwindCash.RealizedPnl = (trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Any() ? trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Sum(o => o.QuoteAmount ?? 0) : 0) * -1;
unwindCash.Commision = OpenCommision + CloseCommision;
unwindCash.AnnualFee = trade_cash_details.Where(o => o.TradeCashType == "利息").Any() ? trade_cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0) : 0;
new TradeModule.TradeExtendService(this).SetTradeExtend(new List<trade> { t });
unwindCash.BuySell = t.trade_swap.PayLongShort == "多头" ? "Buy" : "Sell";
unwindCash.Amount = unwindCash.Amount * (unwindCash.BuySell == "Buy" ? 1 : -1);
if (boundSide == BoundSideEnum.南向)
{
unwindCash.BuySell = unwindCash.BuySell[0].ToString();
unwindCash.BuySell = unwindCash.BuySell == "B" ? "S" : "B";
unwindCash.Rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(unwindCash.QuoteCurrency, "CNY", emailData.To);
//var um = DataCacheProvider.GetUnderlyingDataSource().GetData(flow.UnderlyingCode);
unwindCash.flowNumber = flow.Number;
unwindCash.ExerciseDate = flow.ExerciseDate;
unwindCash.TradeDate = unwindCash.UnwindDate;
unwindCash.Amount *= -1;
unwindCash.SpotPrice = item.FinalPrice ?? 0;
unwindCash.CloseDate = flow.SettlementDate;
}
ret.Add(unwindCash);
}
return ret;
}
/// <summary>
/// 客户流水
/// </summary>
private List<TradeFlowModel> clientTradeFlowQueryList(DateTime endDate, IEnumerable<int> userAssetUnits, Client client, bool extendInfo = false, bool canUsePreRate = false)
{
var ret = new List<TradeFlowModel>();
var PriceProvider = new EodPriceProvider(endDate).Initialize().GetPriceProvider();
var flowData = from flow in DbContext.trade_swap_flow
where (flow.StartDate <= endDate && flow.ClientNumber == client.Number)
join swaps in (from swap in DbContext.trade_swap join trade in DbContext.trade on swap.TradeId equals trade.id where trade.ValidState != "InValid" select swap)
on flow.id equals swaps.FlowId
into swaps
from swap in swaps.DefaultIfEmpty()
join eod_trades in DbContext.eod_trade
on swap.TradeId equals eod_trades.TradeId
into eod_trades
from eod_trade in eod_trades.Where(o => o.ValueDate == endDate).DefaultIfEmpty()
join cash_swaps in DbContext.trade_cash_swap
on flow.id equals cash_swaps.FlowId
into cash_swaps
from cash_swap in cash_swaps.DefaultIfEmpty()
join tradeCashPres in DbContext.trade_cash_pre
on swap.TradeId equals tradeCashPres.TradeId
into tradeCashPres
from tradeCashPre in tradeCashPres.Where(o => o.ValueDate > endDate && o.HappenedDate <= endDate).DefaultIfEmpty()
join tradeCashs in DbContext.trade_cash
on cash_swap.TradeCashId equals tradeCashs.id
into tradeCashs
from tradeCash in tradeCashs.DefaultIfEmpty()
join ums in DbContext.underlying_manager
on flow.UnderlyingCode equals ums.UnderlyingCode
into ums
from um in ums.DefaultIfEmpty()
select new
{
flow,
eod_trade,
cash_swap,
swap,
tradeCashPre,
tradeCash,
um
};
var data = flowData.GroupBy(o => o.flow).ToDictionary(o => o.Key, o => o.ToList());
var tradeIds = flowData.Where(o => o.swap != null).Select(o => o.swap.TradeId).ToList();
var notSettledForward = flowData.Where(o => o.tradeCashPre != null).Select(o => o.tradeCashPre.TradeId).ToList();
var trades = DbContext.trade.Where(o => tradeIds.Contains(o.id)).ToList();
var cashDetails_all = DbContext.trade_cash_detail.Where(o => tradeIds.Contains(o.TradeId)).ToList();
var tcs_all = DbContext.trade_cash.Where(o => tradeIds.Contains(o.TradeId) && o.ValueDate <= endDate).ToList();
foreach (var item in data)
{
var variety = DataCacheProvider.GetVariety(item.Key.UnderlyingCode);
var um = item.Value[0].um;
if (um == null)
{
ret.Add(new TradeFlowModel
{
ClientName = client.Name,
id = item.Key.id,
Amount = item.Key.Lots * (item.Key.BuySell == "B" ? 1 : -1),
AnnualRate = 0,
BBGTicker = "",
BuySell = "客户" + (item.Key.BuySell == "B" ? "买入" : "卖出"),
Contract = item.Key.UnderlyingCode,
ContractSize = 0,
QuoteCurrency = "",
ExerciseDate = item.Key.ExerciseDate,
FlowNumber = item.Key.Number,
CloseDate = item.Key.SettlementDate,
SettlementCurrency = client.SettlementCurrency,
UnderlyingCode = item.Key.UnderlyingCode,
TradeDate = item.Key.TradeDate,
TradeType = "swap",
RemainAmount = 0,
RealizedPnl = 0,
});
continue;
}
var eod_trade = item.Value.FirstOrDefault(o => o.eod_trade != null)?.eod_trade;
var cash_swap = item.Value.FirstOrDefault(o => o.cash_swap != null)?.cash_swap;
var swap = item.Value.FirstOrDefault(o => o.swap != null)?.swap;
var tc_pres = item.Value.Where(o => o.tradeCashPre != null).Select(o => o.tradeCashPre).Distinct();
var tradeId = swap != null ? swap.TradeId :
item.Value.Any(o => o.tradeCash != null) ? item.Value.FirstOrDefault(o => o.tradeCash != null).tradeCash.TradeId :
tc_pres.Any() ? tc_pres.FirstOrDefault().TradeId :
cash_swap?.TradeId;
var t = trades.FirstOrDefault(o => o.id == tradeId);
var QCurrency = t != null ? t.QuoteCurrency : variety.QuoteCurrency;
var tradeFlow = new TradeFlowModel()
{
ClientName = client.Name,
id = item.Key.id,
Amount = item.Key.Lots * (item.Key.BuySell == "B" ? 1 : -1),
AnnualRate = 0,
BBGTicker = um.BBGTicker,
BuySell = "客户" + (item.Key.BuySell == "B" ? "买入" : "卖出"),
Contract = item.Key.UnderlyingCode,
ContractSize = um.ContractSize,
QuoteCurrency = QCurrency,
ExerciseDate = item.Key.ExerciseDate,
StartDate = item.Key.StartDate,
FlowNumber = item.Key.Number,
CloseDate = item.Key.SettlementDate,
SettlementCurrency = client.SettlementCurrency,
UnderlyingCode = item.Key.UnderlyingCode,
TradeDate = item.Key.TradeDate,
TradeType = "swap",
RemainAmount = 0,
RealizedPnl = 0,
AnnualFee = 0,
Commision = 0,
QuoteFloatFee = 0,
FloatFee = 0,
IsOpen = false,
};
tradeFlow.FlagExpd = "expired";
//找到开仓那笔的结算日
if (tradeId != null && tradeId != 0)
{
var dic = data.FirstOrDefault(o => o.Value.Any(x => (x.eod_trade != null && x.eod_trade.TradeId == tradeId) || (x.swap != null && x.swap.TradeId == tradeId)));
var stlDate = item.Key.SettlementDate;
if (dic.Key != null)
{
stlDate = dic.Key.SettlementDate;
}
//到结算日才算expired
if (stlDate != null && stlDate > endDate)
{
tradeFlow.FlagExpd = "active";
}
}
tradeFlow.SpotPrice = item.Key.SpotPrice;
if (item.Key.QuoteCurrency != client.SettlementCurrency)
{
tradeFlow.Rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(tradeFlow.QuoteCurrency, client.SettlementCurrency, endDate, canUsePreRate);
tradeFlow.initRate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(tradeFlow.QuoteCurrency, client.SettlementCurrency, tradeFlow.TradeDate ?? DateTime.Now, canUsePreRate);
}
var config = DbContext.client_variety_config.Where(o => o.ClientId == client.id && o.VarietyId == variety.id && o.ValueDate <= item.Key.TradeDate).OrderByDescending(o => o.ValueDate).FirstOrDefault();
if (config == null)
{
throw new ServiceException($"{client.Name} - {variety.ShortName} 在 {item.Key.TradeDate} 无收费配置");
}
tradeFlow.AnnualRate = config.AnnualRate;
if (item.Key.NeedCostFee)
{
tradeFlow.CommisionRate = config.UnAnnualRate == 0 ? config.SingleFee.ToString() : config.UnAnnualRate.OtcFormatPercent();
}
else
{
tradeFlow.CommisionRate = "0";
}
//远期未到期的也要进去
if (eod_trade != null || (swap != null && notSettledForward.Contains(swap.id)))
{
if (eod_trade != null)
{
if (eod_trade.trade.TradeStatus == "确认成交")
{
tradeFlow.FlagExpd = "active";
var eod_trade_position_swap = DbContext.eod_trade_position_swap.FirstOrDefault(o => o.TradeId == eod_trade.TradeId && o.ValueDate == endDate);
if (eod_trade_position_swap != null)
{
tradeFlow.AnnualFee = eod_trade_position_swap.AnnualFee * -1;
tradeFlow.Commision = eod_trade_position_swap.Commission * -1;
tradeFlow.QuoteFloatFee = eod_trade_position_swap.QuoteFloatingWinLoss * -1;
tradeFlow.FloatFee = eod_trade_position_swap.FloatingWinLoss * -1;
tradeFlow.UnrealizedPnl = tradeFlow.AnnualFee + tradeFlow.Commision + tradeFlow.FloatFee;
}
}
tradeFlow.RemainAmount = eod_trade.trade.Notional / um.ContractSize * (item.Key.BuySell == "B" ? 1 : -1);
}
if (tc_pres != null && tc_pres.Count() > 0)
{
foreach (var tc_pre in tc_pres)
{
var rate = tradeFlow.Rate ?? 1;
var cash_details = cashDetails_all.Where(o => o.TradeCashPreId == tc_pre.id && o.ValueDate > endDate).ToList();
var Annual_Fee = cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0);
var Commision = cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) + cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0);
var FloatFee = cash_details.Where(o => o.TradeCashType == "浮动收益").Sum(o => o.QuoteAmount ?? 0);
tradeFlow.AnnualFee += Annual_Fee * rate * -1;
tradeFlow.Commision += Commision * rate * -1;
tradeFlow.QuoteFloatFee += FloatFee * -1;
tradeFlow.FloatFee += FloatFee * rate * -1;
}
tradeFlow.UnrealizedPnl = tradeFlow.AnnualFee + tradeFlow.Commision + tradeFlow.FloatFee;
}
tradeFlow.TodayPrice = PriceProvider.GetPrice(item.Key.UnderlyingCode);
}
if (swap != null)
{
var tcs = tcs_all.Where(o => o.TradeId == swap.TradeId && o.ValueDate <= endDate).ToList();
if (tcs != null && tcs.Count() > 0)
{
tradeFlow.RealizedPnl = tcs.Sum(o => o.Amount) * -1;
}
if (extendInfo)
{
tradeFlow.IsOpen = true;
tradeFlow.AssetName = t.AssetBookName;
tradeFlow.OriginStockEqvNotion = t.OriginalStockEqvNotional ?? 0;
tradeFlow.TradeNumber = t.TradeNumber;
tradeFlow.CommisionSingleFee = config.SingleFee;
tradeFlow.CommisionRateShow = config.UnAnnualRate;
tradeFlow.RemainStockEqvNotion = t.TradeStatus == "确认成交" ? t.StockEqvNotional : 0;
var tcIds = tcs.Select(o => o.id);
var cash_details = DbContext.trade_cash_detail.Where(o => tcIds.Contains(o.TradeCashId) && o.ValueDate <= endDate).ToList();
var Annual_Fee = cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0);
var Commision = cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) + cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0);
tradeFlow.UnwindCommision = Commision;
tradeFlow.UnwindAnnualFee = Annual_Fee;
}
}
ret.Add(tradeFlow);
}
ret = ret.OrderByDescending(o => o.TradeDate).ToList();
return ret;
}
/// <summary>
/// 标的汇总
/// </summary>
private List<PositionUnderlyingModel> getClientUnderlyingPosition(List<PositionTradeModel> swap_position, DateTime endDate)
{
var ret = new List<PositionUnderlyingModel>();
var settlementCurrency = "CNY";
var umDic = swap_position.GroupBy(o => o.UnderlyingCode).ToDictionary(o => o.Key);
foreach (var item in umDic)
{
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.Key);
var variety = DataCacheProvider.GetVariety(item.Key);
var Rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(variety.QuoteCurrency, settlementCurrency, endDate);
var position = new PositionUnderlyingModel()
{
Amount = item.Value.Sum(o => (o.Amount + o.UnwindLots)),
//StockEqvNotional = item.Value.Sum(o => o.trade.StockEqvNotional * Rate),
CloseDate = um.CloseDate,
ContractSize = um.ContractSize,
QuoteCurrency = variety.QuoteCurrency,
Rate = Rate,
UnderlyingCode = um.UnderlyingCode,
UnderlyingName = um.UnderlyingName,
//FloatFee = item.Value.Sum(o => o.StlUnrealizedPnl),
MaturityDate = um.MaturityDate,
QuoteFloatFee = item.Value.Sum(o => o.UnrealizedPnl),
QuoteUnrealized = item.Value.Sum(o => o.UnrealizedPnl - o.Commision - o.AnnualFee),
TodayPrice = item.Value.FirstOrDefault().TodayPrice
};
position.StockEqvNotional = Math.Abs(position.Amount) * position.ContractSize * position.TodayPrice * position.Rate;
position.UnrealizedPnl = position.QuoteUnrealized * Rate;
position.FloatFee = position.QuoteFloatFee * Rate;
ret.Add(position);
}
return ret;
}
/// <summary>
/// 资金明细
/// </summary>
/// <returns></returns>
private CashInCashOutModel SearchListExtendOnly(EntryExitReq req, string SettlementCurrency, string QuotaCurrency, BoundSideEnum side, bool canUsePreRate = false)
{
var result = new CashInCashOutModel();
result.cashes = new List<Cash_Record>();
req.State = "已确认,已结算";
req.Direction = $"入金,出金,其他收入,其他支出";
req.TradeAction =
$"{ClientCashInCashOut.系统操作_行权费},{ClientCashInCashOut.系统操作_平仓费},{ClientCashInCashOut.系统操作_期权费},{ClientCashInCashOut.系统操作_票息},{ClientCashInCashOut.系统操作_互换}";
req.IsMoneyNotEqualsZero = true;
var sList = new EntryExitBLL().SearchListExtendOnly(req);
foreach (var item in sList)
{
var tc = DbContext.trade_cash.Find(item.TradeCashId);
var trade_cash_details = DbContext.trade_cash_detail.Where(o => o.TradeCashId == item.TradeCashId && o.TradeCashId != 0);
var RealizedPnl = (trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Any() ? trade_cash_details.Where(o => o.TradeCashType == "浮动收益").Sum(o => o.QuoteAmount ?? 0) : 0) * -1;
var CloseCommision = trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "了结手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
var OpenCommision = trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Any() ? trade_cash_details.Where(o => o.TradeCashType == "开仓手续费").Sum(o => o.QuoteAmount ?? 0) : 0;
var AnnualFee = trade_cash_details.Where(o => o.TradeCashType == "利息").Any() ? trade_cash_details.Where(o => o.TradeCashType == "利息").Sum(o => o.QuoteAmount ?? 0) : 0;
//北向需要的是USD转CNH的汇率,所以这里倒过来了,相应的用到这个汇率是用的除
var rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(SettlementCurrency, QuotaCurrency, item.HappenDate ?? DateTime.Now, canUsePreRate);//待讨论
result.cashes.Add(new Cash_Record()
{
cash = item,
tc = tc,
AnnualFee = AnnualFee,
Commision = CloseCommision + OpenCommision,
CurrencyRate = rate,
EndBalance = 0,
RealizedPnl = RealizedPnl,
ValueDate = item.HappenDate
});
}
if (side == BoundSideEnum.北向)
{
result.cashes = result.cashes.OrderBy(o => o.ValueDate).ThenBy(o => o.cash.id).ToList();
}
else
{
result.cashes = result.cashes.OrderBy(o => o.OptDate).ThenBy(o => o.ValueDate).ToList();
}
for (var i = 0; i < result.cashes.Count; i++)
{
var item = result.cashes[i];
item.ClientName = req.ClientName;
if (item.tc == null)
{
item.CashInFlow = item.cash.Money ?? 0;
if (item.cash.DirectionType == "支出")
{
item.CashInFlow = Math.Abs(item.CashInFlow) * -1;
item.CashType = "出金";
}
else
{
item.CashInFlow = Math.Abs(item.CashInFlow);
item.CashType = "入金";
}
item.flowNumber = "银行流水";
}
else
{
if (item.tc.Action == ClientCashInCashOut.系统操作_期权费)
{
var flowId = DbContext.trade_swap.FirstOrDefault(o => o.TradeId == item.tc.TradeId)?.FlowId;
item.flowNumber = DbContext.trade_swap_flow.FirstOrDefault(o => o.id == flowId)?.Number;
item.CashType = "期权费";
}
else
{
var flowId = DbContext.trade_cash_swap.FirstOrDefault(o => o.TradeCashId == item.tc.id)?.FlowId;
item.flowNumber = DbContext.trade_swap_flow.FirstOrDefault(o => o.id == flowId)?.Number;
item.CashType = "结算金额";
}
}
if (item.cash.CurrencyCode != SettlementCurrency)
{
//北向需要的是USD转CNH的汇率,所以这里倒过来了,相应的用到这个汇率是用的除
var rate = new EodModule.EodCurrencyRateService(UserInfo).
GetCurrencyRate(SettlementCurrency, item.cash.CurrencyCode, req.HappenDateEnd, canUsePreRate);
item.CashInFlow /= rate;
}
//var TradeCashes = (item.RealizedPnl - item.Commision - item.AnnualFee) / item.CurrencyRate;
item.CashMovement = item.CashInFlow == 0 && item.tc != null ? (item.tc.Amount * -1) : item.CashInFlow;
if (i == 0)
{
item.EndBalance = item.CashMovement;
}
else
{
item.EndBalance = result.cashes[i - 1].EndBalance + item.CashMovement;
}
item.OptDate = item.cash.OptDate;
}
return result;
}
/// <summary>
/// 历史数据
/// </summary>
private ClientDingShiReport_ZJ GetHistoryInfo(ClientDingShiReport_ZJ report)
{
var flowReq = new TradeFlowReq() { ClientIds = new List<int>() { report.client.id }, TradeDateEnd = report.ReportEnd };
var tradeFlowHis = new TradeModule.SwapModule.TradeSwapService(OptUser).SearchFlowHistoryList(flowReq);
var cashReq = new ClientCashInCashOutHistoryReq() { ClientIds = new List<int>() { report.client.id }, HappenDateEnd = report.ReportEnd };
var clientCashes = new ClientCashModule.ClientCashInCashOutHistoryService(OptUser).SearchClientCashInCashOutHistoryList(cashReq);
foreach (var item in tradeFlowHis.rows)
{
report.summaryReportModel.swap_flow.Add(new TradeFlowModel()
{
FlowNumber = item.ContractId,
FlagExpd = item.FlagExpired,
QuoteCurrency = item.QuoteCurrency,
SettlementCurrency = item.SettleCurrency,
TradeDate = item.TradeDate,
ExerciseDate = item.ExpireDate,
CloseDate = item.SettleDate,
BuySell = item.Direction,
PrmDate = item.PremiumDate,
PremCNY = item.PremiumCNY,
TradeType = item.TradeType,
UnderlyingCode = item.UnderlyingCode,
Amount = item.InitialLots,
RemainAmount = item.Lots,
ContractSize = item.Size,
SpotPrice = item.InitialSpotPrice,
TodayPrice = item.SpotPrice,
initRate = item.InitialRate,
Rate = item.Rate,
Commision = item.EstimateCommision,
CommisionRate = item.CommissionRate,
AnnualFee = item.EstimateAnnualFee,
AnnualRate = item.AnnualRate,
FloatFee = item.FloatingWinLoss,
QuoteFloatFee = item.FloatingWinLossQuote,
UnrealizedPnl = item.UnRealizedPnl,
RealizedPnl = item.RealizedPnl
});
}
foreach (var item in clientCashes.rows)
{
report.cash_records.cashes.Add(new Cash_Record()
{
OptDate = item.ValueDate,
ValueDate = item.HappenDate,
flowNumber = item.ContractId,
CashMovement = item.Amount ?? 0,
CashType = item.Action
});
}
return report;
}
public string GenerateFileEntry(ClientDingShiReport_ZJ report)
{
var tempFolder = OtcAppContext.MapPath("~/App_Docs/Temp/结算报告");
var targetPath = string.IsNullOrEmpty(report.downloadFilePath) ? Path.Combine(tempFolder, report.ReportEnd.ToString("yyyyMMdd")) : report.downloadFilePath;
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
var clientName = string.IsNullOrEmpty(report.client.Abbreviation) ? report.client.Name : report.client.Abbreviation;
var fileName = report.ReportFrom == DateTime.MinValue ? $"持仓报告_{report.ReportEnd:yyyyMMdd}_{clientName}" : $"持仓报告_{report.ReportFrom:yyyyMMdd}_{report.ReportEnd:yyyyMMdd}_{clientName}";
var targetFileName = Path.Combine(targetPath, $"{fileName}.xlsx");
var modelDict = new Dictionary<string, object>();
var sourcePath = "";
var sourceFileName = "";
if (report.client.BoundSide == BoundSideEnum.北向)
{
modelDict.Add("Summary", report.summaryReportModel);
modelDict.Add("Holding Details", report.swap_position);
modelDict.Add("Unwind Trade Details", report.swap_unwind);
modelDict.Add("Cash Statement", report.cash_records);
sourcePath = OtcAppContext.MapPath("~/App_Docs/导出模板");
sourceFileName = Path.Combine(sourcePath, "北向估值单模板.xlsx");
}
else
{
modelDict.Add("Report_CptyBalance", report.summaryReportModel);
modelDict.Add("Holdings", report.underlying_positon);
modelDict.Add("Trades_today", report.today_swap);
modelDict.Add("Report_CptyCashFlow", report.cash_records);
sourcePath = OtcAppContext.MapPath("~/App_Docs/导出模板");
sourceFileName = Path.Combine(sourcePath, "南向估值单模板.xlsx");
}
var pdffile = ExcelTemplate.GeneratePDFFromExeclTemplate(sourcePath, sourceFileName, modelDict, targetPath, targetFileName
, shouldDeleteSheet: true, needToPdf: false, callback: new GenerateExcelCallback(this)
{
report = report
}.Callback);
return Path.Combine(targetPath, targetFileName);
}
public string ReplaceWildcard(string input, ClientDingShiReport_ZJ report)
{
if (!string.IsNullOrEmpty(input))
{
input = Regex.Replace(input, @"\{\{(.*?)\}\}", m =>
{
switch (m.Groups[1].Value)
{
case "客户名称": return report.client.Name;
case "客户编号": return report.client.Number;
case "支付截止时间": return QdpCalendarHelper.GetNonHoliday(DateTime.Now < DateTime.Now.Date.AddHours(9).AddMinutes(30) ? DateTime.Now : DateTime.Now.AddDays(1)).ToString("yyyy年MM月dd日") + "上午9:30";
case "追保金额": return report.summaryReportModel.Margin.ToString("0.00");
case "大写追保金额": return NumberHelper.CmycurD(report.summaryReportModel.Margin);
case "应付资金总额": return report.summaryReportModel.PayableFund.ToString("0.00");
case "大写应付资金总额": return NumberHelper.CmycurD(report.summaryReportModel.PayableFund);
case "发送日期": return DateTime.Now.ToString("yyyy-MM-dd");
case "预付金占用": return report.summaryReportModel.MarginRequiement.ToString("0.00");
case "可用资金": return report.summaryReportModel.AvailableFund.ToString("0.00");
case "授信额度": return report.summaryReportModel.Credit.ToString("0.00");
//case "应付了结交易款": return report.FundReportModel.ClosedTradePayableFundString;
//case "应付存续交易款": return report.FundReportModel.PositionTradePayableFundString;
//case "存续交易期权费净额": return report.FundReportModel.PositionPremiumNetCashString;
//case "可取资金": return report.FundReportModel.DesirableFundString;
case "起始日期": return report.ReportFrom.ToString("yyyy-MM-dd");
case "结束日期": return report.ReportEnd.ToString("yyyy-MM-dd");
default: return string.Empty;
}
});
}
return input;
}
class GenerateExcelCallback : YLBaseService
{
public ClientDingShiReport_ZJ report;
public GenerateExcelCallback(YLBaseService baseService) : base(baseService)
{
}
public void Callback(ExcelWorksheets sheets)
{ }
}
public byte[] exportFlowInfo()
{
var endDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
var clients = DbContextFactory.GetClientDbContext(OptUser).client.Where(o => o.BoundSide == BoundSideEnum.南向 && o.ProcessOrderId == -2).ToList();
var result = new List<TradeFlowModel>();
foreach (var item in clients)
{
var clientFlowList = clientTradeFlowQueryList(endDate, null, item, canUsePreRate: true);
result.AddRange(clientFlowList);
}
//客户名称 交易编码 是否到期 计价货币 结算货币 交易日 到期日 交割日(LME Prompt) 客户买/卖
//权利金日 期权费¥ 衍生品类型 标的代码 初始开仓手数 剩余手数 合约乘数 初始价格
//初始汇率 最新价格 最新汇率 佣金费率 预估佣金¥ 年化手续费率 预估年化手续费¥
//浮动收益(计价货币) 浮动收益(结算货币) 未实现收益(结算货币) 已实现收益(结算货币)
var dc = new List<Commons.ExcelHelper.DataColumnModel>
{
new Commons.ExcelHelper.DataColumnModel("客户名称", "ClientName"),
new Commons.ExcelHelper.DataColumnModel("交易编码", "FlowNumber"),
new Commons.ExcelHelper.DataColumnModel("是否到期", "FlagExpd"),
new Commons.ExcelHelper.DataColumnModel("计价货币", "QuoteCurrency"),
new Commons.ExcelHelper.DataColumnModel("结算货币", "SettlementCurrency"),
new Commons.ExcelHelper.DataColumnModel("交易日", "TradeDate"),
new Commons.ExcelHelper.DataColumnModel("到期日", "ExerciseDate"),
new Commons.ExcelHelper.DataColumnModel("交割日(LME Prompt)", "CloseDate"),
new Commons.ExcelHelper.DataColumnModel("客户买/卖", "BuySell"),
new Commons.ExcelHelper.DataColumnModel("权利金日", "PrmDate"),
new Commons.ExcelHelper.DataColumnModel("期权费¥", "PremCNY"),
new Commons.ExcelHelper.DataColumnModel("衍生品类型", "TradeType"),
new Commons.ExcelHelper.DataColumnModel("标的代码", "UnderlyingCode"),
new Commons.ExcelHelper.DataColumnModel("初始开仓手数", "Amount"),
new Commons.ExcelHelper.DataColumnModel("剩余手数", "RemainAmount"),
new Commons.ExcelHelper.DataColumnModel("合约乘数", "ContractSize"),
new Commons.ExcelHelper.DataColumnModel("初始价格", "SpotPrice"),
new Commons.ExcelHelper.DataColumnModel("初始汇率", "initRate"),
new Commons.ExcelHelper.DataColumnModel("最新价格", "TodayPrice"),
new Commons.ExcelHelper.DataColumnModel("最新汇率", "Rate"),
new Commons.ExcelHelper.DataColumnModel("佣金费率", "CommisionRate"),
new Commons.ExcelHelper.DataColumnModel("预估佣金¥", "Commision"),
new Commons.ExcelHelper.DataColumnModel("年化手续费率", "AnnualRate"),
new Commons.ExcelHelper.DataColumnModel("预估年化手续费¥", "AnnualFee"),
new Commons.ExcelHelper.DataColumnModel("浮动收益(计价货币)", "QuoteFloatFee"),
new Commons.ExcelHelper.DataColumnModel("浮动收益(结算货币)", "FloatFee"),
new Commons.ExcelHelper.DataColumnModel("未实现收益(结算货币)", "UnrealizedPnl"),
new Commons.ExcelHelper.DataColumnModel("已实现收益(结算货币)", "RealizedPnl"),
};
new Commons.ExcelHelper().ListToExcel<TradeFlowModel>(dc.ToArray(), result, "Sheet1", true, out var buffer);
return buffer;
}
public byte[] exportCashInfo()
{
var endDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
var clients = DbContextFactory.GetClientDbContext(OptUser).client.Where(o => o.BoundSide == BoundSideEnum.南向 && o.ProcessOrderId == -2).ToList();
var result = new List<Cash_Record>();
foreach (var item in clients)
{
var req = new EntryExitReq() { ClientId = item.id, HappenDateEnd = endDate, ClientName = item.Name };
var cashRet = SearchListExtendOnly(req, item.SettlementCurrency, "CNY", item.BoundSide, true);
result.AddRange(cashRet.cashes);
}
var dc = new List<Commons.ExcelHelper.DataColumnModel>
{
new Commons.ExcelHelper.DataColumnModel("客户名称", "ClientName"),
new Commons.ExcelHelper.DataColumnModel("记录日期", "OptDate"),
new Commons.ExcelHelper.DataColumnModel("发生日期", "ValueDate"),
new Commons.ExcelHelper.DataColumnModel("资金金额", "CashMovement"),
new Commons.ExcelHelper.DataColumnModel("资金科目", "CashType"),
new Commons.ExcelHelper.DataColumnModel("交易编码", "flowNumber"),
};
new Commons.ExcelHelper().ListToExcel<Cash_Record>(dc.ToArray(), result, "Sheet1", true, out var buffer);
return buffer;
}
public byte[] exportOpenFlow()
{
var clients = DbContextFactory.GetClientDbContext(OptUser).client.Where(o => o.ProcessOrderId == -2).ToList();
var result = new List<TradeFlowModel>();
foreach (var item in clients)
{
var endDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
var clientFlowList = clientTradeFlowQueryList(endDate, null, item, true, true).Where(o => o.IsOpen).ToList();
clientFlowList.ForEach(o => o.boundSide = item.BoundSide);
result.AddRange(clientFlowList);
}
var dc = new List<Commons.ExcelHelper.DataColumnModel>
{
//资金流向 簿记账户 交易状态 结构类型 流水编号 合约编号 客户名称
//计价货币 标的 初始名义本金 期初数量 交易日期 开始日期 到期日期
//结算日 期初价格 佣金费率 年化手续费率 交易方向 结算货币
//合约乘数 初始汇率 预估佣金(结算) 实收佣金(结算) 预估年化手续费(结算)
//实收年化手续费(结算) 剩余数量 未实现收益(结算货币) 已实现盈亏(结算) 剩余名义本金(结算)
new Commons.ExcelHelper.DataColumnModel("资金流向", "BoundSideDesc"),
new Commons.ExcelHelper.DataColumnModel("簿记账户", "AssetName"),
new Commons.ExcelHelper.DataColumnModel("交易状态", "FlagExpd"),
new Commons.ExcelHelper.DataColumnModel("结构类型", "TradeType"),
new Commons.ExcelHelper.DataColumnModel("流水编号", "FlowNumber"),
new Commons.ExcelHelper.DataColumnModel("合约编号", "TradeNumber"),
new Commons.ExcelHelper.DataColumnModel("客户名称", "ClientName"),
new Commons.ExcelHelper.DataColumnModel("计价货币", "QuoteCurrency"),
new Commons.ExcelHelper.DataColumnModel("标的", "UnderlyingCode"),
new Commons.ExcelHelper.DataColumnModel("初始名义本金", "OriginStockEqvNotion"),
new Commons.ExcelHelper.DataColumnModel("初始开仓手数", "Amount"),
new Commons.ExcelHelper.DataColumnModel("交易日期", "TradeDate"),
new Commons.ExcelHelper.DataColumnModel("开始日期", "StartDate"),
new Commons.ExcelHelper.DataColumnModel("到期日期", "ExerciseDate"),
new Commons.ExcelHelper.DataColumnModel("结算日", "CloseDate"),
new Commons.ExcelHelper.DataColumnModel("期初价格", "SpotPrice"),
new Commons.ExcelHelper.DataColumnModel("佣金费率", "CommisionRateShow"),
new Commons.ExcelHelper.DataColumnModel("佣金单手费用", "CommisionSingleFee"),
new Commons.ExcelHelper.DataColumnModel("年化手续费率", "AnnualRate"),
new Commons.ExcelHelper.DataColumnModel("交易方向", "BuySell"),
new Commons.ExcelHelper.DataColumnModel("结算货币", "SettlementCurrency"),
new Commons.ExcelHelper.DataColumnModel("合约乘数", "ContractSize"),
new Commons.ExcelHelper.DataColumnModel("预估佣金(结算)", "Commision"),
new Commons.ExcelHelper.DataColumnModel("实收佣金(结算)", "UnwindCommision"),
new Commons.ExcelHelper.DataColumnModel("初始汇率", "initRate"),
new Commons.ExcelHelper.DataColumnModel("预估年化手续费(结算) ", "AnnualFee"),
new Commons.ExcelHelper.DataColumnModel("实收年化手续费(结算) ", "UnwindAnnualFee"),
new Commons.ExcelHelper.DataColumnModel("剩余数量", "RemainAmount"),
new Commons.ExcelHelper.DataColumnModel("未实现收益(结算货币)", "UnrealizedPnl"),
new Commons.ExcelHelper.DataColumnModel("已实现收益(结算货币)", "RealizedPnl"),
new Commons.ExcelHelper.DataColumnModel("剩余名义本金", "RemainStockEqvNotion"),
};
new Commons.ExcelHelper().ListToExcel<TradeFlowModel>(dc.ToArray(), result, "Sheet1", true, out var buffer);
return buffer;
}
public byte[] exportClientCashRemian(DateTime reportDate)
{
var clients = DbContextFactory.GetClientDbContext(OptUser).client.Where(o => o.ProcessOrderId == -2).ToList();
var lastBalanceDate = BLL.Eod.EodOperationBase.GetLastSettlementDate(reportDate);
var clientRemians = new List<clientCashRemian>();
var balances = DbContext.ClientBalanceDaily.Where(o => o.BalanceDate == reportDate).ToArray();
foreach (var client in clients)
{
var dic = new Dictionary<string, double>();
if (reportDate <= lastBalanceDate)
{
var balance = balances.FirstOrDefault(o => o.ClientId == client.id);
if (balance != null)
{
var fundObject = JsonConvert.DeserializeObject<FundObject>(balance.FundJson);
dic = fundObject.TodayRemainFund;
}
}
else
{
dic = new EntryExitBLL().getClientCash(client.id);
}
if (dic != null && (dic.ContainsKey("USD") || dic.ContainsKey("CNY")))
{
clientRemians.Add(new clientCashRemian
{
ClientNumber = client.Number,
ClientName = client.Name,
RemainUSD = dic["USD"],
RemainRMB = dic["CNY"],
reportDateStr = reportDate.ToString("yyyy-MM-dd"),
});
}
}
var dc = new List<Commons.ExcelHelper.DataColumnModel>
{
new Commons.ExcelHelper.DataColumnModel("客户名称", "ClientName"),
new Commons.ExcelHelper.DataColumnModel("客户编码", "ClientNumber"),
new Commons.ExcelHelper.DataColumnModel("日终余额USD", "RemainUSD"),
new Commons.ExcelHelper.DataColumnModel("日终余额CNY", "RemainRMB"),
new Commons.ExcelHelper.DataColumnModel("日期", "reportDateStr"),
};
new Commons.ExcelHelper().ListToExcel<clientCashRemian>(dc.ToArray(), clientRemians, "Sheet1", true, out var buffer);
return buffer;
}
private class clientCashRemian
{
public string ClientName { get; set; }
public string ClientNumber { get; set; }
public double RemainUSD { get; set; }
public double RemainRMB { get; set; }
public string reportDateStr { get; set; }
}
}
}