315 lines
9.9 KiB
C#
315 lines
9.9 KiB
C#
using Qdp.Foundation.Implementations;
|
|
using YLErp.BLL.Calculation;
|
|
using YLErp.QdpModule;
|
|
|
|
namespace YLErp.BLL
|
|
{
|
|
public delegate void ValueDateChangedEventHandler(object sender, EventArgs e);
|
|
|
|
public static class valuedateBLL
|
|
{
|
|
public static string VanillaAmericanOptionName
|
|
{
|
|
get
|
|
{
|
|
var engineName = "";
|
|
switch (SystemDate.ConfigInfoData.ValueVanillaOptionMode)
|
|
{
|
|
case "BAW":
|
|
engineName = "AnalyticalVanillaAmericanOptionBAWEngine";
|
|
break;
|
|
case "二叉树":
|
|
engineName = "BinomialTreeAmericanEngine";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return engineName;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 系统当前运行时间
|
|
/// </summary>
|
|
|
|
public static valuedate SystemDate => InnerValueDate.Instance;
|
|
|
|
/// <summary>
|
|
/// 系统设置的二元期权的计算方法
|
|
/// </summary>
|
|
public static string BinaryCalculation => SystemDate.BinaryCalculation;
|
|
|
|
/// <summary>
|
|
/// 二元期权的ReplicationStrategy
|
|
/// </summary>
|
|
public static string BinaryReplicationStrategy => (BinaryCalculation == "Replication") ? BinaryCalculation : "None";
|
|
|
|
/// <summary>
|
|
/// 系统设置的无风险利率
|
|
/// </summary>
|
|
public static double RiskFreeRate => SystemDate.RiskFreeRate ?? 0.0;
|
|
|
|
/// <summary>
|
|
/// 系统设置的无风险利率(除以100)
|
|
/// </summary>
|
|
public static double SysRiskFreeRate()
|
|
{
|
|
return RiskFreeRate / 100;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 系统设置的扩展无风险利率
|
|
/// </summary>
|
|
public static double RiskFreeRateExtend => SystemDate.RiskFreeRateExtend ?? 0.0;
|
|
|
|
public static string RiskFreeCurveData => SystemDate.RiskFreeCurveData;
|
|
|
|
/// <summary>
|
|
/// 是否在手机报价端开启客户自助定价计算
|
|
/// </summary>
|
|
public static bool EnableClientCalculation => SystemDate.EnableClientCalculation == 1;
|
|
|
|
/// <summary>
|
|
/// 是否开启手机端实时报价
|
|
/// </summary>
|
|
public static bool EnableMobileQuotation => SystemDate.EnableMobileQuotation == 1;
|
|
|
|
/// <summary>
|
|
/// 手机端报价是否展示波动率报价
|
|
/// </summary>
|
|
public static bool EnableMobileVolQuote => SystemDate.EnableMobileVolQuote == 1;
|
|
|
|
public static string TradeDayCount => SystemDate.TradeDayCount;
|
|
|
|
public static DateTime ValueDate
|
|
{
|
|
get
|
|
{
|
|
//自动更新时间
|
|
if (SystemDate.Type != "false" && SystemDate.ValueDate < DateTime.Today)
|
|
{
|
|
InnerValueDate.UpdateSystemDate();
|
|
}
|
|
return SystemDate.ValueDate;
|
|
}
|
|
}
|
|
|
|
public static DateTime? TwoSideMarginValueDate => SystemDate.TwoSideMarginValueDate;
|
|
|
|
/// <summary>
|
|
/// 获取系统时间
|
|
/// </summary>
|
|
public static valuedate ResetValueDate()
|
|
{
|
|
return InnerValueDate.ResetValueDate();
|
|
}
|
|
|
|
public static event ValueDateChangedEventHandler ValueDateChanged;
|
|
|
|
/// <summary>
|
|
/// 从利率曲线上获取无风险利率(无风险利率百分比数值)
|
|
/// </summary>
|
|
public static double GetRiskFreeRateFromCurve(DateTime? startDate, DateTime? endDate)
|
|
{
|
|
//为了与System.RiskFreeRate统一,所以乘以100
|
|
return GetRiskFreeRateFromCurveV2(startDate, endDate) * 100;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从利率曲线上获取无风险利率(无风险利率真实值)
|
|
/// </summary>
|
|
public static double GetRiskFreeRateFromCurveV2(DateTime? startDate, DateTime? endDate)
|
|
{
|
|
var curveData = RiskFreeCurveData;
|
|
|
|
if (string.IsNullOrWhiteSpace(curveData) || startDate == null || endDate == null)
|
|
{
|
|
return SysRiskFreeRate();
|
|
}
|
|
|
|
var curvePoints = JsonHelper.Deserialize<List<SimpleIRCurvePoint>>(curveData);
|
|
if (curvePoints == null || curvePoints.Count < 2)
|
|
{
|
|
return SysRiskFreeRate();
|
|
}
|
|
|
|
var curve = CalculatorHelper.BuildIRCurve("RiskFreeCurve", startDate.Value, curvePoints);
|
|
if (curve == null)
|
|
{
|
|
return SysRiskFreeRate();
|
|
}
|
|
|
|
var qdpEnd = new Date(endDate.Value);
|
|
|
|
return curve.GetSpotRate(qdpEnd);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取date(包括)之前的第一个非假日
|
|
/// </summary>
|
|
public static DateTime GetNonHolidayDefore(DateTime date)
|
|
{
|
|
if (PS.Config.ErpElement.SupportMultiCalendar)
|
|
{
|
|
switch (date.DayOfWeek)
|
|
{
|
|
case DayOfWeek.Saturday:
|
|
return date.AddDays(-1);
|
|
case DayOfWeek.Sunday:
|
|
return date.AddDays(-2);
|
|
default: return date;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return QdpCalendarHelper.GetNonHolidayDefore(date);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取date(包括)之后的第一个非假日
|
|
/// </summary>
|
|
public static DateTime GetNonHoliday(DateTime date)
|
|
{
|
|
if (PS.Config.ErpElement.SupportMultiCalendar)
|
|
{
|
|
switch (date.DayOfWeek)
|
|
{
|
|
case DayOfWeek.Saturday:
|
|
return date.AddDays(2);
|
|
case DayOfWeek.Sunday:
|
|
return date.AddDays(1);
|
|
default: return date;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return QdpCalendarHelper.GetNonHoliday(date);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static bool IsHoliday(DateTime date)
|
|
{
|
|
if (PS.Config.ErpElement.SupportMultiCalendar)
|
|
{
|
|
switch (date.DayOfWeek)
|
|
{
|
|
case DayOfWeek.Saturday:
|
|
case DayOfWeek.Sunday:
|
|
return true;
|
|
default: return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return QdpCalendarHelper.IsHoliday(date);
|
|
}
|
|
}
|
|
|
|
static class InnerValueDate
|
|
{
|
|
static DateTime _cacheUpdateTime;
|
|
static valuedate _systemDate = null;
|
|
|
|
/// <summary>
|
|
/// 系统当前运行时间
|
|
/// </summary>
|
|
public static valuedate Instance
|
|
{
|
|
get
|
|
{
|
|
if (_systemDate == null)
|
|
{
|
|
ResetValueDate();
|
|
}
|
|
else
|
|
{
|
|
//自动更新系统时间为当前时间
|
|
UpdateSystemDate();
|
|
}
|
|
|
|
return _systemDate;
|
|
}
|
|
}
|
|
|
|
public static valuedate ResetValueDate()
|
|
{
|
|
lock (typeof(valuedate))
|
|
{
|
|
using (var ylcon = new YLContext())
|
|
{
|
|
_systemDate = ylcon.valuedate.FirstOrDefault(v => v.State == valuedate.当前使用);
|
|
}
|
|
}
|
|
|
|
return _systemDate;
|
|
}
|
|
|
|
public static void UpdateSystemDate()
|
|
{
|
|
if (_cacheUpdateTime.AddSeconds(10) > DateTime.Now)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_cacheUpdateTime = DateTime.Now;
|
|
|
|
var tradingDay = GetEstimatedTradingDay();
|
|
|
|
if (_systemDate != null && _systemDate.ValueDate >= tradingDay)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//更新为当天
|
|
using (var ylcon = Modules.DbContextFactory.GetYLDbContext())
|
|
{
|
|
var curDate = ylcon.valuedate.FirstOrDefault(v => v.State == valuedate.当前使用);
|
|
if (curDate == null)
|
|
{
|
|
var vd = new valuedate() { ValueDate = tradingDay, State = valuedate.当前使用, CreateTime = DateTime.Now };
|
|
ylcon.valuedate.Add(vd);
|
|
_systemDate = vd;
|
|
ylcon.SaveChanges();
|
|
}
|
|
else
|
|
{
|
|
if (curDate.Type != "false" && curDate.ValueDate < tradingDay) //自动更新时间
|
|
{
|
|
//如果当前时间是假日向后延
|
|
curDate.ValueDate = QdpCalendarHelper.GetNonHoliday(tradingDay);
|
|
ylcon.SaveChanges();
|
|
}
|
|
_systemDate = curDate;
|
|
}
|
|
}
|
|
|
|
Task.Run(() =>
|
|
{
|
|
ValueDateChanged?.Invoke(_systemDate, EventArgs.Empty);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取预估的交易日
|
|
/// </summary>
|
|
private static DateTime GetEstimatedTradingDay()
|
|
{
|
|
var now = DateTime.Now;
|
|
|
|
var tradingDay = now.Date;
|
|
|
|
if (now.TimeOfDay > new TimeSpan(23, 59, 00))
|
|
{
|
|
tradingDay = tradingDay.AddDays(1);
|
|
}
|
|
|
|
return GetNonHoliday(tradingDay);
|
|
}
|
|
}
|
|
}
|
|
}
|