structure.js×3/structure_dz.js/tradeEditV2.js/tradeEditGroup.js的setExtendInfo里同一行式:靠indexOf("%")>0嗅探值是否已带%,决定原样展示还是×100加%。抽为app/trade/percentColumnText.js纯函数(UMD,jest可测),表达式逐字符等价——含>0而非>=0、空值回退ColumnDefaultValue、回退源也无值时NaN%等历史行为全部被7个特征测试冻结(TDD:测试先红后绿)。四个页面cshtml在tradeHelper后补脚本序;jest覆盖率清单纳入。fe-tests 326/326通过
911 lines
49 KiB
Plaintext
911 lines
49 KiB
Plaintext
@using Microsoft.AspNetCore.Html
|
|
@using YLErp.QdpModule.Constants
|
|
@model PricingModel
|
|
@{
|
|
ViewBag.Title = "期权定价";
|
|
|
|
if (Model.IsImport)
|
|
{
|
|
Layout = "~/Views/Shared/_InfoLayout.cshtml";
|
|
}
|
|
else
|
|
{
|
|
Layout = "~/Views/Shared/_MainLayout.cshtml";
|
|
}
|
|
var assetunits = JsDataModel.GetAssetUnits(CurUser);
|
|
var traders = JsDataModel.GetTraders(assetunits);
|
|
var pageObj = new
|
|
{
|
|
assetunits = assetunits,
|
|
trade = new trade() { Strike = 0 },
|
|
traders = JsDataModel.GetTraders(assetunits),
|
|
tradeMarginTemplateItems = new tradeController().GetMarginTemplateItems(),
|
|
tradeMarginTemplates = new tradeController().GetMarginTemplates(),
|
|
engineNames = new[] { "abc", "xyz" },
|
|
structureTypes = ViewBag.StructureTypeMap?.Keys,
|
|
PropertyMap = ViewBag.StructureTypeMap,
|
|
IsPVIncludePrincipal = PS.Config.ErpElement.IsPVIncludePrincipal
|
|
};
|
|
var pageData = new
|
|
{
|
|
showCCR = PS.Config.Company == CompanyEnum.国海,
|
|
is厦门象屿 = PS.Config.Company == CompanyEnum.厦门象屿,
|
|
};
|
|
}
|
|
@section CSS{
|
|
<link href="~/Style/Css/pricing.structure.css?v=1" rel="stylesheet" />
|
|
@switch (PS.Config.Company)
|
|
{
|
|
case CompanyEnum.光大光子:
|
|
<link href="~/Style/GDGZ/pricing.structure.css" rel="stylesheet" />
|
|
break;
|
|
case CompanyEnum.国泰君安:
|
|
<link href="~/Style/GTJA/pricing.structure.css" rel="stylesheet" />
|
|
break;
|
|
}
|
|
<style>
|
|
.pitem-cash:not(.pitem) {
|
|
background: #f0f8ff
|
|
}
|
|
|
|
.customPanel {
|
|
background: #CDE0E6;
|
|
height: 100%;
|
|
display: table;
|
|
width: 100%;
|
|
}
|
|
|
|
.autocomplete-suggestions {
|
|
width: auto !important;
|
|
min-width: 11%;
|
|
}
|
|
|
|
.pricing-item {
|
|
transform: none !important;
|
|
}
|
|
|
|
.empty {
|
|
border-top: none !important;
|
|
background: none !important;
|
|
}
|
|
|
|
.bottomborder {
|
|
border-bottom: 1px solid #ddd !important;
|
|
}
|
|
|
|
.topborder {
|
|
border-top: 1px solid #ddd !important;
|
|
}
|
|
</style>
|
|
}
|
|
@section JS{
|
|
<script src="~/Statics/libs/_utils/dragscroll.js?v=@(HtmlUtil.JsVersion)"></script>
|
|
<script src="~/Statics/libs/_utils/FileSaver.js?v=@(HtmlUtil.JsVersion)"></script>
|
|
<script src="~/Statics/libs/_utils/dom-to-image.min.js?v=@(HtmlUtil.JsVersion)"></script>
|
|
<script src="~/Statics/libs/sortable/Sortable.min.js"></script>
|
|
<script src="~/front/calendar?v=@(HtmlUtil.JsVersion)"></script>
|
|
<script src="~/Scripts/app/tradeHelper.js?v=@HtmlUtil.JsVersion"></script>
|
|
<script src="~/Scripts/app/trade/percentColumnText.js?v=@HtmlUtil.JsVersion"></script>
|
|
<script src="@HtmlUtil.BasicDataJs("品种", "客户")"></script>
|
|
<script>
|
|
const pageObj = @Json.Serialize(pageObj);
|
|
const pageData = @Json.Serialize(pageData);
|
|
const pageVue = @Json.Serialize(Model);
|
|
const optionTradeTypes = Object.freeze([{ value: "香草期权", pinyin: 'XCQQ' },
|
|
{ value: "障碍期权", pinyin: 'ZAQQ' }, { value: "二元期权", pinyin: 'EYQQ' },
|
|
{ value: "亚式期权", pinyin: 'YSQQ' }, { value: "凤凰期权", pinyin: 'FHQQ' },
|
|
{ value: "雪球期权", pinyin: 'XQQQ' }, { value: "结构化产品", pinyin: 'JGHCP' },
|
|
]);
|
|
pageVue.GetTotalMargin = function (trades, structureType) {
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.InitialMargin) || 0, 0);
|
|
};
|
|
pageVue.GetTotalTradePrice = function (trades) {
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.TradePrice) || 0, 0);
|
|
};
|
|
pageVue.GetTotalDay1Pnl = function (trades) {
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.Day1Pnl) || 0, 0);
|
|
};
|
|
pageVue.CalcVersion = "@(Context.Request.Query["version"])";
|
|
ylotc.trade = pageObj.trade;
|
|
ylotc.traders = pageObj.traders;
|
|
ylotc.assetunits = pageObj.assetunits;
|
|
ylotc.tradeMarginTemplateItems = pageObj.tradeMarginTemplateItems;
|
|
ylotc.tradeMarginTemplates = pageObj.tradeMarginTemplates;
|
|
ylotc.engineNames = pageObj.engineNames;
|
|
ylotc.options = pageObj.options;
|
|
ylotc.structureTypes = pageObj.structureTypes;
|
|
|
|
</script>
|
|
|
|
@if (PS.Config.Company == CompanyEnum.伴兴)
|
|
{
|
|
<script>
|
|
pageVue.GetTotalMargin = function (trades, structureType) {
|
|
if (trades.length === 1) return parseFloat(trades[0].InitialMargin) || 0;
|
|
if (!structureType || structureType === "结构化交易") {
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.InitialMargin) || 0, 0);
|
|
}
|
|
if (structureType.indexOf("跨式") >= 0) {
|
|
return _.max(_.map(trades, x => Math.abs(x.InitialMargin)));
|
|
}
|
|
return _.reduce(trades, (acc, cur) => acc += cur.BuySell === '卖出' ? 0 : parseFloat(cur.InitialMargin) || 0, 0);
|
|
};
|
|
</script>
|
|
}
|
|
else if (PS.Config.Company == CompanyEnum.茂川资本)
|
|
{
|
|
<script>
|
|
pageVue.GetTotalMargin = function (trades, structureType) {
|
|
if (structureType && structureType.indexOf("跨式") >= 0) {
|
|
return _.max(_.map(trades, x => Math.abs(x.InitialMargin)));
|
|
}
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.InitialMargin) || 0, 0);
|
|
};
|
|
</script>
|
|
}
|
|
else if (PS.Config.Company == CompanyEnum.弘业)
|
|
{
|
|
<script>
|
|
pageVue.GetTotalMargin = function (trades, structureType) {
|
|
if (structureType && structureType.indexOf("跨式") >= 0) {
|
|
return _.max(_.map(trades, x => Math.abs(x.InitialMargin)));
|
|
}
|
|
return _.reduce(trades, (acc, cur) => acc += parseFloat(cur.InitialMargin) || 0, 0);
|
|
};
|
|
</script>
|
|
}
|
|
|
|
<script src="~/Scripts/app/pricing/tradePricing_dz.js?v=@(HtmlUtil.JsVersion)"></script>
|
|
<script src="~/Scripts/app/pricing/structure_dz.js?v=@(HtmlUtil.JsVersion)"></script>
|
|
}
|
|
|
|
@await Html.PartialAsync("_CouponDayCount")
|
|
|
|
<div id="listdiv" class="@(Model.IsImport ? "sr-only" : "")">
|
|
|
|
<!--定价顶部-->
|
|
<div class="card pricing-top" id="pricing-top">
|
|
<div class="card-body">
|
|
<div class="row no-gutters">
|
|
<label class="col-auto mr-2">波动率类型</label>
|
|
<div class="col-auto mr-2">
|
|
<select v-model="viewState.VolType" v-on:change="pricingVue.changeVolType()">
|
|
@foreach (var item in ConsVolInfos.VolTypes)
|
|
{
|
|
<option value="@item">@item</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col" style="min-width:350px">
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">新增单腿</button>
|
|
<div class="dropdown-menu" style="width:200px;">
|
|
<a href="javascript:;" class="dropdown-item" v-for="item in optionTradeTypes" v-on:click="pricingVue.addTrade(null,item.value)">{{item.value}}</a>
|
|
<div class="dropdown-divider"></div>
|
|
<div class="form-group ml-2">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="importTradeNumber" placeholder="输入交易编号导入" />
|
|
<span class="input-group-append">
|
|
<a href="javascript:;" class="pl-2 pr-2" onclick="topVue.importTrade()"><i class="fa fa-copy"></i></a>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">新增组合</button>
|
|
<div class="dropdown-menu">
|
|
<a v-if="!simpleMode" href="javascript:;" class="dropdown-item" onclick="pricingVue.combine()">自由组合</a>
|
|
@foreach (var item in StructureOption_Code.StructureOptionsCn)
|
|
{
|
|
if (!new List<string>() { "复制标的资产", "比例价差", "箱式价差" }.Contains(item.Text))
|
|
{
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="addStructure('@item.Value','@item.Text')">@item.Text</a>
|
|
}
|
|
}
|
|
</div>
|
|
</div>
|
|
<button type="button" class="btn btn-primary" onclick="pricingVue.calcPrice()">定价计算</button>
|
|
@if (CurUser.交易管理_交易新增)
|
|
{
|
|
<button type="button" class="btn btn-primary" onclick="pricingVue.saveTrades()">录入交易</button>
|
|
}
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">图形分析</button>
|
|
<div class="dropdown-menu">
|
|
@*<a class="dropdown-item" href="javascript:;" v-on:click="pricingVue.showPayoffLineChart()">到期收益曲线</a>*@
|
|
@*<a class="dropdown-item" href="javascript:;" v-on:click="pricingVue.showPvChart()">组合价值曲线</a>*@
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="pricingVue.showLifeLineChart()">Pv变化曲线</a>
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="pricingVue.showGreeksChart()">时间变化曲线</a>
|
|
</div>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-danger" onclick="templateVue.showList()">模板</button>
|
|
<button type="button" class="btn btn-danger" onclick="templateVue.showSave()" title="保存为模板">保存</button>
|
|
</div>
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">选项</button>
|
|
<div class="dropdown-menu">
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="toggleSimpleMode" title="是否隐藏不常用的字段">
|
|
<span class="fa mr-2" v-bind:class="simpleMode?'fa-check':''"></span>
|
|
<span>精简模式</span>
|
|
</a>
|
|
@if (Model.ShowInitialMargin)
|
|
{
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="toggleCalcMargin" title="是否计算初始预付金">
|
|
<span class="fa mr-2" v-bind:class="calcMargin?'fa-check':''"></span>
|
|
<span>计算预付金</span>
|
|
</a>
|
|
}
|
|
<a class="dropdown-item" href="javascript:;" v-on:click="toggleCalcAutocallGreeks" title="是否计算凤凰和雪球的所有Greeks">
|
|
<span class="fa mr-2" v-bind:class="calcAutocallGreeks?'fa-check':''"></span>
|
|
<span>计算凤凰和雪球的所有Greeks</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<button type="button" class="btn btn-primary" onclick="pricingVue.clear()" title="清空legs交易">清空</button>
|
|
@if (CurUser.交易管理_分组设置)
|
|
{
|
|
<button type="button" class="btn btn-primary" onclick="pricingVue.saveGroupTrades()">加入分组</button>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="yc-panel">
|
|
<!--定价合计-->
|
|
<div class="pricing-summary" id="pricing-summary">
|
|
<table class="table table-bordered">
|
|
<colgroup>
|
|
<col span="1" width="200" />
|
|
<col span="1" width="150" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>对冲手数</th>
|
|
@*<th>组合成交金额</th>*@
|
|
<th v-if="topVue.calcMargin">组合预付金</th>
|
|
<th>Day1Pnl</th>
|
|
<th>PV</th>
|
|
<th>Delta</th>
|
|
<th>GammaCash</th>
|
|
<th>Theta</th>
|
|
<th>Vega</th>
|
|
<th>Rho</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody v-cloak>
|
|
<tr>
|
|
<td style="color:red;font-weight: bold;">
|
|
<span>{{DeltaHands}}</span>
|
|
@if (Model.HedgingOrder && Model.IsTrader)
|
|
{
|
|
<a href="javascript:;" class="ml-1" onclick="pricingVue.hedgingOrder()" title="对冲下单"><i class="fa fa-external-link"></i></a>
|
|
}
|
|
</td>
|
|
@*<td>{{summary.TotalTradePrice| FixNumber}}</td>*@
|
|
<td v-if="topVue.calcMargin">{{summary.TotalMargin| FixNumber}}</td>
|
|
<td>{{summary.TotalDay1Pnl| FixNumber}}</td>
|
|
<td>{{summary.Pv| FixNumber}}</td>
|
|
<td>{{summary.Delta| FixNumber}}</td>
|
|
<td>{{summary.GammaCash| FixNumber}}</td>
|
|
<td>{{summary.Theta| FixNumber}}</td>
|
|
<td>{{summary.Vega| FixNumber}}</td>
|
|
<td>{{summary.Rho| FixNumber}}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="clearfix"></div>
|
|
|
|
<!--定价列表-->
|
|
<div class="pricing-main">
|
|
<div class="d-flex">
|
|
<div class="pricing-titles-cont">
|
|
<div class="singleprice" id="singleprice">@(Model.CompanyName) 付 0.000</div>
|
|
<div class="pricing-titles">
|
|
<div>组合单价</div>
|
|
</div>
|
|
<div id="pricing-titles"></div>
|
|
</div>
|
|
<div class="pricing-items-cont">
|
|
<div class="zhanwei"></div>
|
|
<div class="d-flex" id="pricing-items"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!--定价组件模板框架-->
|
|
<template id="pricingItems_tpl">
|
|
<div class="pricing-item">
|
|
<div class="pricing-index screenshot-hide" v-if="!pageVue.IsImport">
|
|
<span class="structure-type">{{structureType}}</span>
|
|
<a href="javascript:;" title="拖动位置" class="pricing-index-drag" v-show="!floating"><i class="fa fa-arrows"></i></a>
|
|
<a href="javascript:;" v-on:click="remove" title="移除此项" v-show="!floating"><i class="fa fa-remove"></i></a>
|
|
<a href="javascript:void(0)" class="pricing-index-text">{{index}}</a>
|
|
<div class="pricing-index-icons" v-show="!floating">
|
|
<label class="check-label">
|
|
<input type="checkbox" v-model="isSelected" v-on:change="resetSummary(true)">
|
|
</label>
|
|
<a href="javascript:;" v-on:click="saveTrade" title="录入交易"><i class="fa fa-save"></i></a>
|
|
<a href="javascript:;" v-show="showFloatingIcon" v-on:click="showFloatVue" title="浮窗编辑">
|
|
<i class="fa fa-external-link"></i>
|
|
</a>
|
|
</div>
|
|
<div class="pricing-index-right" v-show="!floating">
|
|
<div class="dropdown">
|
|
<a href="javascript:;" class="pricing-index-right-toggle" data-toggle="dropdown">
|
|
<i class="fa fa-ellipsis-v"></i>
|
|
</a>
|
|
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
|
<a href="javascript:;" class="dropdown-item" v-on:click="copyThis">复制此项</a>
|
|
<a href="javascript:;" class="dropdown-item" v-on:click="screenshot">生成截图</a>
|
|
<a href="javascript:;" class="dropdown-item" v-show="datas.length>1" v-on:click="uncouple">取消组合</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="pricing-trades">
|
|
<template v-for="(data,index) in datas">
|
|
<vue-trade2 v-if="data.trade.TradeType==='现金流交易'" v-on:reset-summary="resetSummary" v-on:change-client="changeClient" :floating="floating" :trade="data.trade" :view-state="data.viewState" :calc-result="data.calcResult"></vue-trade2>
|
|
<vue-trade v-else v-on:reset-summary="resetSummary" v-on:change-client="changeClient" v-on:synch-trade="synchTrade" v-on:sum-total="sumTotal" :floating="floating" :trade="data.trade" :view-state="data.viewState" :calc-result="data.calcResult"></vue-trade>
|
|
</template>
|
|
</div>
|
|
<div class="border-0 text-center" v-show="!floating">
|
|
<label class="w-100 m-0">
|
|
<input type="checkbox" class="checkbox" v-model="isSelected" title="是否录入交易" v-on:change="resetSummary(true)" />
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!--定价组件模板内部-->
|
|
@await Html.PartialAsync("_PricingItemTpl_dz")
|
|
|
|
<!--定价浮窗-->
|
|
<div id="floatModal" class="modal modal-fullscreen @(Model.IsImport?"show":"")" tabindex="-1" data-backdrop="static">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-body">
|
|
<div class="pricing-float-topbar">
|
|
<div class="btn-group screenshot-hide">
|
|
<button type="button" class="btn btn-primary" onclick="floatVue.screenshot()">截图</button>
|
|
<button type="button" class="btn btn-primary" onclick="floatVue.calcPrice()">定价计算</button>
|
|
<button type="button" class="btn btn-primary" onclick="floatVue.saveTrade()">录入交易</button>
|
|
<button type="button" class="btn btn-primary" onclick="floatVue.hide()">关闭</button>
|
|
</div>
|
|
</div>
|
|
<div class="pricing-float-main d-flex" id="for-screenshot">
|
|
<div class="ml-auto pricing-titles-cont">
|
|
<div class="singleprice screenshot-hide" id="singleprice2">@(Model.CompanyName) 付 0.000</div>
|
|
<div class="pricing-titles screenshot-hide">
|
|
<div>组合单价</div>
|
|
</div>
|
|
<div id="pricing-titles2"></div>
|
|
</div>
|
|
<div class="mr-auto pricing-items-cont">
|
|
<div class="zhanwei screenshot-hide"></div>
|
|
<div class="pricing-float-items" id="pricing-items2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--截图内容-->
|
|
<div id="screenshot" class="text-center screenshot-wrap" style="display:none;">
|
|
<div class="img-wrap">
|
|
<img id="screenshot-img" />
|
|
</div>
|
|
<div class="toolbar">
|
|
<button type="button" class="btn btn-primary" onclick="screenshoter.download()">保存截图</button>
|
|
<button type="button" class="btn btn-primary" onclick="screenshoter.closeShow()">关闭</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!--标的下拉选择显示模板-->
|
|
<script type="text/html" id="underlyingSuggestionTpl">
|
|
<div class="row no-gutters" style="padding:3px 10px;">
|
|
<div class="col text-left">${Code}</div>
|
|
<% if (!!Name) { %>
|
|
<div class="col-auto text-right text-truncate" style="width:70px;">${Name}</div>
|
|
<% } %>
|
|
</div>
|
|
</script>
|
|
|
|
<!--输入错误信息提示-->
|
|
<div class="modal" id="checkErrorModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">错误提示</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<table id="checkErrorTable" class="table table-bordered table-hover">
|
|
<colgroup>
|
|
<col span="1" width="100" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>编号</th>
|
|
<th>错误信息</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<th>1</th>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--交易录入-->
|
|
<div class="modal" tabindex="-1" id="modalTradeSave" data-backdrop="static">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content" style="width:520px;">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">交易保存</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form class="mx-auto form-layout form-layout-save p-0 m-0 border-0" style="width:500px;border-radius:0;box-shadow:none">
|
|
<div class="form-group">
|
|
<label class="form-label">簿记账户</label>
|
|
<input type="text" class="form-input" id="AssetId" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">交易员</label>
|
|
<input type="text" class="form-input" @(Model.CanSelectTrader ? "" : "readonly") id="TraderId" value="@(Model.Trade.TraderName)" data-id="@(Model.Trade.TraderId)" />
|
|
</div>
|
|
@if (!Model.ClientUsedForCalc)
|
|
{
|
|
<div class="form-group">
|
|
<label class="form-label">客户名称</label>
|
|
<input type="text" class="form-input" id="ClientId" />
|
|
</div>
|
|
}
|
|
<div id="salesCommissionCtrl"></div>
|
|
<div class="form-group">
|
|
<label class="form-label">交易编号</label>
|
|
<input type="text" class="form-input @(Model.UpperTradeNumber?"text-uppercase":"")" id="TradeNumber" maxlength="50" autocomplete="off" placeholder="不填则自动生成" />
|
|
</div>
|
|
|
|
@if (PS.Config.ErpElement.SecuritiesEnvironment)
|
|
{
|
|
<div class="form-group" hidden>
|
|
<label class="form-label">交易场所</label>
|
|
<select class="form-input" name="TradingPlace" id="TradingPlace">
|
|
@{
|
|
HtmlString html1 = new HtmlString("");
|
|
foreach (var item in YLErp.DBModels.Consts.ConsReport.TradingPlaceMap)
|
|
{
|
|
var str = "";
|
|
if (Model.Trade.MetaDic.ContainsKey("交易场所") && Model.Trade.MetaDic["交易场所"] == item.Key)
|
|
{
|
|
str = "selected='selected'";
|
|
}
|
|
<option @str>@item.Key</option>
|
|
}
|
|
}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group" hidden>
|
|
<label class="form-label">清算机构</label>
|
|
<select class="form-input" name="ClearingAgency" id="ClearingAgency">
|
|
@{
|
|
html1 = new HtmlString("");
|
|
foreach (var item in YLErp.DBModels.Consts.ConsReport.ClearingAgencyMap)
|
|
{
|
|
if (item.Key == "甲方" || item.Key == "乙方")
|
|
{
|
|
continue;
|
|
}
|
|
<option>@item.Key</option>
|
|
}
|
|
}
|
|
</select>
|
|
</div>
|
|
if (!Model.ClientUsedForCalc)
|
|
{
|
|
<div class="form-group">
|
|
<label class="form-label">主协议编号</label>
|
|
<select class="form-input" name="MainProtocolCode" id="MainProtocolCode">
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="formlabel">补充协议编号</label>
|
|
<select class="form-input" name="SupProtocolCode" id="SupProtocolCode">
|
|
</select>
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="form-group">
|
|
<label class="formlabel">中央对手方清算</label>
|
|
<select id="IsCentralClearing" class="form-input" name="IsCentralClearing">
|
|
<option value="N">否</option>
|
|
<option value="Y">是</option>
|
|
<option value="I">计划中央对手方清算</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="formlabel">中央清算平台</label>
|
|
<select id="CentralClearingPaltform" class="form-input" name="CentralClearingPaltform">
|
|
@foreach (var item in YLErp.BLL.DictionaryBLL.GetList("中央清算平台", true,"",true))
|
|
{
|
|
<option value="@item.Value">@item.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="formlabel">交易平台</label>
|
|
<select id="TradingPaltform" class="form-input" name="TradingPaltform">
|
|
@foreach (var item in YLErp.BLL.DictionaryBLL.GetList("交易平台", true, "", true))
|
|
{
|
|
<option value="@item.Value">@item.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
}
|
|
|
|
|
|
|
|
<div class="form-group" hidden>
|
|
<label class="form-label">交易对手方角色</label>
|
|
<select class="form-input" name="OpponentRole" id="OpponentRole">
|
|
<option>甲方</option>
|
|
<option selected>乙方</option>
|
|
</select>
|
|
</div>
|
|
@if (PS.Config.Company == CompanyEnum.东方财富)
|
|
{
|
|
<div class="form-group">
|
|
<label class="formlabel">初始预付金率</label>
|
|
<input type="number" class="form-input" id="InitialAdvance" />
|
|
<span>% </span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="formlabel">期间预付金率</label>
|
|
<input type="number" class="form-input" id="PeriodAdvance" />
|
|
<span>% </span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="formlabel">前端收益费率</label>
|
|
<input type="number" class="form-input" id="FontEarning" />
|
|
<span>% </span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="formlabel">追保线</label>
|
|
<input type="number" class="form-input" id="ConfirmedLine" />
|
|
<span>% </span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="formlabel">追保比例下限</label>
|
|
<input type="number" class="form-input" id="ConfirmedFloor" />
|
|
<span>% </span>
|
|
</div>
|
|
}
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<div class="mx-auto">
|
|
<button type="button" id="btnSave" class="btn btn-primary btn-save">录入交易</button>
|
|
<button type="button" class="btn btn-primary btn-close" data-dismiss="modal">关闭</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--加入组合-->
|
|
<div class="modal" tabindex="-1" id="modalGroupTradeSave" data-backdrop="static">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content" style="width:1020px;">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">组合交易保存</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form class="mx-auto form-layout form-layout-save p-0 m-0 border-0" style="width:990px;border-radius:0;box-shadow:none">
|
|
<div style="background-color: #F2F2F2; height: 15px; margin: unset;"></div>
|
|
<div style="background-color: #F2F2F2; height: 225px; margin: unset;">
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">交易日期</label>
|
|
<vue-datepicker class="text-box form-input" v-model="trade.TradeDate" disabled />
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">到期日期</label>
|
|
<vue-datepicker class="text-box form-input" v-model="trade.ExerciseDate" />
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">买卖方向</label>
|
|
<select class="form-input" v-model="trade.BuySell" v-on:change="changeBuySell()">
|
|
<option>卖出</option>
|
|
<option>买入</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">成交方式</label>
|
|
<select class="form-input" v-model="trade.IsUsePremiumRate" v-on:change="changeIsUsePremiumRate()">
|
|
<option :value="true">名义本金</option>
|
|
<option :value="false">成交数量</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">期初价格</label>
|
|
<vue-number-input class="form-input" v-model="trade.SpotPrice" v-bind:format="inputFormatSpot" disabled></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">成交数量</label>
|
|
<vue-number-input class="form-input" v-model="trade.TradeAmount" v-on:input="changeTradeAmount()" v-bind:format="inputFormatTradeAmount" v-bind:disabled="trade.IsUsePremiumRate"></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">名义本金</label>
|
|
<vue-number-input class="form-input" v-model="trade.StockEqvNotional" v-on:input="changeStockEqvNotional()" v-bind:format="inputFormatEqvNotional" v-bind:disabled="!trade.IsUsePremiumRate"></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">权利金</label>
|
|
<template v-if="trade.IsUsePremiumRate">
|
|
<vue-number-input class="form-input" v-model="trade.PremiumRate" v-bind:format="inputFormatPremiumRate" disabled></vue-number-input>
|
|
</template>
|
|
<template v-else>
|
|
<vue-number-input class="form-input" v-model="trade.TradeSinglePrice" v-bind:format="inputFormatSinglePriceOnly" disabled></vue-number-input>
|
|
</template>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">交易总额</label>
|
|
<vue-number-input class="form-input" v-model="trade.TradePrice" disabled></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">相对行权价</label>
|
|
<select class="form-input" v-model="trade.IsMoneynessOption">
|
|
<option>是</option>
|
|
<option>否</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div style="background-color: #CDE0E6; height: 15px; margin: unset;"></div>
|
|
<div class="customPanel">
|
|
<div class="form-group col-6">
|
|
<label class="form-label">结构类型</label>
|
|
<select class="form-input" v-model="trade.StructureType" v-on:change="changeStrucTureType()">
|
|
<option v-for="structureType in structureTypes">
|
|
{{ structureType }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<template v-if="trade.StructureType == '气囊结构'">
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">看涨看跌</label>
|
|
<select class="form-input" v-model="trade.OptionType">
|
|
<option>看涨</option>
|
|
<option>看跌</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">敲入价格</label>
|
|
<vue-number-input class="form-input" v-model="trade.trade_airbag.Barrier" v-bind:format="inputFormatStrike"></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">低执行价格</label>
|
|
<vue-number-input class="form-input" v-model="trade.Strike" v-bind:format="inputFormatStrike"></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">高执行价格</label>
|
|
<vue-number-input class="form-input" v-model="trade.trade_airbag.HighStrike" v-bind:format="inputFormatStrike" v-bind:disabled="!trade.trade_airbag.HasPayoffLimit"></vue-number-input>
|
|
<input type="checkbox" class="mr-1" v-model="trade.trade_airbag.HasPayoffLimit">
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">未敲入参与率</label>
|
|
<vue-number-input class="form-input" v-model="trade.trade_airbag.NotKIParticipationRate" v-bind:format="inputFormatPercent"></vue-number-input>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="formlabel">上涨参与率</label>
|
|
<vue-number-input class="form-input" v-model="trade.trade_airbag.KIParticipationRate" v-bind:format="inputFormatPercent"></vue-number-input>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<template v-for="(value,key,index) in PropertyMap">
|
|
<template v-if="key != '气囊结构'">
|
|
<div v-show="trade.StructureType == key">
|
|
<template v-for="(item,index) in value">
|
|
<div class="form-group col-6">
|
|
<template v-if="item.isNew">
|
|
<input type="text" class="form-input" style="width: 120px;" v-model="item.ColumnName" v-on:change="changeOption()" />
|
|
</template>
|
|
<template v-else>
|
|
<label class="formlabel">{{item.ColumnName}}</label>
|
|
</template>
|
|
<template v-if="item.ColumnType == @((int)YLErp.Enums.StructureColumnTypeEnum.NUMBER)">
|
|
<vue-number-input type="text" class="form-input" v-model="item.ColumnDefaultValue" v-bind:format="customNumberFormat"></vue-number-input>
|
|
</template>
|
|
<template v-else-if="item.ColumnType == @((int)YLErp.Enums.StructureColumnTypeEnum.NUMBERP)">
|
|
<vue-number-input type="text" class="form-input" v-model="item.ColumnDefaultValue" v-bind:format="customNumberPercentFormat"></vue-number-input>
|
|
</template>
|
|
<template v-else-if="item.ColumnType == @((int)YLErp.Enums.StructureColumnTypeEnum.DATE)">
|
|
<vue-datepicker class="text-box form-input" v-model="item.ColumnDefaultValue" />
|
|
</template>
|
|
<template v-else-if="item.ColumnType == @((int)YLErp.Enums.StructureColumnTypeEnum.COMBO_BOX_SINGLE)">
|
|
<select class="form-input" v-model="item.ColumnDefaultValue" autocomplete="off">
|
|
<option v-for="opt in item.ColumnOptions.split(',')" :value="opt" :key="opt">
|
|
{{opt}}
|
|
</option>
|
|
</select>
|
|
</template>
|
|
<template v-else>
|
|
@*YLErp.Enums.StructureColumnTypeEnum.TEXT*@
|
|
<input type="text" class="form-input" v-model="item.ColumnDefaultValue" />
|
|
</template>
|
|
<a class="fa fa-minus" style="margin-left: 10px;" v-on:click="deleteProperty(index)"></a>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<div class="form-group col-6" style="text-align: center;">
|
|
<button type="button" class="btn btn-primary btn-save" v-on:click="addNewProperty()">新增</button>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div style="background-color: #F2F2F2; height: 15px; margin: unset;"></div>
|
|
<div style="background-color: #F2F2F2; height: 180px;">
|
|
<div style="margin-left: 15px;">
|
|
<label class='formlabel'>交易备注</label>
|
|
<textarea rows='3' v-model="trade.Comments" class="text-box h-auto text-left" style="width: 80%"></textarea>
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="form-label">簿记账户</label>
|
|
<input type="text" class="form-input" id="GroupAssetId" />
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="form-label">交易员</label>
|
|
<input type="text" class="form-input" id="GroupTraderId" />
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="form-label">交易对手方</label>
|
|
<input type="text" class="form-input" id="GroupClientId" />
|
|
</div>
|
|
<div class="form-group col-6">
|
|
<label class="form-label">交易编号</label>
|
|
<input type="text" class="form-input" v-model="trade.TradeNumber" />
|
|
</div>
|
|
</div>
|
|
|
|
@*@if (Model.SecuritiesEnvironment)
|
|
{
|
|
<div class="form-group">
|
|
<label class="form-label">交易场所</label>
|
|
<select class="form-input" v-model="trade.TradingPlace">
|
|
@foreach (var item in YLErp.DBModels.Consts.ConsReport.TradingPlaceMap)
|
|
{
|
|
<option>@item.Key</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">清算机构</label>
|
|
<select class="form-input" v-model="trade.ClearingAgency">
|
|
@foreach (var item in YLErp.DBModels.Consts.ConsReport.ClearingAgencyMap)
|
|
{
|
|
if (item.Key == "甲方" || item.Key == "乙方")
|
|
{
|
|
continue;
|
|
}
|
|
<option>@item.Key</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
if (!Model.ClientUsedForCalc)
|
|
{
|
|
<div class="form-group">
|
|
<label class="form-label">主协议编号</label>
|
|
<select class="form-input" name="MainProtocolCode" id="MainProtocolCode">
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="formlabel">补充协议编号</label>
|
|
<select class="form-input" name="SupProtocolCode" id="SupProtocolCode">
|
|
</select>
|
|
</div>
|
|
}
|
|
}*@
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<div class="mx-auto">
|
|
<button type="button" class="btn btn-primary btn-save" data-dismiss="modal" v-on:click="saveGroupTrade()">录入组合交易</button>
|
|
<button type="button" class="btn btn-primary btn-close" data-dismiss="modal">关闭</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--对冲下单-->
|
|
<form id="orderForm" action="/RiskHedging/HedgingOrder" method="post" target="_blank" class="sr-only">
|
|
<input type="hidden" name="InstType" value="" />
|
|
</form>
|
|
|
|
@await Html.PartialAsync("_SyntheticPrice")
|
|
@await Html.PartialAsync("/Views/trade/_part/SalesCommission.cshtml", new SalesCommissionModel() { Disabled = false, ViewType = "期权" })
|
|
|
|
<!--自定义模板-->
|
|
<div class="modal" tabindex="-1" id="modalTemplate">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">自定义模板</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<template v-if="saveMode">
|
|
<form id="formTemplateSave" onsubmit="return false;">
|
|
<div class="form-group">
|
|
<label>模板名称</label>
|
|
<input type="text" class="form-control text-left" style="width:100%;" maxlength="50" v-model="saveData.name">
|
|
</div>
|
|
<div class="form-group">
|
|
<div><label><input type="checkbox" v-model="saveData._override" checked="" class="mr-1">覆盖已存在的模板</label></div>
|
|
<div>
|
|
<label><input type="checkbox" v-model="saveData._CommonTemplate" checked="" class="mr-1">保存为公共模板</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group text-center">
|
|
<button type="button" class="btn btn-primary" v-on:click="saveTemplate">保存模板</button>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
<template v-else>
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="yt-input-group d-inline-block">
|
|
<input type="text" class="search" v-model="searchText" placeholder="搜索" v-on:input="searchList" />
|
|
<a href="javascript:void(0)" class="yt-input-group-append show" v-on:click="searchList('reset')" style="padding-top:4px;" title="清除搜索"><i class="fa fa-remove"></i></a>
|
|
</div>
|
|
</div>
|
|
<div class="col text-right">
|
|
<a href="javascript:void(0)" v-on:click="refreshList" title="重新加载列表" style="line-height:30px;"><i class="fa fa-refresh"></i></a>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<ul class="list-group list-group-flush yt-template-group border">
|
|
<li class="list-group-item yt-template-item" v-for="item in listData" v-show="item.show">
|
|
<a href="javascript:void(0)" title="删除" class="yt-template-remove" v-on:click="removeTemplate(item.id)"><i class="fa fa-remove"></i></a>
|
|
<a href="javascript:void(0)" v-on:click="loadTemplate" class="yt-template-link">{{item.name}}</a><span>{{item.ConfigType==3?"公共模板":"个人模板"}}</span>
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|