从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,452 @@
|
||||
using BaseOUDAL;
|
||||
using YLErp.Abstract.DataProviders;
|
||||
using YLErp.BLL;
|
||||
using YLErp.Helpers;
|
||||
using YLErp.Model;
|
||||
using YLErp.Modules.CalculationModule;
|
||||
using YLErp.Modules.DataProviderModule;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
using YLErp.Office;
|
||||
using YLErp.QdpModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule.QueryModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 东证日终存续交易导出服务
|
||||
/// </summary>
|
||||
public class DongZhengEodTradePositionExportService : YLBaseService
|
||||
{
|
||||
public DongZhengEodTradePositionExportService(OptUserInfo optUser) : base(optUser)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void ExportDongZhengZipFile(DateTime valueDate)
|
||||
{
|
||||
|
||||
if (QdpCalendarHelper.GetNonHoliday(valueDate) != valueDate)
|
||||
{
|
||||
throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'不是交易日!");
|
||||
}
|
||||
|
||||
if (!DbContext.eodStatus.Any(n => n.ValueDate == valueDate && n.Status == "已收盘"))
|
||||
{
|
||||
throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'未收盘!");
|
||||
}
|
||||
|
||||
List<eod_position_dz> eods = GetEodPosition(valueDate);
|
||||
List<client_dz> clients = GetClients(valueDate);
|
||||
|
||||
var dateStr = valueDate.ToString("yyyyMMdd");
|
||||
var fileName = $"RH_Otc_Option_List.{dateStr}";
|
||||
|
||||
var zipFileName = $"{fileName}.zip";
|
||||
|
||||
var targetPath = Path.Combine("F:");
|
||||
if (!Directory.Exists(targetPath))
|
||||
{
|
||||
targetPath = Path.Combine("D:\\list\\wait", dateStr);
|
||||
if (!Directory.Exists(targetPath))
|
||||
{
|
||||
Directory.CreateDirectory(targetPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetPath = Path.Combine("F:\\list\\wait", dateStr);
|
||||
if (!Directory.Exists(targetPath))
|
||||
{
|
||||
Directory.CreateDirectory(targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
var marketZipFile = Path.Combine(targetPath, zipFileName);
|
||||
if (File.Exists(marketZipFile))
|
||||
{
|
||||
File.Delete(marketZipFile);
|
||||
}
|
||||
|
||||
var excelFileName = $"{fileName}.xlsx";
|
||||
var targetFileName = Path.Combine(targetPath, excelFileName);
|
||||
var path = Path.Combine(targetPath, targetFileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
var modelDict = new Dictionary<string, object>();
|
||||
if (eods != null)
|
||||
{
|
||||
modelDict.Add("存续交易", eods);
|
||||
}
|
||||
if (clients != null)
|
||||
{
|
||||
modelDict.Add("客户信息", clients);
|
||||
}
|
||||
|
||||
var sourcePath = OtcAppContext.MapPath("~/App_Docs/导出模板");
|
||||
var sourceFileName = Path.Combine(sourcePath, "东证RH_Otc_Option_List.xlsx");
|
||||
var pdffile = ExcelTemplate.GeneratePDFFromExeclTemplate(sourcePath, sourceFileName, modelDict, targetPath, targetFileName, shouldDeleteSheet: true, needToPdf: false);
|
||||
ZipHelper.zipOnlyFile(pdffile, marketZipFile, "Dzrh@2022");
|
||||
File.Delete(targetFileName);
|
||||
}
|
||||
|
||||
private List<eod_position_dz> GetEodPosition(DateTime valueDate)
|
||||
{
|
||||
using (var basedb = new ErpBaseContext())
|
||||
{
|
||||
EodPriceProvider eodPrice = new EodPriceProvider(valueDate, isDiviendPrice: false);
|
||||
eodPrice.Initialize();
|
||||
double riskFreeRate = (valuedateBLL.SystemDate.RiskFreeRate / 100).Normalize();
|
||||
IEodVolProvider eodVolProvider = EodVolProviderFactory.GetEodVolProvider(valueDate, "持仓");
|
||||
List<trade> otcTrades = OtcTrades(valueDate);
|
||||
|
||||
var eodTradeQuery = DbContext.eod_trade.Where(et => et.ValueDate == valueDate && et.TradeId > 0 && et.TradeType != "结构化交易" && et.ClientId > 0 && ConsTrade.NeedMarginTradeStatusList.Contains(et.TradeStatus));
|
||||
|
||||
var query = from trade in eodTradeQuery
|
||||
join tradeOrigin in DbContext.trade on trade.TradeId equals tradeOrigin.id
|
||||
join po in DbContext.eod_trade_position.Where(x => x.ValueDate == valueDate) on trade.TradeId equals po.TradeId into position
|
||||
from po in position.DefaultIfEmpty()
|
||||
where (tradeOrigin.TradeType != "结构化交易" && tradeOrigin.IsGroup != 1 || tradeOrigin.IsGroup == 1 && tradeOrigin.TradeType == "结构化交易")
|
||||
&& (tradeOrigin.IsGroup != 2 || tradeOrigin.IsGroup == 2 && tradeOrigin.TradeType == "收益互换")
|
||||
&& tradeOrigin.ValidState != ConsGlobal.InValid
|
||||
select new eod_position_dz
|
||||
{
|
||||
TradeId = tradeOrigin.id,
|
||||
TradeType = tradeOrigin.IsGroup == 1 ? tradeOrigin.StructureType : tradeOrigin.TradeType,
|
||||
ClientId = tradeOrigin.ClientId,
|
||||
TradeNumber = tradeOrigin.TradeNumber,
|
||||
TradeDate = tradeOrigin.TradeDate,
|
||||
ExerciseDate = tradeOrigin.ExerciseDate,
|
||||
PrincipalRate = tradeOrigin.PrincipalRate ?? 0,
|
||||
BasisUnderlyingCode = tradeOrigin.BasisUnderlyingCode,
|
||||
BasisGap = tradeOrigin.BasisGap ?? 0,
|
||||
Lots = tradeOrigin.Lots ?? 0,
|
||||
ParticipationRate = tradeOrigin.ParticipationRate ?? 0,
|
||||
NoRiskRate = tradeOrigin.NoRiskRate ?? 0,
|
||||
UnderlyingCode = trade.UnderlyingCode,
|
||||
UnderlyingPrice = null,
|
||||
ValueDate = valueDate,
|
||||
TradeJson = trade.TradeJson,
|
||||
PvDouble = 0,
|
||||
PnlDouble = 0,
|
||||
InstrumentType = tradeOrigin.UnderlyingInstrumentType,
|
||||
IsGroup = tradeOrigin.IsGroup,
|
||||
SettlementType = tradeOrigin.SettlementType,
|
||||
Margin = po == null ? 0 : po.Margin,
|
||||
Pv = po == null ? 0 : PS.Config.IsPVRounded ? po.RoundedPv : po.Pv,
|
||||
};
|
||||
|
||||
var queryList = query.ToList();
|
||||
|
||||
var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource();
|
||||
var varietyDataSource = DataCacheProvider.GetVarietyDataSource();
|
||||
var clients = DataCacheProvider.GetClientDataSource();
|
||||
|
||||
var varietyTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "品种类型" select i).ToList();
|
||||
var assetTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "资产类型" select i).ToList();
|
||||
GetUpDownLimitPrices(otcTrades, eodPrice, out IPriceProvider upLimitPrices, out IPriceProvider downLimitPrices);
|
||||
|
||||
foreach (var x in queryList)
|
||||
{
|
||||
var um = underlyingDataSource.GetData(x.UnderlyingCode);
|
||||
|
||||
if (um != null)
|
||||
{
|
||||
if (um.IsSynthetic())
|
||||
{
|
||||
var sy = underlyingDataSource.GetSyntheticUnderlying(x.UnderlyingCode);
|
||||
if (sy != null)
|
||||
{
|
||||
x.SyntheticUnderlyingTipsInfo = sy.UnderlyingTipsInfo;
|
||||
}
|
||||
}
|
||||
var va = varietyDataSource.GetData(um.UnderlyingTypeId);
|
||||
if (va != null)
|
||||
{
|
||||
x.underingName = um.MarketCode != null ? va.VarietyCode + "." + um.MarketCode : va.VarietyCode;
|
||||
x.varietyType = formatDictItem(varietyTypeList, va.AssetType);
|
||||
x.assType = formatDictItem(assetTypeList, va.AssetType, "O");
|
||||
}
|
||||
}
|
||||
|
||||
if (x.TradeType == "收益互换")
|
||||
{
|
||||
x.toolType = "SW";
|
||||
}
|
||||
else if (x.TradeType == "远期" || x.TradeType == "掉期")
|
||||
{
|
||||
x.toolType = "FW";
|
||||
}
|
||||
else
|
||||
{
|
||||
x.toolType = "OP";
|
||||
}
|
||||
|
||||
if (eodPrice.TryGetPrice(x.UnderlyingCode, x.SettlementType, out var price))
|
||||
{
|
||||
x.UnderlyingPrice = price;
|
||||
}
|
||||
|
||||
var client = clients.GetData(x.ClientId ?? 0);
|
||||
if (client != null)
|
||||
{
|
||||
x.ClientName = client.Name;
|
||||
x.clientNumber = client.Number;
|
||||
x.ClientType = client.CustomerNature2 != null && !client.CustomerNature2.Contains("产业客户") ? "其他客户" : "产业客户";
|
||||
//增加内部客户属性 进行赋值
|
||||
x.IsInsided = client.IsInsided;
|
||||
}
|
||||
|
||||
x.dic = x.trade.MetaDic;
|
||||
|
||||
if (x.TradeType == "现金流交易")
|
||||
{
|
||||
x.trade.OriginalNotional = null;
|
||||
}
|
||||
|
||||
x.buyType = x.BuySell == "买入" ? "买" : "卖";
|
||||
x.isEnd = "否";
|
||||
x.tradeType2 = x.OptionType == "看涨" ? "C" : x.OptionType == "看跌" ? "P" : "0";
|
||||
|
||||
var td = otcTrades.FirstOrDefault(t => t.id == x.TradeId);
|
||||
if (td.TradeType != "自定义交易")
|
||||
{
|
||||
var upValue = CalcLiveOtcTradeValueR(valueDate, td, upLimitPrices, eodVolProvider, riskFreeRate);
|
||||
var downValue = CalcLiveOtcTradeValueR(valueDate, td, downLimitPrices, eodVolProvider, riskFreeRate);
|
||||
x.MaximumLoss = Math.Min(PS.Config.IsPVRounded ? upValue.RoundedPv : upValue.Pv, PS.Config.IsPVRounded ? downValue.RoundedPv : downValue.Pv) + x.TradePrice;
|
||||
}
|
||||
}
|
||||
//去除内部客户交易
|
||||
queryList = queryList.Where(l => l.IsInsided != 1).ToList();
|
||||
return queryList;
|
||||
}
|
||||
}
|
||||
|
||||
private List<client_dz> GetClients(DateTime valueDate, IEnumerable<int> clienIds = null)
|
||||
{
|
||||
using (var baseDb = new ClientDBContext())
|
||||
{
|
||||
var clientQuery = from client in baseDb.client.Where(n => n.ProcessStatus == "已开户" && n.IsInsided != 1)
|
||||
select new client_dz
|
||||
{
|
||||
id = client.id,
|
||||
ProtocolSignDate = client.ProtocolSignDate,
|
||||
LicenseCode = client.LicenseCode,
|
||||
Number = client.Number,
|
||||
Name = client.Name,
|
||||
ClientType = client.CustomerNature2
|
||||
};
|
||||
|
||||
var creditList = DbContext.credit.Where(t => t.ProcessStatus == "已审批" && (!t.CreditDeadLine.HasValue || t.CreditDeadLine >= valueDate) && (!t.CreditStartDate.HasValue || t.CreditStartDate <= valueDate));
|
||||
|
||||
if (clienIds != null)
|
||||
{
|
||||
clientQuery = clientQuery.Where(t => clienIds.Contains(t.id));
|
||||
}
|
||||
|
||||
var list = clientQuery.ToList();
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
item.ClientType = item.ClientType != null && !item.ClientType.Contains("产业客户") ? "其他客户" : "产业客户";
|
||||
var credit = creditList?.FirstOrDefault(x => x.ClientId == item.id);
|
||||
item.isCredit = credit != null ? "是" : "否";
|
||||
item.CreditNumber = credit != null ? credit.Credit : null;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private static string formatDictItem(List<DictionaryItem> dictItemMap, string name, string defaultValue = "")
|
||||
{
|
||||
if (name == null || dictItemMap == null) { return defaultValue; }
|
||||
var obj = dictItemMap.FirstOrDefault(O => O.Name == name);
|
||||
return obj == null ? defaultValue : obj.ShortName;
|
||||
}
|
||||
|
||||
private TradeValueResult CalcLiveOtcTradeValueR(DateTime valueDate, trade td, IPriceProvider eodPrice, IEodVolProvider volProvider, double riskFreeRate)
|
||||
{
|
||||
var underlyings = new underlying_manager[] { new underlying_manager { UnderlyingCode = td.UnderlyingCode } };
|
||||
|
||||
var spotPrice = eodPrice.GetPrice(td.UnderlyingCode);
|
||||
|
||||
switch (td.TradeType)
|
||||
{
|
||||
case ConsGlobal.TradeType.Forward:
|
||||
{
|
||||
if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD && !string.IsNullOrWhiteSpace(td.BasisUnderlyingCode))
|
||||
{
|
||||
var BasiseodPrice = eodPrice.GetPrice(td.BasisUnderlyingCode);
|
||||
spotPrice -= BasiseodPrice;
|
||||
}
|
||||
return ForwardradeCalcService.CalcValue(td, spotPrice);
|
||||
}
|
||||
case ConsGlobal.TradeType.PayoffSwap:
|
||||
return PayoffSwapCalcService.CalcValue(td, valueDate, eodPrice, true);
|
||||
default:
|
||||
{
|
||||
var req = new OptionValueCalcRequest(riskFreeRate)
|
||||
{
|
||||
correlations = null,//不计算彩虹等多标的期权暂时不需要
|
||||
engineName = null,
|
||||
preciseTimeMode = false, //日终一定是false
|
||||
isEodCalc = true,
|
||||
pricingRequest = QdpPricingRequest.BASIC_GREEKS,
|
||||
spotPrices = new[] { spotPrice },
|
||||
calcScenario = Enums.CalcScenarioEnum.EodSettlement,
|
||||
};
|
||||
if (td.TradeType != ConsGlobal.TradeType.CashFlow)
|
||||
{
|
||||
var vol = volProvider.GetVol(td, spotPrice) ?? ConsGlobal.DefaultVol;
|
||||
|
||||
req.vols = new[] { vol };
|
||||
}
|
||||
return OptionCalculatorV2.GetOptionValueResult(valueDate, td, req, out underlyings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取涨跌20%停价格字典
|
||||
/// </summary>
|
||||
private void GetUpDownLimitPrices(List<trade> trade, EodPriceProvider eodPrice, out IPriceProvider upLimitPrices, out IPriceProvider downLimitPrices)
|
||||
{
|
||||
HashSet<string> _underlyingCodeSet;
|
||||
|
||||
_underlyingCodeSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
void setUnderlyingCode(trade td)
|
||||
{
|
||||
if (td?.UnderlyingCode == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_underlyingCodeSet.Add(td.UnderlyingCode);
|
||||
switch (td.TradeType)
|
||||
{
|
||||
case "彩虹期权":
|
||||
if (td.trade_rainbow_option != null)
|
||||
{
|
||||
_underlyingCodeSet.Add(td.trade_rainbow_option.UnderlyingAssetCode2);
|
||||
}
|
||||
break;
|
||||
case "价差期权":
|
||||
if (td.trade_spread_option != null)
|
||||
{
|
||||
var codes = td.trade_spread_option.UnderlyingAssetCodes();
|
||||
foreach (var code in codes)
|
||||
{
|
||||
_underlyingCodeSet.Add(code);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "结构化交易":
|
||||
if (td.SubTrades != null)
|
||||
{
|
||||
foreach (var std in td.SubTrades)
|
||||
{
|
||||
setUnderlyingCode(std);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var td in trade)
|
||||
{
|
||||
setUnderlyingCode(td);
|
||||
}
|
||||
|
||||
var upLimitPrices2 = new ManualPriceProvider();
|
||||
var downLimitPrices2 = new ManualPriceProvider();
|
||||
|
||||
//根据涨跌幅限制以及当日结算价计算涨停价以及跌停价
|
||||
foreach (var code in _underlyingCodeSet)
|
||||
{
|
||||
if (eodPrice.TryGetPrice(code, SettlementTypeEnum.ClosePrice, out var price))
|
||||
{
|
||||
var limit = price * 0.2;
|
||||
var upprice = price + limit;
|
||||
var downprice = price - limit;
|
||||
upLimitPrices2.SetPrice(code, upprice);
|
||||
downLimitPrices2.SetPrice(code, downprice);
|
||||
}
|
||||
}
|
||||
|
||||
upLimitPrices = upLimitPrices2;
|
||||
downLimitPrices = downLimitPrices2;
|
||||
}
|
||||
|
||||
TradeCashDataProvider _tradeCashProvider;
|
||||
|
||||
private List<trade> OtcTrades(DateTime valueDate)
|
||||
{
|
||||
//如果前一天是假日,要显示包含假日的交易
|
||||
var preday = BLL.valuedateBLL.GetNonHolidayDefore(valueDate.AddDays(-1));
|
||||
|
||||
var predicate = PredicateBuilder.Create<trade>(t => t.TradeDate <= valueDate && t.ValidState != ConsGlobal.InValid && t.ClientId > 0
|
||||
&& t.TradeType != "结构化交易" && t.ExerciseDate > preday && (!ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus) || t.UnWindDate > preday));
|
||||
|
||||
var list = new EodSettleDataQueryService(UserInfo)
|
||||
.GetOtcTrades(valueDate, predicate, out _tradeCashProvider);
|
||||
|
||||
var hisDataProvider = new TradeHisDataProvider(valueDate).Initialize();
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
var noRiskRate = hisDataProvider.GetNoRiskRate(item.id);
|
||||
var dividendRate = hisDataProvider.GetDividendRate(item.id);
|
||||
//如果修改过无风险利率或分红率,且和eodTrade中不匹配,则移除该交易来自EodTrade的标记;
|
||||
if (((noRiskRate ?? 0) > 0 && noRiskRate.GetValueOrDefault() != item.NoRiskRate.GetValueOrDefault()) ||
|
||||
((dividendRate ?? 0) > 0 && dividendRate.GetValueOrDefault() != item.DividendRate.GetValueOrDefault()))
|
||||
{
|
||||
item.MetaDic.Remove("from_eod_trade");
|
||||
}
|
||||
item.NoRiskRate = noRiskRate ?? item.NoRiskRate ?? BLL.valuedateBLL.RiskFreeRate;
|
||||
item.DividendRate = dividendRate ?? item.DividendRate;
|
||||
if (item.DividendRate == null)
|
||||
{
|
||||
item.DividendRate = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.DividendRate ?? item.NoRiskRate;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public class eod_position_dz : eod_position
|
||||
{
|
||||
public string clientNumber { set; get; }
|
||||
public string ClientType { get; set; }
|
||||
|
||||
public string buyType { get; set; }
|
||||
public string isEnd { get; set; }
|
||||
public string tradeType2 { get; set; }
|
||||
public string varietyType { get; set; }
|
||||
public string assType { get; set; }
|
||||
public string toolType { get; set; }
|
||||
public string underingName { get; set; }
|
||||
/// <summary>
|
||||
/// 最大亏损
|
||||
/// </summary>
|
||||
public double? MaximumLoss { set; get; }
|
||||
/// <summary>
|
||||
/// 内部客户
|
||||
/// </summary>
|
||||
public int? IsInsided { get; set; }
|
||||
}
|
||||
|
||||
public class client_dz
|
||||
{
|
||||
public int id { get; set; }
|
||||
public DateTime? ProtocolSignDate { get; set; }
|
||||
public string LicenseCode { get; set; }
|
||||
public string Number { set; get; }
|
||||
public string Name { set; get; }
|
||||
public string ClientType { get; set; }
|
||||
public string isCredit { set; get; }
|
||||
public double? CreditNumber { set; get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user