183 lines
5.8 KiB
C#
183 lines
5.8 KiB
C#
using System.Collections.Concurrent;
|
|
using YLErp.Abstract;
|
|
using YLErp.DBModels.Consts;
|
|
|
|
namespace YLErp.Modules.DataProviderModule
|
|
{
|
|
/// <summary>
|
|
/// 交易历史数据提供
|
|
/// </summary>
|
|
public class TradeHisDataProvider : ITradeHisDataProvider
|
|
{
|
|
readonly DateTime _valueDate;
|
|
|
|
//key:tradeId
|
|
readonly ConcurrentDictionary<int, InnerTradeHisData> _dic;
|
|
|
|
public TradeHisDataProvider(DateTime valueDate)
|
|
{
|
|
_valueDate = valueDate;
|
|
_dic = new ConcurrentDictionary<int, InnerTradeHisData>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 加载最近三个月的数据做初始化
|
|
/// </summary>
|
|
public TradeHisDataProvider Initialize()
|
|
{
|
|
if (_dic.Count > 0)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
lock (this)
|
|
{
|
|
if (_dic.Count > 0)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
//只取3个月以内的
|
|
var startDate = _valueDate.AddMonths(-3);
|
|
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var query1 = from a in db.TradeHisData
|
|
where a.ValueDate > startDate && a.ValueDate <= _valueDate
|
|
group a by new { a.TradeId, a.ValueType } into g
|
|
select new
|
|
{
|
|
g.Key.TradeId,
|
|
g.Key.ValueType,
|
|
ValueDate = g.Max(n => n.ValueDate)
|
|
};
|
|
|
|
var query2 = from a in query1
|
|
join b in db.TradeHisData on a equals new { b.TradeId, b.ValueType, b.ValueDate }
|
|
select new
|
|
{
|
|
b.TradeId,
|
|
b.ValueType,
|
|
b.Value
|
|
};
|
|
|
|
var datas = query2.ToArray();
|
|
|
|
foreach (var data in datas)
|
|
{
|
|
if (!_dic.TryGetValue(data.TradeId, out var idata))
|
|
{
|
|
_dic[data.TradeId] = idata = new InnerTradeHisData();
|
|
}
|
|
|
|
if (ConsTradeField.NoRiskRate.Equals(data.ValueType, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
idata.NoRiskRate = data.Value;
|
|
idata.Flag |= ValueFlag.NoRiskRate;
|
|
}
|
|
else if (ConsTradeField.DividendRate.Equals(data.ValueType, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
idata.DividendRate = data.Value;
|
|
idata.Flag |= ValueFlag.DividendRate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
private double? GetValue(int tradeId, ValueFlag valueFlag)
|
|
{
|
|
if (_dic.TryGetValue(tradeId, out var data))
|
|
{
|
|
if ((data.Flag & valueFlag) == valueFlag)
|
|
{
|
|
switch (valueFlag)
|
|
{
|
|
case ValueFlag.NoRiskRate: return data.NoRiskRate;
|
|
case ValueFlag.DividendRate: return data.DividendRate;
|
|
default: throw new InvalidOperationException();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_dic[tradeId] = data = new InnerTradeHisData();
|
|
}
|
|
|
|
string valueType;
|
|
|
|
switch (valueFlag)
|
|
{
|
|
case ValueFlag.NoRiskRate:
|
|
valueType = ConsTradeField.NoRiskRate; break;
|
|
case ValueFlag.DividendRate:
|
|
valueType = ConsTradeField.DividendRate; break;
|
|
default: throw new InvalidOperationException();
|
|
}
|
|
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var query = from n in db.TradeHisData
|
|
where n.TradeId == tradeId && n.ValueDate <= _valueDate && n.ValueType == valueType
|
|
orderby n.ValueDate descending
|
|
select (double?)n.Value;
|
|
|
|
var value = query.FirstOrDefault();
|
|
|
|
switch (valueFlag)
|
|
{
|
|
case ValueFlag.NoRiskRate:
|
|
data.NoRiskRate = value; break;
|
|
case ValueFlag.DividendRate:
|
|
data.DividendRate = value; break;
|
|
default: throw new InvalidOperationException();
|
|
}
|
|
|
|
data.Flag |= valueFlag;
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取无风险利率
|
|
/// </summary>
|
|
public double? GetNoRiskRate(int tradeId)
|
|
{
|
|
return GetValue(tradeId, ValueFlag.NoRiskRate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取分红率
|
|
/// </summary>
|
|
public double? GetDividendRate(int tradeId)
|
|
{
|
|
return GetValue(tradeId, ValueFlag.DividendRate);
|
|
}
|
|
|
|
class InnerTradeHisData
|
|
{
|
|
/// <summary>
|
|
/// 无风险利率
|
|
/// </summary>
|
|
public double? NoRiskRate;
|
|
|
|
/// <summary>
|
|
/// 分红率
|
|
/// </summary>
|
|
public double? DividendRate;
|
|
|
|
public ValueFlag Flag;
|
|
}
|
|
|
|
enum ValueFlag
|
|
{
|
|
None = 0,
|
|
NoRiskRate = 1 << 0,
|
|
DividendRate = 1 << 1
|
|
}
|
|
}
|
|
}
|