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; } }