Files
zszq-trs/UnitTestProject/Modules/EodModule/EodSettlementTest.cs
T
2024-05-09 14:06:26 +08:00

116 lines
4.3 KiB
C#

using Qdp.Pricing.Base.Implementations;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.EodModule.SettlementModule;
using YLErp.QdpModule;
namespace YLErp.Modules.EodModule
{
[TestClass]
public class EodSettlementTest : UnitTestBase
{
[TestMethod("收盘估值计算")]
public void TestCalcPv()
{
var settleDate = new DateTime(2021, 4, 27);
var predicate = PredicateBuilder.Create<trade>(t => t.TradeNumber == "CW20210016E0002");
var otcTrades = new EodSettleDataQueryService(GetOptUser())
.GetOtcTrades(settleDate, predicate, out var tradeCashProvider);
var td = otcTrades.FirstOrDefault();
if (td == null)
{
Console.WriteLine("没有找到交易");
return;
}
var eodpriceProvider = new YLErp.Modules.DataProviderModule.EodPriceProvider(settleDate);
var spotPrice = eodpriceProvider.GetPrice(td.UnderlyingCode, SettlementTypeEnum.ClosePrice);
var req = new OptionValueCalcRequest(td.NoRiskRate ?? 0)
{
correlations = null,//不计算彩虹等多标的期权暂时不需要
engineName = null,
preciseTimeMode = false, //日终一定是false
pricingRequest = QdpPricingRequest.BASIC_GREEKS,
spotPrices = new[] { spotPrice }
};
if (td.TradeType != ConsGlobal.TradeType.CashFlow)
{
var volProvider = EodVolProviderFactory.GetEodVolProvider(settleDate, "持仓");
var vol = volProvider.GetVol(td, spotPrice) ?? ConsGlobal.DefaultVol;
req.vols = new[] { vol };
}
var option = OptionCalculatorV2.GetOptionValueResult(settleDate, td, req, out var underlyings);
Console.WriteLine($"[{td.TradeType},{td.TradeNumber},{td.id}] pv:{option.Pv}, delta:{option.Delta}");
}
[TestMethod("测试盈亏分解--当天新开仓的交易")]
public void TestCalcPnlExplainV2_NewOtcTradeDeal()
{
var db = DbContextFactory.GetYLDbContext();
var td = db.trade.FirstOrDefault(n => n.TradeNumber == "CW20210016C0001");
YLErp.BLL.tradeBLL.SetFieldsByTradeType(td);
var pnl = new EodPnl();
double spot0 = 5910, spot1 = 5911, pv1 = 53796.37;
var pS0V1Q1T1 = CalcPnlExplainV2(td, new CalcField
{
spot = spot0,
vol = 0.28,
dividendRate = 0,
riskFreeRate = 0.03,
date = new DateTime(2021, 4, 27)
}, PricingRequest.Pv | PricingRequest.Delta, x =>
{
});
if (pS0V1Q1T1 != null)
{
pnl.PnLVega += NumberHelper.Normalize(pS0V1Q1T1.Pv - ((td.TradeSinglePrice ?? 0) * td.Notional));
pnl.PnLDelta += NumberHelper.Normalize(pS0V1Q1T1.Delta * (spot1 - spot0));
pnl.PnLGamma += NumberHelper.Normalize(pv1 - pS0V1Q1T1.Pv - pnl.PnLDelta);
Console.WriteLine($"pS0V1Q1T1 pv:{pS0V1Q1T1.Pv}, delta:{pS0V1Q1T1.Delta}");
}
Console.WriteLine("计算失败");
}
//计算pv和delta
private static TradeValueResult CalcPnlExplainV2(trade td, CalcField f, PricingRequest pricingRequest
, Action<OptionTradeParamBase> paramOverride = null)
{
td.NoRiskRate = f.riskFreeRate;
td.DividendRate = f.dividendRate;
var req = new OptionValueCalcRequest(f.riskFreeRate)
{
correlations = null,//不计算彩虹等多标的期权暂时不需要
engineName = null,
preciseTimeMode = false, //日终一定是false
pricingRequest = pricingRequest,
spotPrices = new[] { f.spot },
vols = new[] { f.vol },
ParamOverride = paramOverride
};
return OptionCalculatorV2.GetOptionValueResult(f.date, td, req, out _);
}
class CalcField
{
//public double pv;
public DateTime date;
public double vol;
public double dividendRate;
public double spot;
public double riskFreeRate;
}
}
}