using System.Data;
using YLErp.BLL;
namespace YLErp.Modules.SkewMapVolModule
{
public class VolSkewMapDbInitializer : IVolSkewMapInitializer
{
///
/// 从数据库表读取SkewMapData
///
///
public DataTable GetSkewMapData(bool isBuy)
{
if (isBuy)
{
if (_bidTable == null)
{
var rawTable = ReadDataFromDb(isBuy);
if (rawTable == null)
{
return null;
}
_bidTable = ExpandSkewMap(rawTable);
}
return _bidTable;
}
else
{
if (_askTable == null)
{
var rawTable = ReadDataFromDb(isBuy);
if (rawTable == null)
{
return null;
}
_askTable = ExpandSkewMap(rawTable);
}
return _askTable;
}
}
public bool SetSkewMapData(string table, bool isBuy)
{
if (SaveDataToDb(table, isBuy))
{
var rawTable = ReadDataFromDb(isBuy);
if (isBuy)
{
_bidTable = ExpandSkewMap(rawTable);
}
else
{
_askTable = ExpandSkewMap(rawTable);
}
return true;
}
return false;
}
private static DataTable ExpandSkewMap(DataTable base_map)
{
int[] base_var = { 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
var target_var = new int[50];
for (int i = 0; i < 50; i++)
{
target_var[i] = i + 1;
}
var tb = new DataTable();
tb.Columns.Add("term", System.Type.GetType("System.Double"));
tb.Columns.Add("moneyness", System.Type.GetType("System.Double"));
tb.Columns.Add("basevol", System.Type.GetType("System.Double"));
foreach (int i in target_var)
{
tb.Columns.Add(i.ToString(), System.Type.GetType("System.Double"));
}
foreach (DataRow dr in base_map.Rows)
{
var r = tb.NewRow();
r[0] = Convert.ToSingle(dr["term"]);
r[1] = Convert.ToSingle(dr["moneyness"]);
r[2] = Convert.ToSingle(dr["basevol"]);
int loc = 3;
foreach (int v in target_var)
{
var var_col = v.ToString();
if (base_var.Contains(v))
{
r[loc] = Convert.ToSingle(dr[var_col]);
}
else
{
int l_var = base_var.Where(b => b < v).Last();
int h_var = base_var.Where(b => b > v).First();
float l_v = Convert.ToSingle(dr[l_var.ToString()]);
float h_v = Convert.ToSingle(dr[h_var.ToString()]);
float n_value = l_v + (v - l_var) * (h_v - l_v) / (h_var - l_var);
r[loc] = n_value;
}
loc++;
}
tb.Rows.Add(r);
}
return tb;
}
private static DataTable ReadDataFromDb(bool isBuy)
{
using (var db = new YLContext())
{
var skewMapType = ConvertToSkewMapType(isBuy);
var skewMap = db.globalSkewMap.FirstOrDefault(x => x.SkewMapType == skewMapType);
if (skewMap == null || string.IsNullOrWhiteSpace(skewMap.SkewMapTableData))
{
return null;
}
var tb = new DataTable();
var rows = skewMap.SkewMapTableData.Split('\n');
for (int i = 0; i < rows.Count() - 1; i++)
{
var rowValues = rows[i].Split(',');
if (i == 0)
{
//tb.Columns.Add(rowValues[0].Trim());
for (int j = 0; j < rowValues.Count(); j++)
{
tb.Columns.Add(rowValues[j].Trim());
}
}
else
{
var dr = tb.NewRow();
for (int k = 0; k < rowValues.Count(); k++)
{
dr[k] = Convert.ToSingle(rowValues[k]);
}
tb.Rows.Add(dr);
}
}
return tb;
}
}
private static bool SaveDataToDb(string tableStr, bool isBuy)
{
try
{
var skewMapType = ConvertToSkewMapType(isBuy);
using (var db = new YLContext())
{
var existingRecord = db.globalSkewMap.FirstOrDefault(x => x.SkewMapType == skewMapType);
if (existingRecord == null)
{
existingRecord = new Model.GlobalSkewMap
{
SkewMapTableData = tableStr,
SkewMapType = skewMapType,
UpdateTime = DateTime.Now
};
db.globalSkewMap.Add(existingRecord);
}
else
{
existingRecord.SkewMapTableData = tableStr;
existingRecord.UpdateTime = DateTime.Now;
}
db.SaveChanges();
}
return true;
}
catch (Exception)
{
return false;
}
}
private static string ConvertToSkewMapType(bool isBuy)
{
return isBuy ? "Bid" : "Ask";
}
private DataTable _bidTable = null;
private DataTable _askTable = null;
}
}