从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user