314 lines
11 KiB
C#
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();
|
|
}
|
|
}
|
|
} |