789 lines
32 KiB
C#
789 lines
32 KiB
C#
using YLErp.BLL.Eod;
|
|
using YLErp.BLL.MarginCalculation;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Enums;
|
|
using YLErp.Model.Enum;
|
|
using YLErp.Models.Tag;
|
|
using YLErp.Modules.CalculationModule;
|
|
using YLErp.Modules.EodModule;
|
|
using YLErp.Modules.SalesModule;
|
|
using YLErp.Modules.TagModule;
|
|
using YLErp.Modules.TradeModule;
|
|
using YLErp.Modules.TradeModule.DealModule;
|
|
using YLErp.Modules.TradeModule.ForwardModule;
|
|
|
|
namespace YLErp.Web.Controllers
|
|
{
|
|
public class ForwardTradeController : OtcTradeControllerBase
|
|
{
|
|
private readonly YLContext db = new YLContext();
|
|
private readonly ErpBaseContext sysdb = new ErpBaseContext();
|
|
private static readonly object _LockBatchGenerateSettleBill = new object();
|
|
|
|
readonly IViewRenderService _viewRenderer;
|
|
|
|
public ForwardTradeController(IViewRenderService viewRenderer)
|
|
{
|
|
_viewRenderer = viewRenderer;
|
|
}
|
|
|
|
public ActionResult Index()
|
|
{
|
|
return View("TradeList");
|
|
}
|
|
|
|
[MyAuthorize("交易管理-远期交易")]
|
|
public ActionResult TradeList(int? tabIndex, string settleDate = null)
|
|
{
|
|
if (tabIndex <= 0 || tabIndex == null)
|
|
{
|
|
ViewBag.TabIndex = (int)TradeTabIndexEnum.场外衍生品交易;
|
|
}
|
|
else
|
|
{
|
|
ViewBag.TabIndex = tabIndex;
|
|
}
|
|
|
|
ViewBag.settleDate = settleDate;
|
|
|
|
return View();
|
|
}
|
|
|
|
public ActionResult TradeEditV2(string enid, bool isUseApproval = false)
|
|
{
|
|
OtcTradeForward td = null;
|
|
|
|
var isAdd = string.IsNullOrEmpty(enid) || enid == "0";
|
|
|
|
var model = new ForwardTradeEditModel(CurUser);
|
|
|
|
if (isAdd)
|
|
{
|
|
if (!CurUser.交易管理_交易新增)
|
|
{
|
|
throw new Exception("没有新增权限");
|
|
}
|
|
|
|
td = new OtcTradeForward()
|
|
{
|
|
TradeType = "远期",
|
|
Notional = 1,
|
|
ExerciseMode = "European",
|
|
TradeDate = valuedateBLL.ValueDate,
|
|
TraderId = UserId,
|
|
TraderName = UserName,
|
|
UnderlyingInstrumentType = "CommodityFutures",
|
|
OptionType = "看涨",
|
|
NoRiskRate = 0,
|
|
BuySell = "卖出",
|
|
Lots = 0,
|
|
TradeAmount = 0,
|
|
StructureType = "远期",
|
|
MarginTemplateName = "系统默认",
|
|
OpponentRole = "乙方"
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var intid = DataProtectHelper.DecryptInt(enid);
|
|
td = new TradeForwardService(CurUser).GetDetail(intid);
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("找不到交易数据");
|
|
}
|
|
if (ConsTrade.审批中 != td.TradeStatus)
|
|
{
|
|
if (!CurUser.交易管理_交易编辑 && !(ConsTrade.已拒绝 == td.TradeStatus && td.TraderId == CurUser.UserId))
|
|
{
|
|
throw new Exception("没有编辑权限");
|
|
}
|
|
}
|
|
|
|
var tradeCheck = db.trade_check.FirstOrDefault(t => t.TradeId == td.id && t.ValidState != "InValid");
|
|
if (tradeCheck != null)
|
|
{
|
|
var reviewTrade = tradeCheck.TradeModel;
|
|
var saveTrade = TradeConverter.ConvertForward(td);
|
|
model.DiffList = TradeCheckUtil.GetDiffs(saveTrade, reviewTrade);
|
|
}
|
|
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 == null ? "乙方" : td.OpponentRole;
|
|
using (var tagService = new TagService(CurUser))
|
|
{
|
|
model.Tags = tagService.GetTagByTradeId(intid);
|
|
}
|
|
}
|
|
|
|
model.Trade = td;
|
|
|
|
ViewBag.isUseApproval = isUseApproval;
|
|
using (var tagService = new TagService(CurUser))
|
|
{
|
|
ViewBag.TagList = tagService.GetTagListByType(TagTypeEnum.Trade);
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
public JsonResult TradeEditJson(OtcTradeForward req)
|
|
{
|
|
if (req == null)
|
|
{
|
|
return JsonError("数据不能为空");
|
|
}
|
|
var r = new TradeForwardService(CurUser).SaveData(req);
|
|
return JsonSuccess("更新成功", new { r.EncryptId });
|
|
}
|
|
|
|
#region 远期交易复核
|
|
|
|
public ActionResult TradeCheck2(int? enid)
|
|
{
|
|
var trade = new TradeCheckModel();
|
|
if (enid > 0)
|
|
{
|
|
trade = new TradeForwardService(CurUser).GetCheckTrade(enid);
|
|
if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD)
|
|
{
|
|
if (!trade.Trade.BasisUnderlyingCode.IsNullOrWhiteSpace())
|
|
{
|
|
ViewBag.Underlying2 = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.Trade.BasisUnderlyingCode);
|
|
}
|
|
}
|
|
|
|
using (var tagService = new TagService(CurUser))
|
|
{
|
|
ViewBag.HasTags = tagService.GetTagByTradeId(trade.Trade.id);
|
|
}
|
|
}
|
|
|
|
return View(trade);
|
|
}
|
|
|
|
[HttpPost]
|
|
public JsonResult CheckTrade(trade req, string additionalProcessing)
|
|
{
|
|
if (req == null)
|
|
{
|
|
return JsonError("数据不能为空");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(req.EncryptId))
|
|
{
|
|
return JsonError("获取交易ID参数失败!");
|
|
}
|
|
|
|
req.NoRiskRate /= 100;
|
|
if (req.trade_forward != null)
|
|
{
|
|
req.trade_forward.AnnualMarginRate /= 100;
|
|
}
|
|
|
|
req.id = DataProtectHelper.DecryptInt(req.EncryptId);
|
|
var result = new TradeCheckService(CurUser).TradeCheck(req, additionalProcessing);
|
|
result.message = result.message.TrimToNull();
|
|
if (result.success)
|
|
{
|
|
return JsonSuccess(result.specialOperateForTrade ? string.Empty : result.message ?? "复核审批成功!", result);
|
|
}
|
|
return JsonError(result.message ?? "交易复核失败!", result);
|
|
}
|
|
|
|
|
|
[HttpPost]
|
|
public JsonResult TradeReject(trade req)
|
|
{
|
|
if (req == null)
|
|
{
|
|
return JsonError("数据不能为空");
|
|
}
|
|
if (req.EncryptId.IsNullOrWhiteSpace())
|
|
{
|
|
return JsonError("拒绝失败!");
|
|
}
|
|
var id = DataProtectHelper.DecryptInt(req.EncryptId);
|
|
new TradeRejectService(CurUser).ForwardTradeReject(req, id);
|
|
return JsonSuccess("拒绝成功!");
|
|
}
|
|
|
|
#endregion
|
|
|
|
[HttpPost]
|
|
public JsonResult TradeQuery(TradeReq req)
|
|
{
|
|
var service = new TradeForwardService(CurUser);
|
|
|
|
req.TradeType = "远期";
|
|
if (!string.IsNullOrWhiteSpace(req.OptionType))
|
|
{
|
|
req.OptionType = req.OptionType == "多头" ? "看涨" : "看跌";
|
|
}
|
|
|
|
req.AssetIdList = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIdList).ToList();
|
|
req.UserAssets = CurUser.GetAssetUnitIds();
|
|
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
var sList = service.SearchList(req);
|
|
|
|
var tradeids = sList.rows.Select(r => r.id).ToList();
|
|
var cashTrades = db.trade_cash.Where(t => t.ValidState != ConsGlobal.InValid && tradeids.Contains(t.TradeId) && !t.IsDeleted).ToList();
|
|
|
|
var cashTradesExercise = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_行权费).ToList();
|
|
var cashTradesUnwind = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_平仓费).ToList();
|
|
var realtimerisk = realtime_trade_riskBLL.GetAllrealtime_trade_valueModel();
|
|
|
|
var tradeContractCodeList = (from tradeContractR in db.trade_contract_r
|
|
where tradeids.Contains(tradeContractR.TradeId) && ContractTypeEnum.Trade == tradeContractR.Type && tradeContractR.IsValid
|
|
select tradeContractR).ToList();
|
|
Dictionary<int, List<TagDto>> tradeTagList = null;
|
|
if (sList != null && sList.rows != null && sList.rows.Any())
|
|
{
|
|
using (var tagService = new TagService(CurUser))
|
|
{
|
|
tradeTagList = tagService.GetTagByTradeIds(sList.rows.Select(p => p.id).Distinct().ToList());
|
|
}
|
|
}
|
|
if (tradeTagList == null)
|
|
{
|
|
tradeTagList = new Dictionary<int, List<TagDto>>();
|
|
}
|
|
foreach (var r in sList.rows)
|
|
{
|
|
r.Amount = cashTradesExercise.FirstOrDefault(t => t.TradeId == r.id)?.Amount;
|
|
//r.UnwindAmount = !cashTradesUnwind.Where(t => t.TradeId == r.id).Any() ? null : cashTradesUnwind.Where(t => t.TradeId == r.id).Sum(t => t.Amount);
|
|
r.FinalPrice = cashTradesExercise.FirstOrDefault(t => t.TradeId == r.id)?.FinalPrice;
|
|
r.LotsNewInfo = TradeLotsCalc.GetLots(r.UnderlyingCode, r.Notional);
|
|
|
|
var pv = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.Pv)).ToList();
|
|
var roundedPv = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.RoundedPv)).ToList();
|
|
var positionPnl = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.PositionPnl)).ToList();
|
|
var roundedPositionPnl = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair<string, double?>(t.VolType, t.RoundedPositionPnl)).ToList();
|
|
if (PS.Config.IsPVRounded)
|
|
{
|
|
if (roundedPv != null && roundedPv.Count > 0)
|
|
{
|
|
r.PV = roundedPv.ToJson();
|
|
}
|
|
if (roundedPositionPnl != null && roundedPositionPnl.Count > 0)
|
|
{
|
|
r.PositionPnl = roundedPositionPnl.ToJson();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pv != null && pv.Count > 0)
|
|
{
|
|
r.PV = pv.ToJson();
|
|
}
|
|
if (positionPnl != null && positionPnl.Count > 0)
|
|
{
|
|
r.PositionPnl = positionPnl.ToJson();
|
|
}
|
|
}
|
|
|
|
var un = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode);
|
|
if (un != null)
|
|
{
|
|
r.UnderlyingPrice = un.Price;
|
|
}
|
|
|
|
r.RealizedPnl = cashTradesExercise.Where(x => x.TradeId == r.id).Sum(x => x.Amount) - r.TradePrice * cashTradesExercise.Where(x => x.TradeId == r.id).Sum(x => x.UnwindPercentRate) * ((r.BuySell == "卖出") ? -1 : 1)
|
|
+ cashTradesUnwind.Where(x => x.TradeId == r.id).Sum(x => x.Amount) - r.TradePrice * cashTradesUnwind.Where(x => x.TradeId == r.id).Sum(x => x.UnwindPercentRate) * ((r.BuySell == "卖出") ? -1 : 1);
|
|
|
|
r.TradeOriginalAmount = r.OriginalNotional / un.CountRatio;
|
|
|
|
var tradeContractCode = tradeContractCodeList.FirstOrDefault(t => t.TradeId == r.id);
|
|
r.ContractCode = tradeContractCode?.ContractCode;
|
|
r.trade_forward = db.trade_forward.FirstOrDefault(x => x.TradeId == r.id);
|
|
//拼装标签值
|
|
if (tradeTagList.ContainsKey(r.id))
|
|
{
|
|
r.Tags = tradeTagList[r.id];
|
|
r.OutputTags = TagService.GetOutputTagsStr(r.Tags);
|
|
}
|
|
}
|
|
|
|
return Json(sList);
|
|
}
|
|
|
|
[MyAuthorize("交易管理-远期交易")]
|
|
public ActionResult TradeConfirmList(int tabIndex = (int)TradeTabIndexEnum.今日成交)
|
|
{
|
|
ViewBag.TabIndex = tabIndex;
|
|
return View();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当日成交查询。
|
|
/// 查询在当前交易日成交,或在当前交易日被修改过状态的交易
|
|
/// </summary>
|
|
[HttpPost]
|
|
public JsonResult tradeOnValueDateQuery(TdTradeQueryModel req)
|
|
{
|
|
req.AssetIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIds).ToList();
|
|
req.UserAssets = CurUser.GetAssetUnitIds();
|
|
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
req.OtcTradeType = DBModels.Enums.OtcTradeType.Forward;
|
|
var sList = new TodayTradeQueryService(CurUser).GetConfirmList(req);
|
|
return Json(sList);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当日成交而几个tab的交易总数。
|
|
/// </summary>
|
|
[HttpPost]
|
|
public JsonResult tradeCountsOnValueDateQuery()
|
|
{
|
|
var userAssets = CurUser.GetAssetUnitIds();
|
|
var userClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
var sum = new TodayTradeQueryService(CurUser).GetTdTradesCountSum(userAssets, userClients, DBModels.Enums.OtcTradeType.Forward);
|
|
var countDic = new Dictionary<int, int> {
|
|
{(int)TradeTabIndexEnum.今日到期,sum.TdExerciseCount },
|
|
{(int)TradeTabIndexEnum.今日终止,sum.TdEarlyStoppedCount },
|
|
{(int)TradeTabIndexEnum.明日到期,sum.TmExerciseCount },
|
|
{(int)TradeTabIndexEnum.今日成交,sum.TdCreatedCount },
|
|
};
|
|
return Json(countDic);
|
|
}
|
|
|
|
[MyAuthorize("交易管理-远期交易")]
|
|
public ActionResult TradePreEndList()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
[HttpPost]
|
|
public JsonResult InValidTrade(string id)
|
|
{
|
|
var intid = DataProtectHelper.DecryptInt(id);
|
|
new TradeForwardService(CurUser).InValidTrade(intid);
|
|
return JsonSuccess("无效成功", "已无效");
|
|
}
|
|
|
|
|
|
|
|
public ActionResult TradeUnwind(string enid, bool isUseApproval = false)
|
|
{
|
|
var intid = DataProtectHelper.DecryptInt(enid);
|
|
|
|
var result = new TradeForwardUnwindService(CurUser).PrepareUnwind(intid, isUseApproval);
|
|
|
|
//需要审批或者复核的交易都会显示行权审核提交按钮
|
|
ViewBag.IsShowReCheckClose = ((valuedateBLL.SystemDate.CloseReCheck == 1) || (valuedateBLL.SystemDate.CloseReApprove == 1 && result.HasProcess)) && result.Trade.TradeStatus != ConsTrade.平仓待复核;
|
|
ViewBag.isUseApproval = isUseApproval;
|
|
|
|
return View(result);
|
|
}
|
|
|
|
#region 确认交易
|
|
public JsonResult tradeConfirm(IEnumerable<int> tradeIds, string additionalProcessing)
|
|
{
|
|
if (tradeIds is null || !tradeIds.Any())
|
|
{
|
|
return JsonError("参数错误:" + nameof(tradeIds));
|
|
}
|
|
|
|
var config = valuedateBLL.SystemDate;
|
|
var ignoreMoneyCheck = tradeIds.Count() == 1 && (config.TradeTrial || (!config.TradeTrial && config.SpecialOperateForTrade == 1)) && additionalProcessing == tradeBLL.LackOfMoney;
|
|
var result = new TradeConfirmService(CurUser).tradeConfirm(tradeIds, ignoreMoneyCheck, false);
|
|
|
|
//如果客户缺少资金而操作者有交易特批权限
|
|
if (!ignoreMoneyCheck && result.LackOfMoney)
|
|
{
|
|
return JsonSuccessData(new { proccessType = "AdditionalProcessing", type = PS.Config.ErpElement.Company == Configuration.CompanyEnum.天风 || config.SpecialOperateForTrade == 1 ? tradeBLL.LackOfMoney : "", TrialDataId = result.TrialDataId, message = result.errorMsg, typecode = result.type });
|
|
}
|
|
|
|
//生成交易确认书
|
|
if (PS.Config.IsAutoGenerateContracts && result.confirmedTradeIds?.Count > 0)
|
|
{
|
|
new TradeContractGenerateService(CurUser).GenerateContractsAsync(result.confirmedTradeIds, "确认书");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(result.errorMsg))
|
|
{
|
|
if (result.changeConfirmPaths?.Count > 0)
|
|
{
|
|
return JsonError("确认成交失败,原因:\r\n" + result.errorMsg, new { generateChangeSuccess = true, url = result.changeConfirmPaths });
|
|
}
|
|
return JsonError("确认成交失败,原因:\r\n" + result.errorMsg);
|
|
}
|
|
else
|
|
{
|
|
if (result.changeConfirmPaths?.Count > 0)
|
|
{
|
|
return JsonSuccess("操作完成", new { generateChangeSuccess = true, url = result.changeConfirmPaths });
|
|
}
|
|
return JsonSuccess("操作完成");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 生成远期交易确认书
|
|
/// <summary>
|
|
/// 生成远期交易确认书
|
|
/// </summary>
|
|
/// <param name="tradeIds"></param>
|
|
/// <param name="contractType">contractType为确认书的话,表示生成交易确认书;否则则生成提前终止确认书或者到期结算单</param>
|
|
/// <returns></returns>
|
|
public Result GenerateContracts(List<int> tradeIds, int userId, string userName, string contractType = "其它")
|
|
{
|
|
Result result = null;
|
|
try
|
|
{
|
|
if (contractType == "确认书")
|
|
{
|
|
var tradeConfirmBookController = new TradeConfirmBookController(_viewRenderer);
|
|
var JsonResult = tradeConfirmBookController.GJGenerateConfirmBook(tradeIds, "PDF", userId, userName, null, null);
|
|
result = JsonResult.Value as Result;
|
|
if (result.success)
|
|
{
|
|
result.msg = "生成确认书成功";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
var tradeController = new tradeController();
|
|
|
|
var unwindReportInputModels = new List<UnwindReportInputModel>();
|
|
var clearingTradeIds = new List<int>();
|
|
using (var context = new YLContext())
|
|
{
|
|
var tradeCashes = context.trade_cash.Where(tc => tradeIds.Contains(tc.TradeId) && !tc.IsDeleted)
|
|
.ToLookup(tc => tc.TradeId).Select(l => l.OrderByDescending(m => m.id).First()).ToList();
|
|
tradeCashes.ForEach(tc =>
|
|
{
|
|
if (tc.Action == ClientCashInCashOut.系统操作_平仓费 ||
|
|
(tc.Action == ClientCashInCashOut.系统操作_行权费 &&
|
|
tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权))
|
|
{
|
|
unwindReportInputModels.Add(
|
|
new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id });
|
|
}
|
|
else if (tc.Action == ClientCashInCashOut.系统操作_行权费)
|
|
{
|
|
clearingTradeIds.Add(tc.TradeId);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (unwindReportInputModels.Count > 0)
|
|
{
|
|
var JsonResult =
|
|
tradeController.GJGenerateUnwindReport(unwindReportInputModels, "PDF", userId, userName);
|
|
result = JsonResult.Value as Result;
|
|
if (result.success)
|
|
{
|
|
result.msg = "生成提前终止确认书成功";
|
|
}
|
|
}
|
|
|
|
if (clearingTradeIds.Count > 0)
|
|
{
|
|
var JsonResult = tradeController.GJGenerateSettleBill(clearingTradeIds, "PDF", userId, userName);
|
|
var tempResult = JsonResult.Value as Result;
|
|
if (tempResult.success)
|
|
{
|
|
tempResult.msg = "生成到期结算单成功";
|
|
}
|
|
|
|
if (result != null)
|
|
{
|
|
if (result.success && tempResult.success)
|
|
{
|
|
result.msg = "生成到期结算单或提前终止确认书成功";
|
|
}
|
|
else
|
|
{
|
|
result.msg =
|
|
$"{((!result.success) ? result.msg + "<br/>" : string.Empty)}{((!tempResult.success) ? tempResult.msg + "" : string.Empty)}";
|
|
}
|
|
|
|
result.success = result.success && tempResult.success;
|
|
}
|
|
else
|
|
{
|
|
result = tempResult;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger<ForwardTradeController>().Error("GenerateContracts异常", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 执行到期
|
|
|
|
/// <summary>
|
|
/// 将单个交易标记为到期(并增加一条收益为零的trade_cash记录,直接到期的交易记录期末价格为0)
|
|
/// </summary>
|
|
public JsonResult tradeExpireConfirm(string enid)
|
|
{
|
|
var id = DataProtectHelper.DecryptInt(enid);
|
|
var result = new TradeExpireConfirmService(CurUser).TradeExpireConfirm(id);
|
|
if (result.Success)
|
|
{
|
|
return JsonSuccess(result.Message, result.Trade);
|
|
}
|
|
return JsonError(result.Message, result.Trade);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 预付金占用成本
|
|
|
|
[HttpGet]
|
|
public ActionResult TradeMarginCost(string enid, string tradenum)
|
|
{
|
|
var intid = DataProtectHelper.DecryptInt(enid);
|
|
ViewBag.tradeId = enid;
|
|
if (db.eod_forward_margin.Any(x => x.TradeId == intid))
|
|
{
|
|
var sum = db.eod_forward_margin.Where(x => x.TradeId == intid)
|
|
.OrderByDescending(x => x.ValueDate).Select(x => x.MarginSum).FirstOrDefault();
|
|
ViewBag.MarginCostTotal = sum.ToString("f2");
|
|
}
|
|
else
|
|
{
|
|
ViewBag.MarginCostTotal = "0.00";
|
|
}
|
|
ViewBag.TradeNum = tradenum;
|
|
return View();
|
|
}
|
|
|
|
public JsonResult SingleMarginCost(Eod_forward_marginReq req)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(req.sidx))
|
|
{
|
|
req.sidx = "ValueDate"; req.sord = "desc";
|
|
}
|
|
var list = new EodForwardMarginQueryService(CurUser).GetPagedList(req);
|
|
var tradeId = DataProtectHelper.DecryptInt(req.enid);
|
|
var code = db.trade.Where(O => O.id == tradeId).Select(O => O.UnderlyingCode).FirstOrDefault();
|
|
var un = DataCacheProvider.GetUnderlyingDataSource().GetData(code);
|
|
|
|
var eodList = new List<eod_forward_marginDto>();
|
|
foreach (var item in list.rows)
|
|
{
|
|
var eod = new eod_forward_marginDto();
|
|
YLAutoMapper.Map(item, eod);
|
|
if (un != null)
|
|
{
|
|
eod.TradeAmount = eod.Notional / un.CountRatio;
|
|
}
|
|
eodList.Add(eod);
|
|
}
|
|
|
|
var ret = eodList.AsQueryable().ToSearchList(req);
|
|
return Json(ret);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 财务结算-远期预付金成本
|
|
/// </summary>
|
|
public ActionResult MarginCostList()
|
|
{
|
|
ViewBag.valueDate = EodOperationBase
|
|
.GetLastSettlementDate(valuedateBLL.ValueDate).ToString("yyyy-MM-dd");
|
|
return View();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 财务结算-远期预付金成本
|
|
/// </summary>
|
|
public JsonResult MarginCostListQuery(MarginCostReq req)
|
|
{
|
|
req.AssetIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIds).ToList();
|
|
req.UserAssets = CurUser.GetAssetUnitIds();
|
|
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
|
|
var forward_marginQuery = db.eod_forward_margin.AsQueryable();
|
|
var tradeQuery = db.trade.AsQueryable();
|
|
if (req.UserAssets != null && req.UserClients != null)
|
|
{
|
|
tradeQuery = tradeQuery.Where(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId));
|
|
}
|
|
|
|
var tl = from efm in forward_marginQuery
|
|
where efm.ValueDate == req.ValueDate
|
|
join t in db.trade on efm.TradeId equals t.id
|
|
where t.TradeType == "远期" && t.ValidState != "InValid"
|
|
join tf in db.trade_forward on t.id equals tf.TradeId
|
|
select new MarginCostDto
|
|
{
|
|
TradeId = t.id,
|
|
TradeNumber = t.TradeNumber,
|
|
TradeDate = efm.ValueDate,
|
|
TotalMarginCost = efm.MarginSum,
|
|
ExerciseDate = t.ExerciseDate,
|
|
BuySell = t.BuySell,
|
|
OptionType = t.OptionType,
|
|
UnderlyingCode = t.UnderlyingCode,
|
|
Strike = t.Strike ?? 0,
|
|
TradeAmount = t.TradeAmount,
|
|
StockEqvNotional = t.StockEqvNotional,
|
|
ClientName = t.ClientName,
|
|
AssetBookName = t.AssetBookName,
|
|
TraderName = t.TraderName,
|
|
TraderId = t.TraderId,
|
|
AssetId = t.AssetId,
|
|
ClientId = t.ClientId,
|
|
TradeStatus = t.TradeStatus
|
|
};
|
|
if (req.ClientId != 0)
|
|
{
|
|
tl = tl.Where(x => x.ClientId == req.ClientId);
|
|
}
|
|
if (req.AssetIds.Any())
|
|
{
|
|
tl = tl.Where(x => req.AssetIds.Contains(x.AssetId));
|
|
}
|
|
if (req.TraderId != 0)
|
|
{
|
|
tl = tl.Where(x => x.TraderId == req.TraderId);
|
|
}
|
|
|
|
tl = tl.OrderByDescending(d => d.TradeDate);
|
|
var retListResult = tl.ToSearchList(req);
|
|
|
|
if(retListResult.rows !=null && retListResult.rows.Any())
|
|
{
|
|
foreach (var item in retListResult.rows)
|
|
{
|
|
item.CountRatio = Modules.DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode).CountRatio;
|
|
}
|
|
}
|
|
|
|
return Json(retListResult);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 计算初始保证
|
|
public JsonResult AjaxGetInitialMargin_Forward(OtcTradeForward trade)
|
|
{
|
|
if (trade is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(trade));
|
|
}
|
|
try
|
|
{
|
|
var tdConv = TradeConverter.ConvertForward(trade);
|
|
tdConv.OptId = UserId;
|
|
tdConv.VolType = "报价Bid";
|
|
tdConv.TradeCloseVolatility = null;//不设置为null会影响计算结果
|
|
if (!tdConv.TTMDays.HasValue)
|
|
{
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tdConv.UnderlyingCode);
|
|
tdConv.TTMDays = TradeCalcHelper.CalculateTTMDays(tdConv.TradeDate.Value, tdConv.ExerciseDate.Value,
|
|
underlying?.UnderlyingTypeId ?? 0, PS.Config.ErpElement.PrecisionOfMinuteInQuote);
|
|
}
|
|
var initialMargin = MarginDefault.GetInitialMargin(tdConv, trade.id, true);
|
|
return JsonSuccessData(initialMargin);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("AjaxGetInitialMargin_Forward").Error(ex);
|
|
return JsonError("获取初始预付金失败:" + ex.Message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 多次了结
|
|
|
|
public ActionResult MultiCloseList()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
public JsonResult AjaxGetMultiCloseList(TradeMultiCloseQueryModel queryModel)
|
|
{
|
|
queryModel.PageIndex = queryModel.page;
|
|
queryModel.PageSize = queryModel.rows;
|
|
if (!string.IsNullOrEmpty(queryModel.sidx))
|
|
{
|
|
queryModel.SortExpression = queryModel.sidx + " " + queryModel.sord;
|
|
}
|
|
if (queryModel.PageSize == 0)
|
|
{
|
|
queryModel.PageIndex = 1;
|
|
queryModel.PageSize = 10000;
|
|
}
|
|
queryModel.UserAssets = CurUser.GetAssetUnitIds();
|
|
queryModel.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
queryModel.LoginUserId = CurUser.UserId;
|
|
queryModel.CurUserTradeIds = CurUser.GetTradeIdsByCurUser();
|
|
|
|
var datas = new ForwardMultiCloseService(CurUser).GetPagedDatas(queryModel);
|
|
return JsonForJqGrid(datas);
|
|
}
|
|
|
|
public ActionResult MultiCloseListExport(TradeMultiCloseQueryModel queryModel)
|
|
{
|
|
queryModel.UserAssets = CurUser.GetAssetUnitIds();
|
|
queryModel.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
|
|
var filecontent = new ForwardMultiCloseService(CurUser).ExportExcel2007(queryModel);
|
|
return File(filecontent, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
$"远期多次了结{DateTime.Today:yyyyMMdd}.xlsx");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 远期交易导入
|
|
public ActionResult TradeUpload()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 导入Excel
|
|
/// </summary>
|
|
[MyAuthorize("交易管理-远期交易")]
|
|
public ActionResult UploadTradeExcel(string TypeName)
|
|
{
|
|
|
|
if (Request.Form.Files.Count == 0)
|
|
{
|
|
return JsonError("上传文件不存在");
|
|
}
|
|
|
|
var file = Request.Form.Files[0];
|
|
|
|
if (!Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return JsonError("请上传Excel(.xlsx)格式文件");
|
|
}
|
|
|
|
using var stream = file.OpenReadStream();
|
|
new ForwardTradeImportService(CurUser).ImportFromExcel(stream, TypeName, out var TotalNum, out var SuccessNum);
|
|
|
|
return Json(new
|
|
{
|
|
success = true,
|
|
totalNum = TotalNum,
|
|
successNum = SuccessNum,
|
|
});
|
|
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |