429 lines
16 KiB
C#
429 lines
16 KiB
C#
using System.Text;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Enums;
|
|
using YLErp.Modules.SalesModule;
|
|
using YLErp.Modules.TagModule;
|
|
using YLErp.Modules.TradeModule;
|
|
using YLErp.Modules.TradeModule.AccumulatorOptionModule;
|
|
using YLErp.Modules.TradeModule.DocGenerateModule;
|
|
using YLErp.Modules.TradeModule.OrderModule;
|
|
using YLErp.Modules.TradeModule.QueryModule;
|
|
|
|
namespace YLErp.Web.Controllers
|
|
{
|
|
public partial class tradeController
|
|
{
|
|
/// <summary>
|
|
/// 交易编辑
|
|
/// </summary>
|
|
public ActionResult TradeEditV2(string enid)
|
|
{
|
|
var model = new TradeEditViewModel(CurUser, UserBLL.IsTradeOfCurrentLogin(CurUser.UserId));
|
|
|
|
if (string.IsNullOrEmpty(enid) || enid == "0")
|
|
{
|
|
if (!CurUser.交易管理_交易新增)
|
|
{
|
|
throw new Exception("没有新增权限");
|
|
}
|
|
|
|
var valuedate = valuedateBLL.ValueDate;
|
|
|
|
model.Trade = new OtcOptionTradeFull()
|
|
{
|
|
TradeType = "香草期权",
|
|
StartDate = valuedate,
|
|
Notional = 1,
|
|
TradeAmount = 1,
|
|
ExerciseMode = ConsTrade.ExerciseType.European,
|
|
TradeDate = valuedate,
|
|
PremiumPayDate = valuedate,
|
|
TraderId = UserId,
|
|
TraderName = UserName,
|
|
UnderlyingInstrumentType = AppHelper.OtcConfig.StockFirst ? ConsGlobal.InstrumentType.Stock : ConsGlobal.InstrumentType.CommodityFutures,
|
|
IsMoneynessOption = "否",
|
|
AveragingPeriodStartDate = valuedate,
|
|
AnnualizeFactor = 1,
|
|
IsUsePremiumRate = false,
|
|
IsTradePricePayType = false,
|
|
BuySell = ConsTrade.BuySellType.Sell,
|
|
OptionType = ConsTrade.OptionType.Call,
|
|
MarginTemplateName = "系统默认",
|
|
OpponentRole = "乙方",
|
|
CouponIncludeStartDate = false,
|
|
CouponPercent = true,
|
|
CouponUsePaymentDate = PS.Config.Company == Configuration.CompanyEnum.天风
|
|
};
|
|
|
|
if (PS.Config.IsTradeVol && ("&" + PS.Config.ErpElement.TradePricingCfg + "&").Contains("&平滑过渡天数=ONE&"))
|
|
{
|
|
model.Trade.NumOfSmoothingDays = 1;
|
|
}
|
|
ViewBag.StructureTypeMap = GetStructureMap(StructureRangeEnum.CUSTOM_TRADE);
|
|
ViewBag.ExtendInfoMap = new Dictionary<string, List<Structure_Details>>();
|
|
var map = GetStructureMap(StructureRangeEnum.EXTEND_INFO);
|
|
ViewBag.ExtendInfoMap[""] = new List<Structure_Details>();
|
|
foreach (var item in map)
|
|
{
|
|
ViewBag.ExtendInfoMap[item.Key] = item.Value;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var intid = DecryptInt(enid);
|
|
|
|
var td = new TradeDetailsQueryService(CurUser).GetOtcTradeFull(intid);
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("找不到交易数据");
|
|
}
|
|
if (ConsTrade.审批中 != td.TradeStatus)
|
|
{
|
|
if (!CurUser.交易管理_交易编辑 && !(ConsTrade.已拒绝 == td.TradeStatus && td.TraderId == CurUser.UserId))
|
|
{
|
|
throw new Exception("没有编辑权限");
|
|
}
|
|
}
|
|
|
|
new OptionTradeActionRestoreService(CurUser).RestoreTradeDataForEditiing(td, out var restoredActions);
|
|
|
|
if (restoredActions != null)
|
|
{
|
|
model.RestoredActions = restoredActions.Select(n =>
|
|
{
|
|
switch (n)
|
|
{
|
|
case TradeActionType.AccumulatorChange: return "换月";
|
|
default: return string.Empty;
|
|
}
|
|
}).ToList();
|
|
}
|
|
|
|
var tradeCheck = db.trade_check.FirstOrDefault(t => t.TradeId == td.id && t.ValidState != ConsGlobal.InValid);
|
|
|
|
if (tradeCheck != null)
|
|
{
|
|
var reviewTrade = tradeCheck.TradeModel;
|
|
var saveTrade = TradeConverter.ConvertOptionTrade(td);
|
|
model.DiffList = TradeCheckUtil.GetDiffs(saveTrade, reviewTrade);
|
|
}
|
|
|
|
model.Trade = td;
|
|
|
|
if (!td.IsUsePremiumRate.HasValue)
|
|
{
|
|
td.IsUsePremiumRate = false;
|
|
}
|
|
td.DurationDays = null;
|
|
td.SalesCommission = new SalesCommissionDataService(CurUser).GetTradeCommissionInfo(td.id);
|
|
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1")
|
|
{//计提法只支持百分比;
|
|
if (td.SalesCommission.Commission.Normalize() == 0)
|
|
{
|
|
td.SalesCommission.Commission = 1;
|
|
td.SalesCommission.CommissionFixed = false;
|
|
}
|
|
else
|
|
{
|
|
td.SalesCommission.Commission = td.SalesCommission.Commission * td.SalesCommission.SalesIds.Count();
|
|
}
|
|
}
|
|
td.OpponentRole = td.OpponentRole ?? "乙方";
|
|
|
|
var underying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingId);
|
|
td.CountRatio = underying?.CountRatio ?? 1;
|
|
if (!td.CouponIncludeStartDate.HasValue)
|
|
{
|
|
td.CouponIncludeStartDate = false;
|
|
}
|
|
if (!td.CouponUsePaymentDate.HasValue)
|
|
{
|
|
td.CouponUsePaymentDate = false;
|
|
}
|
|
if (td.TradeType == "累计期权")
|
|
{
|
|
// if (PS.Config.Company == Configuration.CompanyEnum.国泰君安)
|
|
if (PS.Config.ErpElement.AccumulatorShowMultiplier1)
|
|
{
|
|
td.StrikeGearingFactor = td.OptionType == "看涨" ? td.PutMultiplier : td.CallMultiplier;
|
|
}
|
|
}
|
|
else if (td.TradeType == "雪球期权")
|
|
{
|
|
td.CouponDayCount = td.CouponDayCount.TrimToEmpty();
|
|
}
|
|
ViewBag.StructureTypeMap = GetStructureMap(StructureRangeEnum.CUSTOM_TRADE, td, td.StructureType);
|
|
td.MetaDic.TryGetValue(ConsTradeMetaKey.tradeExtendInfo, out var structureType);
|
|
var map = GetStructureMap(StructureRangeEnum.EXTEND_INFO, td, structureType);
|
|
ViewBag.ExtendInfoMap = new Dictionary<string, List<Structure_Details>>();
|
|
ViewBag.ExtendInfoMap[""] = new List<Structure_Details>();
|
|
foreach (var item in map)
|
|
{
|
|
ViewBag.ExtendInfoMap[item.Key] = item.Value;
|
|
}
|
|
|
|
using (var tagService = new TagService(CurUser))
|
|
{
|
|
model.Tags = tagService.GetTagByTradeId(intid);
|
|
}
|
|
}
|
|
|
|
return View("TradeEditV2", model);
|
|
}
|
|
|
|
//保存交易
|
|
public JsonResult AjaxSaveTradeV2(OtcOptionTradeFull trade)
|
|
{
|
|
if (trade is null)
|
|
{
|
|
return JsonError("没有交易数据");
|
|
}
|
|
var dbTrade = new OtcTradeSaveService(CurUser).SaveOptionTradesFromTradeEdit(trade);
|
|
return JsonSuccess("录入交易成功", new { dbTrade.EncryptId });
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导出交易摘要
|
|
/// </summary>
|
|
public ActionResult ExportTradeAbstractInfo(TradeReq req)
|
|
{
|
|
req.LoginUserId = CurUser.UserId;
|
|
|
|
req.AssetIdList = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIdList).ToList();
|
|
req.CurUserTradeIds = CurUser.GetTradeIdsByCurUser();
|
|
|
|
req.IsContainsGroup = true;
|
|
var sList = new tradeBLL().SearchTradeList(req);
|
|
|
|
if (sList == null | sList.Count <= 0)
|
|
{
|
|
return Content("", "text/plain");
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
foreach (var trade in sList)
|
|
{
|
|
if (trade.ParentTradeId > 0 && trade.IsGroup == 2)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (trade.TradeType == "累计期权")
|
|
{
|
|
new OptionTradeActionRestoreService(CurUser).RestoreTradeDataToSpecialDay(trade, trade.TradeDate.Value);
|
|
}
|
|
var text = TradeAbstractService.GetTradeAbstractInfoText(trade);
|
|
var index = text.IndexOf("####");
|
|
var bodyText = text.Substring(index + 4 + 2);
|
|
if (sb.Length < 1)
|
|
{
|
|
sb.Append(text.Substring(0, index));
|
|
}
|
|
sb.AppendLine(text.Substring(index + 4 + 2)).AppendLine().AppendLine();
|
|
}
|
|
|
|
return Content(sb.ToString(), "text/plain");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导出交易了结摘要
|
|
/// </summary>
|
|
public ActionResult ExportTradeSettlementAbstractInfo(TradeMultiCloseQueryModel queryModel)
|
|
{
|
|
if (queryModel.PageSize == 0)
|
|
{
|
|
queryModel.PageIndex = 1;
|
|
queryModel.PageSize = 10000;
|
|
}
|
|
queryModel.UserAssets = CurUser.GetAssetUnitIds();
|
|
queryModel.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
|
|
var datas = new OtcOptionMultiCloseService(CurUser).GetSettlementList(queryModel);
|
|
|
|
if (datas == null | datas.Count <= 0)
|
|
{
|
|
return Content("", "text/plain");
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
foreach (var kv in datas)
|
|
{
|
|
var trade = kv.Key;
|
|
tradeBLL.SetFieldsByTradeType(trade);
|
|
if (trade.TradeType == "累计期权")
|
|
{
|
|
new OptionTradeActionRestoreService(CurUser).RestoreTradeDataToSpecialDay(trade, kv.Value.ValueDate);
|
|
}
|
|
var text = TradeTerminationAbstractService.GetAbstractInfoText(kv.Value, trade, kv.Value.Action.Contains("平仓费"), true, true);
|
|
var index = text.IndexOf("####");
|
|
var bodyText = text.Substring(index + 4 + 2);
|
|
if (sb.Length < 1)
|
|
{
|
|
sb.Append(text.Substring(0, index));
|
|
}
|
|
sb.AppendLine(text.Substring(index + 4 + 2)).AppendLine().AppendLine();
|
|
}
|
|
|
|
return Content(sb.ToString(), "text/plain");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量删除当日交易‘新增待确认’状态的交易
|
|
/// </summary>
|
|
public JsonResult AjaxInvalidTodayUnconfirmedTrades(IEnumerable<int> ids)
|
|
{
|
|
if (ids is null)
|
|
{
|
|
return JsonError("参数错误");
|
|
}
|
|
|
|
var count = new TradeInvalidService(CurUser).InvalidTodayUnconfirmedTrades(ids.ToHashSet());
|
|
|
|
return JsonSuccess($"已删除{count}条'新增待确认'状态的交易!");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取用印失败信息
|
|
/// </summary>
|
|
/// <param name="code"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult GetSealErrMsg(string code)
|
|
{
|
|
var msg = new ConfirmationGenerateService(CurUser).GetSealErrMsg(code);
|
|
|
|
return JsonSuccess(msg);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断用印是否在等待
|
|
/// </summary>
|
|
/// <param name="code"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult IsSealWaiting(int tradeId)
|
|
{
|
|
var result = new ConfirmationGenerateService(CurUser).IsSealWaiting(tradeId);
|
|
|
|
return result ? JsonSuccess() : JsonError();
|
|
}
|
|
|
|
#region---累计期权换月-----
|
|
|
|
/// <summary>
|
|
/// 操作页面
|
|
/// </summary>
|
|
public ActionResult AccumulatorChange(string enid)
|
|
{
|
|
var intid = DataProtectHelper.DecryptInt(enid);
|
|
var td = db.trade.AsNoTracking().Where(n => n.id == intid).FirstOrDefault();
|
|
if (td == null)
|
|
{
|
|
return JsonError("找不到交易数据");
|
|
}
|
|
tradeBLL.SetFieldsByTradeType(td);
|
|
var service = new TradeAccumulatorChangeService(CurUser);
|
|
var changeData = service.GetChangeData(valuedateBLL.ValueDate, td, td.trade_accumulator_option);
|
|
var model = new TradeAccumulatorChangeModel
|
|
{
|
|
TradeId = intid,
|
|
ChangeData = changeData,
|
|
HisDataList = service.GetHisDatas(intid),
|
|
TradeStatus = td.TradeStatus,
|
|
IsMoneyness = td.IsMoneynessOptionData,
|
|
ValueDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd"),
|
|
TradeDate = td.TradeDate.Value.ToString("yyyy-MM-dd"),
|
|
ExerciseDate = td.ExerciseDate.Value.ToString("yyyy-MM-dd"),
|
|
Coupon = td.trade_accumulator_option.Coupon,
|
|
PayoffType = td.trade_accumulator_option.PayoffType,
|
|
CouponPercent = td.trade_accumulator_option.CouponPercent
|
|
};
|
|
return View(model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取换月数据
|
|
/// </summary>
|
|
public JsonResult AjaxGetAccumulatorChangeData(DateTime valueDate, int tradeId)
|
|
{
|
|
var td = db.trade.AsNoTracking().Where(n => n.id == tradeId).FirstOrDefault();
|
|
if (td == null)
|
|
{
|
|
return JsonError("找不到交易数据");
|
|
}
|
|
var service = new TradeAccumulatorChangeService(CurUser);
|
|
var changeData = service.GetChangeData(valueDate, td, null);
|
|
return JsonSuccessData(changeData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存换月数据
|
|
/// </summary>
|
|
public JsonResult AjaxSaveAccumulatorChangeData(int tradeId, TradeAccumulatorChangeData data, bool removeChecks)
|
|
{
|
|
var service = new TradeAccumulatorChangeService(CurUser);
|
|
var result = service.SaveChangeData(tradeId, data, removeChecks);
|
|
return JsonSuccessData(new
|
|
{
|
|
result.TradeUpdated,
|
|
changeDatas = TradeAccumulatorHelper.GetChangeDatas(result.Actions)
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除换月数据
|
|
/// </summary>
|
|
public JsonResult AjaxRemoveAccumulatorChangeData(DateTime valueDate, int tradeId)
|
|
{
|
|
var result = new TradeAccumulatorChangeService(CurUser).RemoveChangeData(valueDate, tradeId);
|
|
return JsonSuccessData(new
|
|
{
|
|
result.TradeUpdated,
|
|
changeDatas = TradeAccumulatorHelper.GetChangeDatas(result.Actions)
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断标的是否为组合标的
|
|
/// </summary>
|
|
/// <param name="codes"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult IsCodesExistsCommoditySpot(string[] codes)
|
|
{
|
|
var result = new OtcTradeSaveService(CurUser).IsCodesExistsCommoditySpot(codes);
|
|
return JsonSuccessData(result);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 判断确认书是否生成过
|
|
/// </summary>
|
|
/// <param name="tradeIds"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult IsContractGenerated(List<int> ids,List<string> types)
|
|
{
|
|
var result = new ConfirmationGenerateService(CurUser).IsContractGenerated(ids,types);
|
|
|
|
return result ? JsonSuccess() : JsonError("有确认书未生成,请在用印前先生成确认书!");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量确认书用印
|
|
/// </summary>
|
|
/// <param name="tradeIds"></param>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public JsonResult SealContracts(List<int> ids,List<string> types)
|
|
{
|
|
new ConfirmationGenerateService(CurUser).SealContracts(ids,types);
|
|
return JsonSuccess("用印等待中...");
|
|
}
|
|
}
|
|
}
|