563 lines
22 KiB
C#
563 lines
22 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using System.Reflection;
|
|
using YLErp.BLL;
|
|
using YLErp.DBModels;
|
|
using YLErp.Helpers;
|
|
using YLErp.Modules;
|
|
using YLErp.QdpModule;
|
|
using YLErp.Jobs.Configs;
|
|
|
|
namespace YLErp.Jobs.Imp
|
|
{
|
|
/// <summary>
|
|
/// 国元价格数据同步
|
|
/// </summary>
|
|
public class GuoYuanPriceSyncJob : BaseJob
|
|
{
|
|
private readonly YLContext ylDb;
|
|
|
|
private static readonly Dictionary<string, UpdatetimeModel> runInfo;
|
|
private static readonly Dictionary<string, string> irsCurveTypeCodeDict;
|
|
private static readonly Dictionary<string, string> cbCurveCodeDict;
|
|
private static readonly Dictionary<decimal, string> cbYieldCurveDict;
|
|
private static readonly Dictionary<string, string> propertiesDict;
|
|
static readonly IYcLogger logger;
|
|
private string database = "";
|
|
private GuoYuanPriceSyncJobConfig _guoYuanPriceSyncJobConfig;
|
|
|
|
static GuoYuanPriceSyncJob()
|
|
{
|
|
logger = LogFactory.GetLogger<GuoYuanPriceSyncJob>();
|
|
runInfo = new Dictionary<string, UpdatetimeModel>() {
|
|
{ "CGB", new UpdatetimeModel() },
|
|
{ "CIB", new UpdatetimeModel() },
|
|
{ "FR", new UpdatetimeModel() },
|
|
{ "SRS", new UpdatetimeModel() },
|
|
{ "SIBO", new UpdatetimeModel() },
|
|
{ "FRR", new UpdatetimeModel() }
|
|
};
|
|
irsCurveTypeCodeDict = new Dictionary<string, string>() {
|
|
{ "2", "FR" },
|
|
{ "5", "SRS" },
|
|
};
|
|
cbCurveCodeDict = new Dictionary<string, string>() {
|
|
{ "10", "CGB" },
|
|
{ "195", "CIB" },
|
|
};
|
|
cbYieldCurveDict = new Dictionary<decimal, string>() {
|
|
{ 0.25m, "3M" },
|
|
{ 0.5m, "6M" },
|
|
{ 0.75m, "9M" },
|
|
{ 1m, "1Y" },
|
|
{ 2m, "2Y" },
|
|
{ 3m, "3Y" },
|
|
{ 5m, "5Y" },
|
|
{ 15m, "15Y" },
|
|
{ 20m, "20Y" },
|
|
{ 10m, "10Y" },
|
|
{ 30m, "30Y" },
|
|
};
|
|
//暂时没用,本来打算反射生成sql语句的;
|
|
//Properties =
|
|
// typeof(eod_commodity_future_price)
|
|
// .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty)
|
|
// .Where(O => !O.GetCustomAttributes(typeof(NotMappedAttribute)).Any() && O.Name != nameof(eod_commodity_future_price.id))
|
|
// .Select(O =>
|
|
// {
|
|
// var temp = O.GetCustomAttributes(typeof(ColumnAttribute)).FirstOrDefault() as ColumnAttribute;
|
|
// return temp?.Name ?? O.Name;
|
|
// }).ToArray();
|
|
var eodStockPrice = new eod_stock_price();
|
|
propertiesDict =
|
|
eodStockPrice.GetType()
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty)
|
|
.Where(O => !O.GetCustomAttributes(typeof(NotMappedAttribute)).Any() && O.Name != nameof(eod_stock_price.id))
|
|
.Select(O =>
|
|
{
|
|
var temp = O.GetCustomAttributes(typeof(ColumnAttribute)).FirstOrDefault() as ColumnAttribute;
|
|
var val = O.GetValue(eodStockPrice);
|
|
return new
|
|
{
|
|
Key = temp?.Name ?? O.Name,
|
|
Value = val == null ? "null" : $"'{O.GetValue(eodStockPrice)}'"
|
|
};
|
|
}).ToDictionary(o => o.Key, o => o.Value);
|
|
}
|
|
|
|
public GuoYuanPriceSyncJob(GuoYuanPriceSyncJobConfig guoYuanPriceSyncJobConfig)
|
|
{
|
|
ylDb = new YLContext();
|
|
_guoYuanPriceSyncJobConfig=guoYuanPriceSyncJobConfig;
|
|
}
|
|
|
|
public override Task JobImp()
|
|
{
|
|
logger.Info("guoyuan-test");
|
|
logger.Info("开始执行");
|
|
var valueDate = valuedateBLL.ValueDate;
|
|
var optTime = DateTime.Now;
|
|
|
|
InitEodPrice(valueDate, optTime, "");
|
|
|
|
if (QdpCalendarHelper.IsHoliday(optTime))
|
|
{
|
|
logger.Info($"{optTime:yyyy-MM-dd} 非交易日,跳过");
|
|
return Task.CompletedTask;
|
|
}
|
|
var tasks = new Task[4];
|
|
var connection = _guoYuanPriceSyncJobConfig.ConnStr;//context.MergedJobDataMap["ConnStr"]?.ToString();
|
|
database = _guoYuanPriceSyncJobConfig.DataBase;//context.MergedJobDataMap["DataBase"]?.ToString();
|
|
|
|
logger.Info(connection);
|
|
if (optTime.Hour >= 15/* && optTime.Hour < 18*/)
|
|
{
|
|
foreach (var info in runInfo)
|
|
{
|
|
if (info.Value.EodData < DateTime.Today)
|
|
{
|
|
logger.Info("插入日终价格");
|
|
InitEodPrice(valueDate, optTime, info.Key);
|
|
UpdatePrevClosePrice(info.Key);
|
|
info.Value.EodData = DateTime.Today;
|
|
}
|
|
}
|
|
}
|
|
try
|
|
{
|
|
using (var db = new DbHelper(connection))
|
|
{
|
|
tasks[0] = Task.Run(() =>
|
|
SyncCbYieldCurve(db, valueDate, optTime)
|
|
);
|
|
tasks[1] = Task.Run(() =>
|
|
SyncIrsCurve(db, valueDate, optTime)
|
|
);
|
|
tasks[2] = Task.Run(() =>
|
|
SyncShibor(db, valueDate, optTime)
|
|
);
|
|
tasks[3] = Task.Run(() =>
|
|
SyncBaseRate(db, valueDate, optTime)
|
|
);
|
|
foreach (var t in tasks)
|
|
{
|
|
t.ContinueWith(O =>
|
|
{
|
|
if (O.Exception != null)
|
|
{
|
|
logger.Error(O.Exception);
|
|
}
|
|
});
|
|
}
|
|
Task.WaitAll(tasks);
|
|
}
|
|
}
|
|
catch (AggregateException)
|
|
{ }
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error(ex);
|
|
}
|
|
|
|
logger.Info("完成");
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
#region JobStatus Manager
|
|
static JobStatus jobStatus = JobStatus.Init;
|
|
|
|
public override JobStatus GetJobStatus()
|
|
{
|
|
return jobStatus;
|
|
}
|
|
|
|
public override void SetJobStatus(JobStatus status)
|
|
{
|
|
jobStatus = status;
|
|
}
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
/// 国债收益率曲线
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="optTime"></param>
|
|
private void SyncCbYieldCurve(DbHelper db, DateTime valueDate, DateTime optTime)
|
|
{
|
|
logger.Info("SyncCbYieldCurve开始");
|
|
var dbName = "";
|
|
if (!string.IsNullOrEmpty(database))
|
|
dbName = database + ".";
|
|
var curveCodeList = cbCurveCodeDict.Keys.ToArray();
|
|
var stepLenghtList = cbYieldCurveDict.Keys.ToArray();
|
|
var key = "CGB";
|
|
var sqlStr = "SELECT CurveCode,YearsToMaturity,Yield,UpdateTime FROM " + dbName + "Bond_CBYieldCurveAll WHERE CurveCode IN (" + string.Join(",", curveCodeList) + ") AND YearsToMaturity IN (" + string.Join(",", stepLenghtList) + ") AND YieldTypeCode = 1 AND StepTypeCode = 99 AND {0} ORDER BY UpdateTime";
|
|
var lastTime = runInfo[key].RealtimeData;
|
|
if (lastTime == default)
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"EndDate = to_date('{optTime.ToString("yyyy-MM-dd")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
else
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"UpdateTime > to_date('{lastTime.ToString("yyyy-MM-dd HH:mm:ss")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
logger.Info(sqlStr);
|
|
var list = new List<CbYieldCurveModel>();
|
|
db.ExecuteSql(sqlStr, dr =>
|
|
{
|
|
var c = new CbYieldCurveModel
|
|
{
|
|
CurveCode = dr.GetString(0),
|
|
YearsToMaturity = dr.GetInt32(1),
|
|
Yield = dr.GetDouble(2),
|
|
UpdateTime = dr.GetDateTime(3)
|
|
};
|
|
list.Add(c);
|
|
});
|
|
foreach (var item in list)
|
|
{
|
|
if (!cbCurveCodeDict.ContainsKey(item.CurveCode))
|
|
{
|
|
continue;
|
|
}
|
|
if (!cbYieldCurveDict.ContainsKey(item.YearsToMaturity))
|
|
{
|
|
continue;
|
|
}
|
|
var code = cbCurveCodeDict[item.CurveCode] + cbYieldCurveDict[item.YearsToMaturity];
|
|
logger.Info($"{code},{item.Yield},{item.UpdateTime}");
|
|
Flow(key, valueDate, optTime, code, item.Yield, item.UpdateTime);
|
|
}
|
|
logger.Info($"SyncCbYieldCurve完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 利率互换收盘曲线
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="optTime"></param>
|
|
private void SyncIrsCurve(DbHelper db, DateTime valueDate, DateTime optTime)
|
|
{
|
|
logger.Info("SyncIrsCurve开始");
|
|
var dbName = "";
|
|
if (!string.IsNullOrEmpty(database))
|
|
dbName = database + ".";
|
|
var curveTypeCodeList = irsCurveTypeCodeDict.Keys;
|
|
var key = "FR";
|
|
var sqlStr = "SELECT CueveName,MaturityYield,UpdateTime FROM " + dbName + "Bond_IRSCurveQuote WHERE CurveTypeCode IN (" + string.Join(",", curveTypeCodeList) + ") AND {0} ORDER BY UpdateTime";
|
|
var lastTime = runInfo[key].RealtimeData;
|
|
if (lastTime == default)
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"TradingDay = to_date('{optTime.ToString("yyyy-MM-dd")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
else
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"UpdateTime > to_date('{lastTime.ToString("yyyy-MM-dd HH:mm:ss")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
logger.Info(sqlStr);
|
|
var list = new List<IrsCurveModel>();
|
|
db.ExecuteSql(sqlStr, dr =>
|
|
{
|
|
var c = new IrsCurveModel
|
|
{
|
|
CueveName = dr.GetString(0),
|
|
MaturityYield = dr.GetDouble(1),
|
|
UpdateTime = dr.GetDateTime(2)
|
|
};
|
|
list.Add(c);
|
|
});
|
|
foreach (var item in list)
|
|
{
|
|
if (!irsCurveTypeCodeDict.ContainsKey(item.CueveName))
|
|
{
|
|
continue;
|
|
}
|
|
var code = irsCurveTypeCodeDict[item.CueveName];//Todo:
|
|
logger.Info($"{code},{item.MaturityYield},{item.UpdateTime}");
|
|
Flow(key, valueDate, optTime, code, item.MaturityYield, item.UpdateTime);
|
|
}
|
|
logger.Info($"SyncIrsCurve完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 上海银行间同业拆借利率
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="optTime"></param>
|
|
private void SyncShibor(DbHelper db, DateTime valueDate, DateTime optTime)
|
|
{
|
|
logger.Info("SyncShibor开始");
|
|
var dbName = "";
|
|
if (!string.IsNullOrEmpty(database))
|
|
dbName = database + ".";
|
|
var key = "SIBO";
|
|
var sqlStr = "SELECT TradingDay,ReportPeriod,OfferedMaturity,WeightAveragePrice,UpdateTime FROM " + dbName + "Bond_SHIBOR WHERE {0} ORDER BY UpdateTime";
|
|
var lastTime = runInfo[key].RealtimeData;
|
|
if (lastTime == default)
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"TradingDay = to_date('{optTime.ToString("yyyy-MM-dd")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
else
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"UpdateTime > to_date('{lastTime.ToString("yyyy-MM-dd HH:mm:ss")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
logger.Info(sqlStr);
|
|
var list = new List<ShiborModel>();
|
|
db.ExecuteSql(sqlStr, dr =>
|
|
{
|
|
var c = new ShiborModel
|
|
{
|
|
TradingDay = dr.GetDateTime(0),
|
|
ReportPeriod = dr.GetInt32(1),
|
|
OfferedMaturity = dr.GetString(2),
|
|
WeightAveragePrice = dr.GetDouble(3),
|
|
UpdateTime = dr.GetDateTime(4)
|
|
};
|
|
list.Add(c);
|
|
});
|
|
foreach (var item in list)
|
|
{
|
|
var code = item.OfferedMaturity + item.ReportPeriod;
|
|
logger.Info($"{code},{item.WeightAveragePrice},{item.UpdateTime}");
|
|
Flow(key, valueDate, optTime, code, item.WeightAveragePrice, item.UpdateTime);
|
|
}
|
|
logger.Info($"SyncShibor完成");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 回购定盘利率
|
|
/// </summary>
|
|
/// <param name="db"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="optTime"></param>
|
|
private void SyncBaseRate(DbHelper db, DateTime valueDate, DateTime optTime)
|
|
{
|
|
logger.Info("SyncBaseRate开始");
|
|
var dbName = "";
|
|
if (!string.IsNullOrEmpty(database))
|
|
dbName = database + ".";
|
|
var key = "FRR";
|
|
var sqlStr = "SELECT FR001,FR007,FR014,FDR001,FDR007,FDR014,GC001,GC007,UpdateTime FROM " + dbName + "Bond_BaseRateReference WHERE {0} ORDER BY UpdateTime";
|
|
var lastTime = runInfo[key].RealtimeData;
|
|
if (lastTime == default)
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"EndDate = to_date('{optTime.ToString("yyyy-MM-dd")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
else
|
|
{
|
|
sqlStr = string.Format(sqlStr, $"UpdateTime > to_date('{lastTime.ToString("yyyy-MM-dd HH:mm:ss")}', 'yyyy-MM-dd HH24:mi:ss')");
|
|
}
|
|
logger.Info(sqlStr);
|
|
var list = new List<BaseRateModel>();
|
|
db.ExecuteSql(sqlStr, dr =>
|
|
{
|
|
var c = new BaseRateModel
|
|
{
|
|
FR001 = dr[0] == DBNull.Value ? 0 : dr.GetDouble(0),
|
|
FR007 = dr[1] == DBNull.Value ? 0 : dr.GetDouble(1),
|
|
FR014 = dr[2] == DBNull.Value ? 0 : dr.GetDouble(2),
|
|
FDR001 = dr[3] == DBNull.Value ? 0 : dr.GetDouble(3),
|
|
FDR007 = dr[4] == DBNull.Value ? 0 : dr.GetDouble(4),
|
|
FDR014 = dr[5] == DBNull.Value ? 0 : dr.GetDouble(5),
|
|
GC001 = dr[6] == DBNull.Value ? 0 : dr.GetDouble(6),
|
|
GC007 = dr[7] == DBNull.Value ? 0 : dr.GetDouble(7),
|
|
UpdateTime = dr[8] == DBNull.Value ? DateTime.MinValue : dr.GetDateTime(8),
|
|
};
|
|
list.Add(c);
|
|
});
|
|
foreach (var item in list)
|
|
{
|
|
Flow(key, valueDate, optTime, nameof(item.FR001), item.FR001, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.FR007), item.FR007, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.FR014), item.FR014, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.FDR001), item.FDR001, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.FDR007), item.FDR007, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.FDR014), item.FDR014, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.GC001), item.GC001, item.UpdateTime);
|
|
Flow(key, valueDate, optTime, nameof(item.GC007), item.GC007, item.UpdateTime);
|
|
}
|
|
logger.Info($"SyncBaseRate完成");
|
|
}
|
|
|
|
#region 镒链系统相关逻辑
|
|
|
|
private void Flow(string key, DateTime valueDate, DateTime optTime, string code, double price, DateTime updateTime)
|
|
{
|
|
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(code);
|
|
if (um == null)
|
|
{
|
|
return;
|
|
}
|
|
um.Price = price;
|
|
um.LastUpdateTime = updateTime;
|
|
UpdateRealTimePrice(um);
|
|
if (runInfo[key].RealtimeData < updateTime)
|
|
{
|
|
runInfo[key].RealtimeData = updateTime;
|
|
}
|
|
|
|
if (DateTime.Now.Hour > 15 /*&& DateTime.Now.Hour < 18*/)
|
|
{
|
|
UpdateEodPrice(valueDate, optTime, updateTime, um);
|
|
UpdatePrevClosePrice(key);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新前日收盘价
|
|
/// </summary>
|
|
/// <param name="commodityCode"></param>
|
|
/// <returns></returns>
|
|
private int UpdatePrevClosePrice(string commodityCode)
|
|
{
|
|
var sqlStr = $"UPDATE underlying_manager SET PrevClosePrice = Price WHERE CommodityCode = '{commodityCode}';";
|
|
return ylDb.Database.ExecuteSqlRaw(sqlStr);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新日终价格
|
|
/// </summary>
|
|
/// <param name="valueDate"></param>
|
|
/// <param name="optTime"></param>
|
|
/// <param name="updateTime"></param>
|
|
/// <param name="um"></param>
|
|
/// <returns></returns>
|
|
private int UpdateEodPrice(DateTime valueDate, DateTime optTime, DateTime updateTime, underlying_manager um)
|
|
{
|
|
var sqlStr = $"UPDATE eod_stock_price SET ClosePrice = {um.Price},HighPrice = {um.Price},LowPrice = {um.Price},OptDate = '{optTime.ToString("yyyy-MM-dd HH:mm:ss")}',SourceTime = '{updateTime.ToString("yyyy-MM-dd HH:mm:ss")}' WHERE ValueDate = '{updateTime.ToString("yyyy-MM-dd")}' AND StockId = '{um.UnderlyingCode}'";
|
|
return ylDb.Database.ExecuteSqlRaw(sqlStr);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新实时价格
|
|
/// </summary>
|
|
/// <param name="um"></param>
|
|
/// <returns></returns>
|
|
private int UpdateRealTimePrice(underlying_manager um)
|
|
{
|
|
var sqlStr = $"UPDATE underlying_manager SET Price = {um.Price},LastUpdateTime = '{um.LastUpdateTime?.ToString("yyyy-MM-dd HH:mm:ss")}' WHERE UnderlyingCode = '{um.UnderlyingCode}'";
|
|
return ylDb.Database.ExecuteSqlRaw(sqlStr);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化日终价格
|
|
/// <para>存在则更新,不存在则插入</para>
|
|
/// </summary>
|
|
/// <param name="valueDate">估值日期</param>
|
|
/// <param name="optTime">操作时间</param>
|
|
/// <returns></returns>
|
|
private int InitEodPrice(DateTime valueDate, DateTime optTime, string commodityCode)
|
|
{
|
|
var count = 0;
|
|
var ums = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().Where(O => commodityCode == O.CommodityCode);
|
|
foreach (var um in ums)
|
|
{
|
|
propertiesDict["ValueDate"] = $"'{(um.LastUpdateTime?.Date ?? optTime.Date).ToString("yyyy-MM-dd")}'";
|
|
propertiesDict["StockId"] = $"'{um.UnderlyingCode}'";
|
|
propertiesDict["ClosePrice"] = $"{um.Price ?? 0}";
|
|
propertiesDict["HighPrice"] = $"{um.Price ?? 0}";
|
|
propertiesDict["LowPrice"] = $"{um.Price ?? 0}";
|
|
propertiesDict["OptDate"] = $"'{optTime.ToString("yyyy-MM-dd HH:mm:ss")}'";
|
|
propertiesDict["DataSource"] = $"'系统'";
|
|
propertiesDict["ReferencePrice"] = um.Price == null ? "null" : $"{um.Price}";
|
|
propertiesDict["UnderlyingStatus"] = $"'正常运行'";
|
|
|
|
count += ylDb.Database.ExecuteSqlRaw(GetSqlFromPropertiesDict(propertiesDict));
|
|
}
|
|
return count;
|
|
}
|
|
|
|
private string GetSqlFromPropertiesDict(Dictionary<string, string> dict)
|
|
{
|
|
var keys = string.Join(",", dict.Keys);
|
|
var values = string.Join(",", dict.Values);
|
|
var sql = $"REPLACE INTO eod_stock_price({keys}) VALUES ({values})";
|
|
|
|
return sql;
|
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
#region 内部结构
|
|
|
|
private class CbYieldCurveModel
|
|
{
|
|
public string CurveCode { get; set; }
|
|
|
|
public int YearsToMaturity { get; set; }
|
|
|
|
public double Yield { get; set; }
|
|
|
|
public DateTime UpdateTime { get; set; }
|
|
}
|
|
|
|
private class IrsCurveModel
|
|
{
|
|
public string CueveName { get; set; }
|
|
|
|
public double MaturityYield { get; set; }
|
|
|
|
public DateTime UpdateTime { get; set; }
|
|
}
|
|
|
|
private class ShiborModel
|
|
{
|
|
public DateTime TradingDay { get; set; }
|
|
|
|
public int ReportPeriod { get; set; }
|
|
|
|
public string OfferedMaturity { get; set; }
|
|
|
|
public double WeightAveragePrice { get; set; }
|
|
|
|
public DateTime UpdateTime { get; set; }
|
|
}
|
|
|
|
private class BaseRateModel
|
|
{
|
|
public double FR001 { get; set; }
|
|
|
|
public double FR007 { get; set; }
|
|
|
|
public double FR014 { get; set; }
|
|
|
|
public double FDR001 { get; set; }
|
|
|
|
public double FDR007 { get; set; }
|
|
|
|
public double FDR014 { get; set; }
|
|
|
|
public double GC001 { get; set; }
|
|
|
|
public double GC007 { get; set; }
|
|
|
|
public DateTime UpdateTime { get; set; }
|
|
}
|
|
|
|
private class UpdatetimeModel
|
|
{
|
|
/// <summary>
|
|
/// 实时价格更新时间
|
|
/// </summary>
|
|
public DateTime RealtimeData { get; set; }
|
|
/// <summary>
|
|
/// 日终价格更新时间
|
|
/// </summary>
|
|
public DateTime EodData { get; set; }
|
|
|
|
public UpdatetimeModel()
|
|
{
|
|
RealtimeData = DateTime.MinValue;
|
|
EodData = DateTime.MinValue;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|