Files
zszq-trs/YLErpWeb/Controllers/skewMapController.cs
T
2024-05-09 14:06:26 +08:00

314 lines
11 KiB
C#

using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using YLErp.Commons;
using YLErp.Modules.SkewMapVolModule;
using YLErp.Modules.VolatilityModule;
using YLErp.QdpModule;
using YLErp.QdpModule.Constants;
namespace YLErp.Web.Controllers
{
[MyAuthorizeIgnore]
public class skewMapController : BaseController
{
public ActionResult Index()
{
return View(new BasicViewModel(CurUser));
}
public ActionResult GetBaseVol(string underlyingCode, DateTime valueDate)
{
if (QdpCalendarHelper.IsHoliday(valueDate))
{
return JsonSuccess();
}
var vol = VolatilityHelper.GetVol(valueDate, "交易", underlyingCode, null);
return JsonSuccessData(vol);
}
public ActionResult SetBaseVol(volatility vol)
{
if (vol is null)
{
throw new ArgumentNullException(nameof(vol));
}
var un = yldb.underlying_manager.Where(n => n.UnderlyingCode == vol.ContractCode)
.Select(n => new { n.id }).FirstOrDefault();
if (un == null)
{
return JsonError("标的信息不存在:" + vol.ContractCode);
}
vol.UnderlyingId = un.id;
vol.VolType = "交易";
vol.VolSurfaceMode = "MoneynessVol";
vol.InterpolationMethod = ConsVolMethod.BiLinear;
vol.OptDate = DateTime.Now;
var cur_vol = new VolatilitySaveService(CurUser).SaveVol(vol);
return JsonSuccessData(cur_vol.First());
}
/// <summary>
/// 上传SkewMap文件CSV
/// </summary>
public ActionResult UploadSkewMap(string skewMapType)
{
if (string.IsNullOrEmpty(skewMapType))
{
return Json(Return.Fail("skewMapType 不应为空"));
}
var files = Request.Form.Files;
if (files == null || files.Count == 0)
{
return Json(Return.Fail("上传文件不存在"));
}
if (files[0].Length < 1)
{
return Json(Return.Fail("上传文件内容为空"));
}
try
{
using var stream = files[0].OpenReadStream();
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
var content = Encoding.UTF8.GetString(ms.ToArray());
var result = VolSkewMapInitializerSingleton.Instance.SetSkewMapData(content, skewMapType.ToLower() == "bid");
return result ? JsonSuccess("成功") : JsonError("失败");
}
}
catch (Exception ex)
{
return JsonError("保存失败," + ex.Messages());
}
}
/// <summary>
/// 下载SkewMap文件CSV
/// </summary>
public ActionResult DownLoadSkewMap(string type)
{
try
{
using (var db = new YLContext())
{
var queryObj = db.globalSkewMap.FirstOrDefault(O => O.SkewMapType == type);
if (queryObj == null)
{
return ShowError("文件不存在");
}
var buffer = Encoding.UTF8.GetBytes(queryObj.SkewMapTableData);
return File(buffer, "application/ms-excel", $"SkewMap-{type}.csv");
}
}
catch (Exception e)
{
return ShowError("下载失败," + e.Messages());
}
}
/// <summary>
/// 上传BaseVol文件Excel
/// </summary>
public ActionResult UploadBaseVol()
{
var files = Request.Form.Files;
if (files == null || files.Count == 0)
{
return Json(Return.Fail("上传文件不存在"));
}
var helper = new ExcelHelper();
using var stream = files[0].OpenReadStream();
var dt = helper.ExcelToDataTable(stream, "Sheet1", false);
if (dt.Columns.Count != 2)
{
return Json(Return.Fail("数据格式有误"));
}
var StrikeRow = 0;
var volatilitys = new List<volatility>();
var unProvider = Modules.DataCacheProvider.GetUnderlyingDataSource();
volatility volObj = null;
List<SingleVol> singleVols = null;
for (var i = 0; i < dt.Rows.Count; i++)
{
var drow = dt.Rows[i];
if (string.IsNullOrWhiteSpace(drow[0]?.ToString()))
{
volObj.Data = singleVols.ToJson();
StrikeRow = i + 1;
continue;
}
if (StrikeRow == i)
{
var code = drow[0]?.ToString();
var strike = double.Parse(dt.Rows[StrikeRow][1].ToString());
if (OtcFormatHelper.FormatValue(strike, 2) != 1)
{
return Json(Return.Fail($"{code}的 Strike 不为 1"));
}
var info = unProvider.GetData(code);
if (info == null)
{
return JsonError("标的信息不存在:" + code);
}
if (info.IsFutures() && info.MaturityDate < valuedateBLL.ValueDate)
{
return JsonError("标的已过期:" + code);
}
volObj = new volatility
{
ContractCode = drow[0]?.ToString(),
UnderlyingId = info?.id,
QuotationDate = valuedateBLL.ValueDate,
VolType = "交易",
VolSurfaceMode = "MoneynessVol",
InterpolationMethod = ConsVolMethod.BiLinear,
OptDate = DateTime.Now
};
if (!volatilitys.Exists(O => O.ContractCode == code))//如果存在重复代码则以第一条为准
{
volatilitys.Add(volObj);
}
singleVols = new List<SingleVol>();
continue;
}
singleVols.Add(new SingleVol()
{
Expire = drow[0]?.ToString(),
Strike = double.Parse(dt.Rows[StrikeRow][1].ToString()),
Vol = double.Parse(drow[1].ToString())
});
}
if (volObj != null && volatilitys[volatilitys.Count - 1].Data == null)
{
volObj.Data = singleVols.ToJson();
}
new VolatilitySaveService(CurUser).SaveVols(volatilitys);
return JsonSuccess();
}
/// <summary>
/// 下载BaseVol文件Excel
/// </summary>
public ActionResult DownLoadBaseVol(DateTime valueDate, string underlyingCode, bool query = false)
{
byte[] buffer = null;
try
{
var list = new VolatilityQueryService(CurUser).GetVolatilities(new BatchVolatilityRequest
{
QuotationDate = valueDate,
UnderlyingCodes = string.IsNullOrEmpty(underlyingCode) ? null : new[] { underlyingCode },
TradeVolWithBidAsk = true,
UserGroup = CurUser.UserGroup,
VolType = "交易"
}, false);
if (list == null || !list.Any())
{
return Json(Return.Fail("数据不存在"));
}
if (query)//如果只是查询数据是否存在,则只返回错误信息或数量;
{
return JsonSuccessData(list.Count());
}
list = list.OrderBy(O => O.ContractCode).ToList();
var dt = new DataTable();
var StrikeRow = 0;
dt.Columns.Add();
dt.Columns.Add();
foreach (var item in list)
{
dt.Rows.Add();
dt.Rows[StrikeRow][0] = item.ContractCode;
var vos = item.VolTable;
vos.Sort((X, Y) =>
{
if (X == null) { return -1; }
if (Y == null) { return 1; }
return ExpireToDay(X.Expire) - ExpireToDay(Y.Expire);
});
for (var j = 0; j < vos.Count; j++)
{
dt.Rows.Add();
dt.Rows[StrikeRow][1] = vos[j].Strike;
dt.Rows[StrikeRow + j + 1][0] = vos[j].Expire;
dt.Rows[StrikeRow + j + 1][1] = vos[j].Vol;
}
dt.Rows.Add();
StrikeRow = StrikeRow + vos.Count + 2;
}
new ExcelHelper().DataTableToExcel(dt, "Sheet1", false, out buffer);
if (string.IsNullOrWhiteSpace(underlyingCode)) { underlyingCode = "All"; }
return File(buffer, "application/ms-excel", $"BaseVol-{valueDate:yyyy-MM-dd}-{underlyingCode}.xlsx");
}
catch (Exception e)
{
return ShowError("下载失败" + e.Message);
}
}
private int ExpireToDay(string expire)
{
var result = 0;
var m = Regex.Match(expire.ToUpper(), @"^(?<num>\d+)(?<unit>[D|W|M|Y])$");
if (!m.Success) { return 999; }
var num = int.Parse(m.Groups["num"].Value);
var unit = m.Groups["unit"].Value;
switch (unit)
{
case "D":
result = int.Parse(m.Groups["num"].Value);
break;
case "W":
result = int.Parse(m.Groups["num"].Value) * 7;
break;
case "M":
result = int.Parse(m.Groups["num"].Value) * 30;
break;
case "Y":
result = int.Parse(m.Groups["num"].Value) * 365;
break;
}
return result;
}
public ActionResult GetVarietyVol(int varietyId, DateTime valueDate)
{
var data = new VarietyVolService(CurUser).GetVol(varietyId, valueDate);
return JsonSuccessData(data);
}
public ActionResult SetVarietyVol(int varietyId, DateTime valueDate, double vol)
{
new VarietyVolService(CurUser).SaveData(varietyId, valueDate, vol);
return JsonSuccess();
}
}
}