从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,362 @@
|
||||
using YLErp.Modules.CalculationModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule.SettlementModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 方顿日终数据接口服务
|
||||
/// </summary>
|
||||
public class FangDunSettlementService : YLBaseService
|
||||
{
|
||||
public FangDunSettlementService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取方顿日终数据1
|
||||
/// </summary>
|
||||
public List<ResponseTrade> GetEodData1(FangDunEodData1Request req)
|
||||
{
|
||||
var handleTrades = (from tp in DbContext.eod_trade_position.Where(l => l.ValueDate == req.ValueDate && l.TradeId > 0)
|
||||
join tr in DbContext.eod_trade_risk.Where(l => l.ValueDate == req.ValueDate) on tp.TradeId equals tr.TradeId
|
||||
join x in DbContext.trade.Where(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2) on tp.TradeId equals x.id
|
||||
join tbo in DbContext.trade_barrier_option on tp.TradeId equals tbo.TradeId
|
||||
into tbo
|
||||
from tbo2 in tbo.DefaultIfEmpty()
|
||||
join tao in DbContext.trade_asian_option on tp.TradeId equals tao.TradeId
|
||||
into tao
|
||||
from tao2 in tao.DefaultIfEmpty()
|
||||
join ta in DbContext.trade_autocall on tp.TradeId equals ta.TradeId
|
||||
into ta
|
||||
from ta2 in ta.DefaultIfEmpty()
|
||||
join ts in DbContext.trade_snowball on tp.TradeId equals ts.TradeId
|
||||
into ts
|
||||
from ts2 in ts.DefaultIfEmpty()
|
||||
select new HandleTrade
|
||||
{
|
||||
tradeModel = x,
|
||||
trade_Asian_Option = tao2,
|
||||
TraderId = tp.TradeId,
|
||||
UnderlyingCode = tp.UnderlyingCode,
|
||||
TradeType = tp.TradeType,
|
||||
ordid = x.ParentTradeId == 0 ? x.TradeNumber : DbContext.trade.FirstOrDefault(c => (c.id == x.ParentTradeId && c.TradeType == "结构化交易")).TradeNumber,
|
||||
groupid = "10038801",
|
||||
sub_ordid = x.ParentTradeId == 0 ? "0" : x.TradeNumber.Substring(x.TradeNumber.IndexOf("-") + 1),
|
||||
effective_date_from = x.TradeDate,
|
||||
effective_date_to = x.ExerciseDate,
|
||||
ClientId = x.ClientId,
|
||||
ordname = tp.UnderlyingCode + "-" + (x.OptionType == "看涨" ? "Call" : "Put"),
|
||||
contract_type_cls = x.TradeType,
|
||||
long_short_position_cls = x.BuySell == "买入" ? "L" : "S",
|
||||
put_call_cls = x.OptionType == "看涨" ? "C" : "P",
|
||||
settlement_type_cls = "C",
|
||||
exercise_type_cls = x.ExerciseMode == "European" ? "1" : "2",
|
||||
strike_price = x.Strike,
|
||||
settlement_currency = "CNY",
|
||||
pricing_currency = "CNY",
|
||||
start_date = x.TradeDate,
|
||||
maturity_date = x.ExerciseDate,
|
||||
premium_amt = x.TradePrice,
|
||||
premium_date = x.PremiumPayDate,
|
||||
participation_rate = x.ParticipationRate,
|
||||
levelpercentage = 0,
|
||||
calendar_type_cls = "2",
|
||||
counterparty_name = x.ClientName,
|
||||
businessday_convention_cls = "2",
|
||||
calcrules_cls = "4",
|
||||
single_multi_cls = "1",
|
||||
weight_calc_cls = "1",
|
||||
additionalproduct_type = x.TradeType == "香草期权" ? "普通期权" : "奇异期权",
|
||||
dis_rate = x.DividendRate,
|
||||
underlying_stkcode = tp.UnderlyingCode,
|
||||
caihua_setype0_cls = "5",
|
||||
initial_spot = x.SpotPrice,
|
||||
weight_rate = 1,
|
||||
div_rate = x.DividendRate,
|
||||
vol_rate = tr.Vol,
|
||||
fund_rate = x.DividendRate,
|
||||
barrierType = tbo2.BarrierType,
|
||||
barrier_value = tbo2.BarrierPrice,
|
||||
rebate_rate = tbo2.Rebate,
|
||||
IsMoneynessOption = x.IsMoneynessOption,
|
||||
KOBarrier = ta2.KOBarrier,
|
||||
KIBarrier = ta2.KIBarrier,
|
||||
coupon_rate = ts2.KORebate,
|
||||
observationdate_list = x.ObservationDateStr,
|
||||
obsfreq = "每日",//todo 每日
|
||||
PayoffType = tao2.PayoffType,
|
||||
notional = tp.Amount * x.SpotPrice,
|
||||
margin = x.MarginRate,
|
||||
float_profit_loss = tp.PositionPnL,
|
||||
accu_profit_loss = tp.ClosedPnL,
|
||||
npv = tp.Pv,
|
||||
delta = tr.Delta,
|
||||
gamma = tr.Gamma,
|
||||
theta = tr.Theta,
|
||||
vega = tr.Vega,
|
||||
rho = tr.Rho * 100,
|
||||
settle_date = x.SettlementDate.ToString(),
|
||||
volume = tp.Amount,
|
||||
cashdelta = tr.DeltaCash,
|
||||
current_value = (x.TradeSinglePrice),
|
||||
market_value = (tp.Amount * x.TradeSinglePrice) ?? 0,
|
||||
pnl = tp.DailyPnL,
|
||||
stress_test_value = (tr.DeltaCash * 21.68 / 100 + tr.Vega * 0.1),// 单退
|
||||
underlying_stk_qty = tp.Amount,
|
||||
underlying_royalty_price = x.TradeSinglePrice,
|
||||
}).ToList();
|
||||
var responseTrade = HanderlResponseTradeData(req.ValueDate, handleTrades);
|
||||
return responseTrade;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成Response
|
||||
/// </summary>
|
||||
private List<ResponseTrade> HanderlResponseTradeData(DateTime valueDate, List<HandleTrade> handleTrades)
|
||||
{
|
||||
var responseTrades = new List<ResponseTrade>();
|
||||
foreach (var item in handleTrades)
|
||||
{
|
||||
var responseTrade = new ResponseTrade();
|
||||
responseTrade.ordid = item.ordid;
|
||||
responseTrade.groupid = item.groupid;
|
||||
responseTrade.sub_ordid = item.sub_ordid;
|
||||
responseTrade.sac_ordid = item.sac_ordid;
|
||||
responseTrade.contract_type_cls = GetTradeTypeAbbreviation(item);
|
||||
responseTrade.long_short_position_cls = item.long_short_position_cls;
|
||||
responseTrade.put_call_cls = item.put_call_cls;
|
||||
responseTrade.settlement_type_cls = item.settlement_type_cls;
|
||||
responseTrade.exercise_type_cls = item.exercise_type_cls;
|
||||
responseTrade.strike_price = item.strike_price;
|
||||
responseTrade.settlement_currency = item.settlement_currency;
|
||||
responseTrade.pricing_currency = item.pricing_currency;
|
||||
responseTrade.premium_amt = item.premium_amt;
|
||||
responseTrade.participation_rate = item.participation_rate;
|
||||
responseTrade.levelpercentage = item.levelpercentage;
|
||||
responseTrade.calendar_type_cls = item.calendar_type_cls;
|
||||
responseTrade.counterparty_name = item.counterparty_name;
|
||||
responseTrade.counterparty_sac_ordid = item.counterparty_sac_ordid;
|
||||
responseTrade.businessday_convention_cls = item.businessday_convention_cls;
|
||||
responseTrade.calcrules_cls = item.calcrules_cls;
|
||||
responseTrade.single_multi_cls = item.single_multi_cls;
|
||||
responseTrade.weight_calc_cls = item.weight_calc_cls;
|
||||
responseTrade.additionalproduct_type = item.additionalproduct_type;
|
||||
responseTrade.dis_rate = item.dis_rate;
|
||||
responseTrade.underlying_stkcode = item.underlying_stkcode;
|
||||
responseTrade.underlying_caihua_trade_market = GetUnderlyingCaihuaTradeMarket(item.underlying_caihua_trade_market);
|
||||
responseTrade.caihua_setype0_cls = item.caihua_setype0_cls;
|
||||
responseTrade.initial_spot = item.initial_spot;
|
||||
responseTrade.weight_rate = item.weight_rate;
|
||||
responseTrade.div_rate = item.div_rate;
|
||||
responseTrade.vol_rate = item.vol_rate;
|
||||
responseTrade.fund_rate = item.fund_rate;
|
||||
responseTrade.barrier_type_cls = item.barrier_type_cls;
|
||||
responseTrade.barrier_value = item.barrier_value;
|
||||
responseTrade.rebate_rate = item.rebate_rate;
|
||||
responseTrade.knockout_price = item.knockout_price;
|
||||
responseTrade.knockin_price = item.knockin_price;
|
||||
responseTrade.coupon_rate = item.coupon_rate;
|
||||
responseTrade.observationdate_list = item.observationdate_list;
|
||||
responseTrade.observe_start_date = item.observe_start_date;
|
||||
responseTrade.observe_end_date = item.observe_end_date;
|
||||
responseTrade.obsfreq = item.obsfreq;
|
||||
responseTrade.avg_type_cls = item.avg_type_cls;
|
||||
responseTrade.discrete_type_cls = item.discrete_type_cls;
|
||||
responseTrade.notional = item.notional;
|
||||
responseTrade.margin = item.margin;
|
||||
|
||||
var nowPrice = item.cashdelta / item.delta;
|
||||
|
||||
//亚试
|
||||
responseTrade.accu_underlying_price_asian = AsianOptionCalcHelper.GetAveragePrice(item.tradeModel, item.trade_Asian_Option, nowPrice, valueDate, out var fixingsCount);
|
||||
|
||||
responseTrade.accu_past_count_asian = fixingsCount;
|
||||
responseTrade.float_profit_loss = item.float_profit_loss;
|
||||
responseTrade.accu_profit_loss = item.accu_profit_loss;
|
||||
responseTrade.npv = item.npv;
|
||||
responseTrade.delta = item.delta;
|
||||
responseTrade.gamma = item.gamma;
|
||||
responseTrade.theta = item.theta;
|
||||
responseTrade.vega = item.vega;
|
||||
responseTrade.rho = item.rho;
|
||||
responseTrade.settle_date = item.settle_date;
|
||||
responseTrade.product_code = item.product_code;
|
||||
responseTrade.volume = item.volume;
|
||||
responseTrade.cashdelta = item.cashdelta;
|
||||
responseTrade.current_value = item.current_value;
|
||||
responseTrade.market_value = item.market_value;
|
||||
responseTrade.pnl = item.pnl;
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
//多退
|
||||
if (db.trade.Any(t => t.ParentTradeId == item.tradeModel.id))
|
||||
{
|
||||
var ids = db.trade.Where(t => t.ParentTradeId == item.tradeModel.id).Select(l => l.id).ToArray();
|
||||
var list = db.eod_trade_risk.Where(t => ids.Contains(t.TradeId)).Select(l => new { l.Vega, l.DeltaCash });
|
||||
double vega = 0;
|
||||
double deltaCash = 0;
|
||||
list.ForEachAsync(t => { vega += t.Vega; deltaCash += t.DeltaCash; });
|
||||
responseTrade.stress_test_value = (deltaCash * 21.68 / 100 + vega * 0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
responseTrade.stress_test_value = item.stress_test_value;
|
||||
}
|
||||
}
|
||||
|
||||
responseTrade.underlying_stk_qty = item.underlying_stk_qty;
|
||||
responseTrade.underlying_multiplier = item.underlying_multiplier;
|
||||
responseTrade.underlying_royalty_price = item.underlying_royalty_price;
|
||||
responseTrade.effective_date_from = ConvertDateToInt(item.effective_date_from);
|
||||
responseTrade.effective_date_to = ConvertDateToInt(item.effective_date_to);
|
||||
responseTrade.maturity_date = ConvertDateToInt(item.maturity_date);
|
||||
responseTrade.premium_date = ConvertDateToInt(item.premium_date);
|
||||
responseTrade.start_date = ConvertDateToInt(item.start_date);
|
||||
responseTrade.ordname = item.ordname + "-" + Convert.ToDateTime(item.tradeModel.ExerciseDate).ToString("MMdd") + "M-" + item.tradeModel.Strike + "K" + (item.trade_Asian_Option != null ? ("-" + (Convert.ToDateTime(item.trade_Asian_Option?.AveragingPeriodStartDate).ToString("MMdd") ?? Convert.ToDateTime(item.effective_date_from).ToString("MMdd"))) + "OB" : "");
|
||||
|
||||
DoubleIsNan(responseTrade);
|
||||
responseTrades.Add(responseTrade);
|
||||
}
|
||||
return responseTrades;
|
||||
}
|
||||
|
||||
private void DoubleIsNan(ResponseTrade rt)
|
||||
{
|
||||
|
||||
var t = rt.GetType();
|
||||
foreach (System.Reflection.PropertyInfo p in rt.GetType().GetProperties())
|
||||
{
|
||||
if (p.PropertyType.IsValueType && p.PropertyType.FullName.Contains("Double"))
|
||||
{
|
||||
if (p.GetValue(rt) != null)
|
||||
{
|
||||
if (p.GetValue(rt)?.ToString() == "NAN" || !((Double)p.GetValue(rt)).IsNormalize())
|
||||
{
|
||||
p.SetValue(rt, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public string GetUnderlyingCaihuaTradeMarket(string TradeMarketName)
|
||||
{
|
||||
var strCode = "";
|
||||
switch (TradeMarketName)
|
||||
{
|
||||
case "上海证券交易所":
|
||||
strCode = "001002";
|
||||
break;
|
||||
case "深圳证券交易所":
|
||||
strCode = "001003";
|
||||
break;
|
||||
case "上海期货交易所":
|
||||
strCode = "001008";
|
||||
break;
|
||||
case "上海国际能源交易所":
|
||||
strCode = "001061";
|
||||
break;
|
||||
case "上海黄金交易所":
|
||||
strCode = "001015";
|
||||
break;
|
||||
case "中国金融期货交易所":
|
||||
strCode = "001009";
|
||||
break;
|
||||
case "郑州商品交易所":
|
||||
strCode = "001017";
|
||||
break;
|
||||
case "大连商品交易所":
|
||||
strCode = "001016";
|
||||
break;
|
||||
}
|
||||
return strCode;
|
||||
}
|
||||
/// <summary>
|
||||
/// 交易类型 转换简称
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public string GetTradeTypeAbbreviation(HandleTrade ht)
|
||||
{
|
||||
var strType = "";
|
||||
switch (ht.tradeModel.TradeType)
|
||||
{
|
||||
case "香草期权":
|
||||
strType = "VNL";
|
||||
break;
|
||||
case "障碍期权":
|
||||
//if (t.trade_barrier_option.BarrierType.Contains("双障碍敲"))
|
||||
//{
|
||||
// //二元障碍期权
|
||||
// strType = "BIB";
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
strType = "BRR";
|
||||
//}
|
||||
break;
|
||||
case "多触碰点障碍期权": //todo
|
||||
strType = "ACL";
|
||||
break;
|
||||
case "亚式期权":
|
||||
var type = ht.PayoffType ?? "";
|
||||
if (type.Contains("Enhanced"))
|
||||
{
|
||||
strType = "ESA";//增强亚式
|
||||
}
|
||||
else
|
||||
{
|
||||
strType = "ASN";//亚式
|
||||
}
|
||||
break;
|
||||
case "二元期权":
|
||||
if (ht.tradeModel.ExerciseMode == "European")
|
||||
{
|
||||
strType = "DGT";
|
||||
}
|
||||
else
|
||||
{
|
||||
//一触即发期权
|
||||
strType = "TRN";
|
||||
}
|
||||
break;
|
||||
case "结构化交易":
|
||||
strType = "STG";
|
||||
break;
|
||||
case "凤凰期权":
|
||||
strType = "PHX";
|
||||
break;
|
||||
case "雪球期权":
|
||||
strType = "SNB";
|
||||
break;
|
||||
|
||||
case "区间累计期权":
|
||||
strType = "RAL";
|
||||
break;
|
||||
default:
|
||||
strType = "UNK";
|
||||
break;
|
||||
}
|
||||
return strType;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 日期转换int
|
||||
/// </summary>
|
||||
private static int ConvertDateToInt(DateTime? dt)
|
||||
{
|
||||
if (dt == null) return 0;
|
||||
|
||||
return dt.Value.Year * 10000 + dt.Value.Month * 100 + dt.Value.Day;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 方顿日终数据接口1请求
|
||||
/// </summary>
|
||||
public class FangDunEodData1Request
|
||||
{
|
||||
public DateTime ValueDate { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user