Files
zszq-trs/YLErpDAL/BLL/MarginCalculation/DongWu/UpDownLimitMargin3Provider.cs
T
2024-05-09 14:06:26 +08:00

96 lines
4.2 KiB
C#

using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using YLErp.Abstract.DataProviders;
using YLErp.Models;
using YLErp.Modules.DataProviderModule;
namespace YLErp.BLL.MarginCalculation.DongWu
{
public class UpDownLimitMargin3Provider : IUpDownLimitProvider
{
private DateTime settleDate;
private string underlyingCode;
readonly IUnderlyingDataProvider underlyingDataProvider;
public UpDownLimitMargin3Provider(DateTime settleDate, string underlyingCode)
{
this.settleDate = settleDate;
this.underlyingCode = underlyingCode;
this.underlyingDataProvider = new UnderlyingDataProvider();
}
/// <summary>
/// 获取连续两日最大涨跌幅的95分位和5分位
/// ---------------------------------------------------------------------
/// 例如,对于CF209合约,选取CFFI.WI过去600天内的价格序列,对于任意日T,
/// 其两日最大涨幅=Max(T+1最高价,T+2最高价)/T日收盘价
/// 两日最大跌幅 = Min(T + 1最低价,T + 2最低价) / T日收盘价
/// 得到最大涨跌幅的序列后,取95分位和5分位的百分比作为连续两日最大涨跌幅的95分位数值。
/// </summary>
/// <returns></returns>
public InnerUpDownLimit GetUpDownLimit()
{
var startDate = settleDate.AddDays(-600);
var mainUnderlyingCode = underlyingCode;
var um = underlyingDataProvider.GetUnderlying(underlyingCode);
if (um.IsFutures())
{
// 如果是期货类型的,需要获取到主合约
// 忽略大小写,将字母后的数字替换为00,获取到主合约Code
Regex myRegex = new Regex(@"^([a-zA-Z]*)(\d*)$", RegexOptions.IgnoreCase);
mainUnderlyingCode = myRegex.Replace(underlyingCode, "$1") + "00";
}
var eodPrices = EodPriceQueryService.GetEodPriceByUnserialDateRange(startDate, settleDate, mainUnderlyingCode).OrderBy(b => b.ValueDate).ToList();
int lastIndex = eodPrices.Count - 1;
List<InnerUpDownLimit> innerCodes = new List<InnerUpDownLimit>();
for (int i = 0; i < eodPrices.Count; i++)
{
if (i == lastIndex - 1)
{
// 最后两天没有T+1和T+2,不放到列表中统计95分位和5分位;
break;
}
EodPrice t0 = eodPrices[i];
EodPrice t1 = (i + 1) > lastIndex ? null : eodPrices[i + 1];
EodPrice t2 = (i + 2) > lastIndex ? null : eodPrices[i + 2];
var uplimitRate = Math.Max(t1?.HighPrice ?? 0, t2?.HighPrice ?? 0) / t0.ClosePrice;
var downLimitRate = Math.Min(t1?.LowPrice ?? 0, t2?.LowPrice ?? 0) / t0.ClosePrice;
InnerUpDownLimit innerCode = new InnerUpDownLimit()
{
UnderlyingCode = t0.UnderlyingCode,
//ClosePrice = t0.ClosePrice,
UplimitRate = uplimitRate,
DownLimitRate = downLimitRate
};
innerCodes.Add(innerCode);
}
//最大涨幅95分位和5分位
List<double> priceList = new List<double>();
priceList.AddRange(innerCodes.Select(g => g.UplimitRate));
priceList.AddRange(innerCodes.Select(g => g.DownLimitRate));
var OrderPriceList = priceList.OrderBy(g => g);
var totalCount = OrderPriceList.Count();
var uplimitRatePercent95 = totalCount == 0 ? 0 : Math.Abs(1-OrderPriceList.ElementAt((int)(totalCount * 0.95)));
var downLimitRatePercent5 = totalCount == 0 ? 0 : Math.Abs(1-OrderPriceList.ElementAt((int)(totalCount * 0.05)));
return new InnerUpDownLimit()
{
UnderlyingCode = underlyingCode,
UplimitRate = totalCount == 0 ? 0 : uplimitRatePercent95,
DownLimitRate = totalCount == 0 ? 0 : downLimitRatePercent5
};
}
}
}