Files
zszq-trs/YLErpWeb/wwwroot/Scripts/app/pricing/structure.js
T
hjhan 1c19d2f7c5 fix(EQD-7049): 新建空白期权定价页跳过空标的默认查询,避免'标的信息缺失'弹窗
- 页面初始化时 updateUnderlying 以空 UnderlyingCode/InstrumentType/VarietyId 发起 /pricing/AjaxGetUnderlying,后端三者皆空返回 JsonError('标的信息缺失') 并自动弹窗
- 前端守卫:三者皆空时仅重置空 underlying 并 return,不再发请求,与后端 AjaxGetUnderlying(PricingController.cs:398-414) 判定精确对应
- 不影响正常路径:选类型(InstrumentType)/品种(VarietyId>0)/具体标的(UnderlyingCode) 仍照常查询
- 同步修改东莞定制版 structure_dz.js
2026-08-14 17:49:59 +08:00

3093 lines
126 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//客户选择组件
const vueClient = function () {
return {
props: ['value'],
data() {
return { current: { id: 0, Name: '' } };
},
mounted() {
var self = this;
var id = parseInt(this.value);
if (id) {
this.current = _.clone(ylotc.clients.find(x => x.id === id));
}
var width = 152;
for (var i = 0; i < ylotc.clients.length; i++) {
let ele = document.createElement('span')
ele.innerText = ylotc.clients[i].Name;
ele.style.fontSize = '14px';
document.documentElement.append(ele);
var charLength = ele.offsetWidth + 28;//滚动条
document.documentElement.removeChild(ele);
if (charLength > width) {
width = charLength
}
}
FastVue.autocomplete(this.$el, {
valueField: 'Name', searchField: ['Name', 'PinYin'], lookup: ylotc.clients, width: width,
onSelect(data) {
self.current = _.clone(data);
if (self.value !== data.id) {
self.value = data.id;
self.$emit('input', self.value);
}
$(self.$el).blur();
}
});
},
watch: {
value(val, old) {
if (val !== old) {
var id = parseInt(val);
if (id !== this.current.id) {
this.current = _.clone(ylotc.clients.find(x => x.id === id) || { id: 0, Name: '' });
}
$(this.$el).data('select', '').attr("placeholder", '');
}
}
},
destroyed() {
FastVue.autocomplete.dispose(this.$el);
},
template: '<input id="txtCurrentClient" type="text" v-model="current.Name" :title="current.Name" :data-IsCentralClearing="current.IsCentralClearing" :data-CentralClearingPaltform="current.CentralClearingPaltform" :data-TradingPaltform="current.TradingPaltform"/>'
};
};
//品种选择组件
const vueVariety = function () {
return {
props: ['variety'],
mounted() {
var self = this;
FastVue.autocomplete(this.$el, {
valueField: 'Name', searchField: ['Name', 'Code', 'PinYin'],
lookup: ylotc.varieties,
onSelect(data) {
if (self.variety !== data) {
self.$emit('change-variety', data);
}
}
});
},
destroyed() {
FastVue.autocomplete.dispose(this.$el);
},
template: '<input type="text" v-model="variety.Name" />'
};
};
//期权类型选择组件
const vueTradeType = function () {
return {
props: ['value'],
mounted() {
var self = this;
FastVue.autocomplete(this.$el, {
valueField: 'value', searchField: ['value', 'pinyin'],
lookup: tradeHelper.OptionTradeTypes,
onSelect(data) {
if (self.value !== data.value) {
self.value = data.value;
self.$emit('input', self.value);
}
}
});
this.$el.value = this.value || '';
},
watch: {
value(val, old) {
if (val !== old) {
$(this.$el).val(this.value).data('select', '').attr("placeholder", '');
}
}
},
destroyed() {
FastVue.autocomplete.dispose(this.$el);
},
template: '<input type="text" maxlength="20" />'
};
};
//标的选择组件(EQD-7049:改为服务端搜索,不再依赖全量 ylotc.underlyings,避免十几万标的整段下载卡死)
const vueUnderlying = function () {
const _suggestionTpl = _.template($('#underlyingSuggestionTpl').html());
// 标的缓存:按 品种|关键词 隔离;乱序响应由 token 丢弃(helper 收在函数内,避免全局绑定冲突)
const _cache = {};
const _tokens = {};
function _fetch(varietyId, query, cb) {
var key = (varietyId || 0) + '|' + (query || '');
var token = (_tokens[key] = (_tokens[key] || 0) + 1);
var postData = {
FilterCode: (query || '').toUpperCase(),
VarietyId: varietyId || 0,
MaxShowLength: 20,
BlackLimit: 1,
UseForTrading: true,
IncludeMatured: true,
CheckLaunch: true
};
main.post('/frontdata/AjaxGetUnderlyingSelect', postData).done(function (res) {
if (_tokens[key] !== token) return; // 丢弃过期响应
var arr = (res && (res.obj || res.data)) || [];
var norm = arr.map(function (x) {
return {
Code: x.Code,
Name: x.Name,
InstrumentType: x.InstrumentType,
VarietyId: x.VarietyId,
Disallow: !!x.Disallow,
IsCombined: !!x.IsSynthetic || !!x.IsBasket,
BlackWhiteState: x.BlackWhiteState || 0,
PinYin: x.PinYin || ''
};
});
cb && cb(norm);
});
}
function _filter(list, query, varietyId) {
if (!query) return (list || []).slice(0, 20);
query = query.toUpperCase();
return (list || []).filter(function (x) {
if (varietyId && x.VarietyId !== varietyId) return false;
if (x.IsCombined) return false; // 与原逻辑一致:搜索时排除组合标的
return (x.Code && x.Code.toUpperCase().indexOf(query) !== -1)
|| (x.PinYin && x.PinYin.toUpperCase().indexOf(query) !== -1);
}).slice(0, 20);
}
return {
props: ['underlying'],
data() {
return { jqInput: null, autoctrl: null };
},
mounted() {
var self = this;
this.jqInput = $(this.$el).children(0);
// EQD-7049:预拉默认20条(当前品种),避免下拉空白
_fetch(self.underlying.VarietyId, '', function (list) {
_cache[self.underlying.VarietyId || 0] = list;
try { $(self.jqInput).autocomplete('search', ''); } catch (e) {}
});
this.autoctrl = FastVue.autocomplete(this.jqInput, {
valueField: 'Code',
lookup(query, callback) {
var varietyId = self.underlying.VarietyId;
var cached = _cache[varietyId || 0] || [];
var immediate = _filter(cached, query, varietyId);
if (query) {
// 有输入时异步向服务端搜索并刷新缓存(乱序响应由 token 丢弃)
_fetch(varietyId, query, function (list) {
_cache[varietyId || 0] = list;
});
}
return immediate;
},
onSelect(data) {
if (self.underlying !== data) {
self.$emit('change-underlying', data);
}
self.jqInput.blur();
},
formatResult(suggestion, currentValue) {
return _suggestionTpl(suggestion.data);
}
});
this.jqInput.val(this.underlying.Code);
},
methods: {
showInput() {
this.jqInput.show().focus().next().hide();
},
hideInput() {
this.jqInput.hide().next().show();
}
},
computed: {
showName() {
return (this.underlying.InstrumentType === 'Stock' || this.underlying.InstrumentType === 'StockIndex') ? this.underlying.Name : ' ';
}
},
destroyed() {
FastVue.autocomplete.dispose(this.jqInput);
},
template: '<div v-on:click="showInput"><input v-on:blur="hideInput" type="text" style="display:none" />' +
'<span>{{underlying.Code}}</span><span style="font-size:80%">{{showName}}</span></div>'
};
};
//预付金模板
const vueMarginTemplateName = function () {
return {
props: ['value'],
data() {
return { autoCtrl: null };
},
mounted() {
var self = this;
this.autoctrl = FastVue.autocomplete(this.$el, {
valueField: 'Value',
searchField: ['Value'],
lookup: ylotc.tradeMarginTemplateItems,
onSelect(data) {
if (self.value !== data.Value) {
self.value = data.Value;
self.$emit('input', self.value);
}
}
});
value = self.value || "系统默认";
this.autoctrl.setData({ Text: value, Value: value })
},
watch: {
value(newVal, oldVal) {
if (newVal !== oldVal) {
let data = ylotc.tradeMarginTemplateItems.find(x => x.Value === newVal);
this.autoctrl.setData(data || { Text: "系统默认", Value: "系统默认" })
}
}
},
destroyed() {
FastVue.autocomplete.dispose(this.$el);
},
template: '<input type="text" />'
};
}
//计算结果字段
const consCalcFields = Object.freeze(['TotalMargin', 'Pv', 'Delta', 'Gamma', 'Vega', 'Theta', 'Rho', 'PvContainsKnockOut', 'DeltaContainsKnockOut', 'DeltaInLots', 'GammaInLots', 'DeltaCash', 'GammaCash', 'VegaCash', 'GammaContainsKnockOut', 'Delta_r', 'Delta_r_1bp', 'Dv01', 'Gamma_r', 'Gamma_r_1bp', 'Vega_r', 'Vega_r_1bp']);
var _trades, _tradeVues, _salesCommissionCtrl;
//交易保存
const tradeSaver = (function () {
const needClient = !pageVue.ClientUsedForCalc;
function showTradeView(items) {
let item = items.shift();
if (!item) return;
let url = "/trade/tradeview?abstract=1&enid=" + item.EncryptId;
main.open("查看交易", url, {
end: function () {
showTradeView(items);
}
});
}
function _saveAccumulator() {
if (!_trades) return;
let AssetId = parseInt($('#accumulatorAssetId').data('id'));
let TraderId = parseInt($('#accumulatorTradeID').data('id'));
let ClientId = parseInt($('#accumulatorClientId').data('id'));
if (!AssetId) {
return main.alert("未设置簿记账户");
}
if (!TraderId) {
return main.alert("未设置交易员");
}
if (needClient && !ClientId) {
return main.alert("未设置客户");
}
let TradeNumber = $('#accumulatorTradeNumber').val();
let AssetBookName = $('#accumulatorAssetId').val();
let TraderName = $('#accumulatorTradeID').val();
let ClientName = $('#accumulatorClientId').val();
let TradingPlace = $("#accumulatorTradingPlace").val();
let ClearingAgency = $("#accumulatorClearingAgency").val();
let MainProtocolCode = $("#accumulatorMainProtocolCode").val();
let SupProtocolCode = $("#accumulatorSupProtocolCode").val();
let OpponentRole = $("#accumulatorOpponentRole").val();
let InitialAdvance = parseFloat($("#accumulatorInitialAdvance").val()) || 0;
let PeriodAdvance = parseFloat($("#accumulatorPeriodAdvance").val()) || 0;
let FontEarning = parseFloat($("#accumulatorFontEarning").val()) || 0;
let ConfirmedLine = parseFloat($("#accumulatorConfirmedLine").val()) || 0;
let ConfirmedFloor = parseFloat($("#accumulatorConfirmedFloor").val()) || 0;
let salesCommission = _salesCommissionCtrl.getValue();
let IsCentralClearing = $("#accumulatorIsCentralClearing").val();
let CentralClearingPaltform = $("#accumulatorCentralClearingPaltform").val();
let TradingPaltform = $("#accumulatorTradingPaltform").val();
let ExchangeRate = $("#accumulatorExchangeRate").val();
let QuoteCurrency = $("#accumulatorQuoteCurrency").val();
let SettlementMode = $("#SettlementMode").val();
let ForwardPriceType = $("#ForwardPriceType").val();
let ForwardDateType = $("#ForwardDateType").val();
let SettlementMode1 = $("#SettlementMode1").val();
let ForwardPriceType1 = $("#ForwardPriceType1").val();
let ForwardDateType1 = $("#ForwardDateType1").val();
let SettlementMode2 = $("#SettlementMode2").val();
let ForwardPriceType2 = $("#ForwardPriceType2").val();
let ForwardDateType2 = $("#ForwardDateType2").val();
let SettlementMode3 = $("#SettlementMode3").val();
let ForwardPriceType3 = $("#ForwardPriceType3").val();
let ForwardDateType3 = $("#ForwardDateType3").val();
let AccumuType = $("#AccumuType").val();
var tags = getSelectTags();
if (SettlementMode === '现金期末'&& _trades.some(x => x.EarlyTerminate && (x.AccumulatorStructureType + '') !== '1')) {
return main.alert("结算方式为'现金结算(期末)'时,需要将'敲出是否终止'设为'否'");
}
_trades.forEach(x => {
x.AssetId = AssetId;
x.AssetBookName = AssetBookName;
x.TraderId = TraderId;
x.TraderName = TraderName;
x.TradeNumber = TradeNumber;
x.SalesCommission = salesCommission;
if (needClient) {
x.ClientId = ClientId;
x.ClientName = ClientName;
}
if (x.TradePremium) {
x.MetaDic["交易溢价"] = x.TradePremium;
}
x.MetaDic["交易场所"] = TradingPlace;
x.MetaDic["清算机构"] = ClearingAgency;
x.MetaDic["主协议编号"] = MainProtocolCode;
x.MetaDic["补充协议编号"] = SupProtocolCode;
x.MetaDic["中央对手方清算"] = IsCentralClearing;
x.MetaDic["中央清算平台"] = CentralClearingPaltform;
x.MetaDic["ExchangeRate"] = ExchangeRate;
x.MetaDic["交易平台"] = TradingPaltform;
if (pageData.showCCR) {
//if (x.MarginType == 0) {
x.MetaDic["ccr_k"] = x.ccr_k || "0";
//}
x.MetaDic["ignoreRiskExposure"] = x.ignoreRiskExposure || "0";
}
x.TradeType === '现金流交易' && tradeUtils.resetCashFlow(x);
if (x.TradeType == '累计期权') {
if (x.AccumulatorStructureType.toString() === '1') {
x.SettlementMode = SettlementMode1;
x.ForwardPriceType = ForwardPriceType1;
x.ForwardDateType = ForwardDateType1;
x.SettlementMode2 = SettlementMode2;
x.ForwardPriceType2 = ForwardPriceType2;
x.ForwardDateType2 = ForwardDateType2;
x.SettlementMode3 = SettlementMode3;
x.ForwardPriceType3 = ForwardPriceType3;
x.ForwardDateType3 = ForwardDateType3;
} else {
x.AccumuType = AccumuType;
x.SettlementMode = SettlementMode;
x.ForwardPriceType = ForwardPriceType;
x.ForwardDateType = ForwardDateType;
}
}
x.OpponentRole = OpponentRole;
x.QuoteCurrency = QuoteCurrency;
x.InitialAdvance = InitialAdvance;
x.PeriodAdvance = PeriodAdvance;
x.FontEarning = FontEarning;
x.ConfirmedLine = ConfirmedLine;
x.ConfirmedFloor = ConfirmedFloor;
x.IsUsePremiumRate = (x.IsUsePremiumRate == "" || x.IsUsePremiumRate == null) ? false : x.IsUsePremiumRate;
x.Tags = tags;
x.IsUsePremiumRate = false;
extendVue2.setExtendInfo(x);
});
main.post("/pricing/AjaxSaveTrades", { trades: _trades }).done(function (resp) {
if (pageVue.IsImport) {
let url = "#/trade/tradeview?abstract=1&enid=" + resp.obj[0].EncryptId;
layer.closeMe(url);//必须以#开头
} else {
floatVue.hide();
$('#accumulatormodalTradeSave').modal('hide');
showTradeView(resp.obj);
_.each(_tradeVues, x => x.remove(true));
}
$(".tag-context .tag-item").remove();
});
}
//保存 录入增加字段时 ,累计也需要 增加html、js都要在对应字段保存,因时间仓促目前实现方式不好
function _save() {
if (!_trades) return;
let AssetId = parseInt($('#AssetId').data('id'));
let TraderId = parseInt($('#TraderId').data('id'));
let ClientId = parseInt($('#ClientId').data('id'));
if (!AssetId) {
return main.alert("未设置簿记账户");
}
if (!TraderId) {
return main.alert("未设置交易员");
}
if (needClient && !ClientId) {
return main.alert("未设置客户");
}
let TradeNumber = $('#TradeNumber').val();
let AssetBookName = $('#AssetId').val();
let TraderName = $('#TraderId').val();
let ClientName = $('#ClientId').val();
let TradingPlace = $("#TradingPlace").val();
let ClearingAgency = $("#ClearingAgency").val();
let MainProtocolCode = $("#MainProtocolCode").val();
let SupProtocolCode = $("#SupProtocolCode").val();
let OpponentRole = $("#OpponentRole").val();
let InitialAdvance = parseFloat($("#InitialAdvance").val()) || 0;
let PeriodAdvance = parseFloat($("#PeriodAdvance").val()) || 0;
let FontEarning = parseFloat($("#FontEarning").val()) || 0;
let ConfirmedLine = parseFloat($("#ConfirmedLine").val()) || 0;
let ConfirmedFloor = parseFloat($("#ConfirmedFloor").val()) || 0;
let salesCommission = _salesCommissionCtrl.getValue();
let IsCentralClearing = $("#IsCentralClearing").val();
let CentralClearingPaltform = $("#CentralClearingPaltform").val();
let TradingPaltform = $("#TradingPaltform").val();
let ExchangeRate = $("#ExchangeRate").val();
let QuoteCurrency = $("#QuoteCurrency").val();
var tags = getSelectTags();
_trades.forEach(x => {
x.AssetId = AssetId;
x.AssetBookName = AssetBookName;
x.TraderId = TraderId;
x.TraderName = TraderName;
x.TradeNumber = TradeNumber;
x.SalesCommission = salesCommission;
if (needClient) {
x.ClientId = ClientId;
x.ClientName = ClientName;
}
if (x.TradePremium) {
x.MetaDic["交易溢价"] = x.TradePremium;
}
x.MetaDic["交易场所"] = TradingPlace;
x.MetaDic["清算机构"] = ClearingAgency;
x.MetaDic["主协议编号"] = MainProtocolCode;
x.MetaDic["补充协议编号"] = SupProtocolCode;
x.MetaDic["中央对手方清算"] = IsCentralClearing;
x.MetaDic["中央清算平台"] = CentralClearingPaltform;
x.MetaDic["ExchangeRate"] = ExchangeRate;
x.MetaDic["交易平台"] = TradingPaltform;
if (pageData.showCCR) {
//if (x.MarginType == 0) {
x.MetaDic["ccr_k"] = x.ccr_k || "0";
//}
x.MetaDic["ignoreRiskExposure"] = x.ignoreRiskExposure || "0";
}
x.TradeType === '现金流交易' && tradeUtils.resetCashFlow(x);
x.OpponentRole = OpponentRole;
x.QuoteCurrency = QuoteCurrency;
x.InitialAdvance = InitialAdvance;
x.PeriodAdvance = PeriodAdvance;
x.FontEarning = FontEarning;
x.ConfirmedLine = ConfirmedLine;
x.ConfirmedFloor = ConfirmedFloor;
x.IsUsePremiumRate = (x.IsUsePremiumRate == "" || x.IsUsePremiumRate == null) ? false : x.IsUsePremiumRate;
x.Tags = tags;
extendVue.setExtendInfo(x);
});
main.post("/pricing/AjaxSaveTrades", { trades: _trades }).done(function (resp) {
if (pageVue.IsImport) {
let url = "#/trade/tradeview?abstract=1&enid=" + resp.obj[0].EncryptId;
layer.closeMe(url);//必须以#开头
} else {
floatVue.hide();
$('#modalTradeSave').modal('hide');
showTradeView(resp.obj);
_.each(_tradeVues, x => x.remove(true));
}
$(".tag-context .tag-item").remove();
});
}
//保存
function _saveTrades(tradeVues) {
_tradeVues = tradeVues;
if (!Array.isArray(_tradeVues)) {
throw "参数错误:tradeVues";
}
if (!_tradeVues.length) {
return main.alert("请至少勾选一条交易");
}
_trades = _.flatMap(_tradeVues, x => x.datas).map(x => {
x.viewState.synthetic && (x.trade.MetaDic["组合标的"] = JSON.stringify(x.viewState.synthetic));
return x.trade;
});
var viewStates = _.flatMap(_tradeVues, x => x.datas).map(x => x.viewState).filter(x => x.variety && x.variety.Code);
$("#QuoteCurrency").val(viewStates[0]?.variety.QuoteCurrency);
if ($("#QuoteCurrency").val() && $("#QuoteCurrency").val() != "CNY") {
$("#ExchangeRateDiv").show();
} else {
$("#ExchangeRateDiv").hide();
}
_trades = tradeUtils.prepareTrades(_trades, pageVue.getVolType(), true);
if (_trades) {
$('#TradeNumber').val('').parent().toggle(_tradeVues.length === 1);
var accumulatorStandard = _trades.filter(x => x.TradeType == "累计期权" && x.AccumulatorStructureType == "0");
var accumulatorSegmented = _trades.filter(x => x.TradeType == "累计期权" && x.AccumulatorStructureType == "1");
if (accumulatorSegmented.length > 0 && accumulatorStandard.length > 0) {
return main.alert("因累计结构类型不一致,不支持快速录入");
}
else if (accumulatorStandard.length > 0) {
var accumulatorPayoffType = accumulatorStandard.filter(x => x.PayoffType == "浮动");
if (accumulatorPayoffType.length != 0 && accumulatorPayoffType.length != accumulatorStandard.length) {
return main.alert("因上端收益类型不一致,不支持快速录入");
}
}
if (accumulatorSegmented.length > 0 || accumulatorStandard.length > 0) {
$('#accumulatormodalTradeSave').modal('show');
if (accumulatorSegmented.length > 0) {
$("#leiji").hide();
$("#leijisanduanshi").show();
} else {
$("#leijisanduanshi").hide();
$("#leiji").show();
var accumulatorPayoffTypeF = accumulatorStandard.filter(x => x.PayoffType == "固定");
$("#SettlementMode option").each(function (i, el) {
if ($(el).text() == "现金结算(期末)" && accumulatorPayoffTypeF.length > 0) {
$(this).attr("disabled", true);
} else {
$(this).attr("disabled", false);
}
})
}
} else {
$('#modalTradeSave').modal('show');
}
_setSalesman();
if (pageVue.SecuritiesEnvironment && !pageVue.ClientUsedForCalc) {
var clientId = parseInt($('#ClientId').data('id')) || _trades[0].ClientId;
_getMainProtocolCode(clientId);
}
return true;
}
return false;
}
function _setAutocomplete(elId, datas, initData, onSelectFn, width) {
initData = initData || datas[0] || {};
FastVue.autocomplete(document.getElementById(elId), {
valueField: 'Name', searchField: ['Name', 'PinYin'], lookup: datas, width: width,
onSelect(data) {
$('#' + elId).data('id', data.id);
if (elId === "ClientId") {
if (!pageVue.ClientUsedForCalc) {
$("#IsCentralClearing").val(data.IsCentralClearing);
$("#CentralClearingPaltform").val(data.CentralClearingPaltform);
$("#TradingPaltform").val(data.TradingPaltform);
}
_setSalesman();
}
onSelectFn && onSelectFn(data);
},
zIndex: 300000
}).setData(initData);
$('#' + elId).data('id', initData.id);
}
//保存组合交易
function _saveGroupTrades(tradeVues) {
_tradeVues = tradeVues;
if (!Array.isArray(_tradeVues)) {
throw "参数错误:tradeVues";
}
if (!_tradeVues.length) {
return main.alert("请至少勾选一条交易");
}
_trades = _.flatMap(_tradeVues, x => x.datas).map(x => {
x.viewState.synthetic && (x.trade.MetaDic["组合标的"] = JSON.stringify(x.viewState.synthetic));
return x.trade;
});
var viewStates = _.flatMap(_tradeVues, x => x.datas).map(x => x.viewState).filter(x => x.variety && x.variety.Code);
//验证分组交易是否是同标的同期初价格
$("#selQuoteCurrency").val(viewStates[0].variety.QuoteCurrency);
if ($("#selQuoteCurrency").val() && $("#selQuoteCurrency").val() != "CNY") {
$("#selExchangeRateDiv").show();
} else {
$("#selExchangeRateDiv").hide();
}
var underlyingId = 0;
var hasDiffUnderlying = false;
var spotPrice = 0;
var hasDiffPrice = false;
var tradeDate = null;
var exerciseDate = null;
var hasDiffTradeDate = false;
var buySell = groupVue.trade.BuySell;
var tradePrice = 0;
var clientIdArr = [];
_trades.forEach(x => {
if (x.TradeType != "现金流交易") {
if (underlyingId && underlyingId != x.UnderlyingId) {
hasDiffUnderlying = true;
}
else {
underlyingId = x.UnderlyingId;
}
if (spotPrice && parseFloat(spotPrice) != parseFloat(x.SpotPrice)) {
hasDiffPrice = true;
}
else {
spotPrice = x.SpotPrice;
}
if (!buySell) {
buySell = x.BuySell;
}
}
tradePrice += x.TradePrice * (x.BuySell == "卖出" ? 1 : -1);
if (tradeDate != null && tradeDate != x.TradeDate) {
hasDiffTradeDate = true;
}
else {
tradeDate = x.TradeDate;
}
if (exerciseDate == null || exerciseDate < x.ExerciseDate) {
exerciseDate = x.ExerciseDate;
}
if (clientIdArr.indexOf(x.ClientId) == -1 && x.ClientId > 0) {
clientIdArr.push(x.ClientId);
}
});
if (hasDiffUnderlying) {
main.alert("分组交易必须要保持相同的标的");
return false;
}
if (hasDiffPrice) {
main.alert("分组交易必须要保持相同的期初价格");
return false;
}
if (hasDiffTradeDate) {
main.alert("分组交易必须要保持相同的交易日期");
return false;
}
if (clientIdArr.length > 1) {
main.alert("分组交易必须要保持相同的客户");
return false;
}
_trades = tradeUtils.prepareTrades(_trades, pageVue.getVolType(), true);
if (_trades) {
$('#TradeNumber').val('').parent().toggle(_tradeVues.length === 1);
groupVue.viewState = viewStates[0];
groupVue.trade.TradeDate = tradeDate;
groupVue.trade.ExerciseDate = exerciseDate;
groupVue.trade.BuySell = buySell;
if (groupVue.trade.IsUsePremiumRate == null) {
groupVue.trade.IsUsePremiumRate = true
}
if (groupVue.trade.IsMoneynessOption == null) {
groupVue.trade.IsMoneynessOption = "是";
}
groupVue.trade.IsTradePricePayType = true;
groupVue.trade.TradePrice = tradePrice * (buySell == "卖出" ? 1 : -1);
groupVue.changeIsUsePremiumRate();
groupVue.trade.SpotPrice = spotPrice;
if (!groupVue.trade.StructureType) {
groupVue.trade.StructureType = "气囊结构";
groupVue.trade.OptionType = "看涨";
groupVue.trade.trade_airbag.Barrier = 0.8;
groupVue.trade.Strike = 1;
groupVue.trade.trade_airbag.NotKIParticipationRate = 1;
groupVue.trade.trade_airbag.KIParticipationRate = 1;
}
let stockEqvNotionalArrs = _trades.map((value, index, array) => {
return value.StockEqvNotional
});
groupVue.trade.StockEqvNotional = Math.max(...stockEqvNotionalArrs);
groupVue.changeStockEqvNotional();
if (clientIdArr.length > 0) {
groupVue.trade.ClientId = clientIdArr[0];
}
$('#modalGroupTradeSave').modal('show');
groupVue.init();
_setSalesman();
return true;
}
return false;
}
return {
saveTrades: _saveTrades,
saveGroupTrades: _saveGroupTrades,
init() {
_setAutocomplete('AssetId', ylotc.assetunits);
if (pageVue.CanSelectTrader) {
let trader = pageVue.Trade.TraderId > 0 ? ylotc.traders.find(x => x.id === pageVue.Trade.TraderId) : null;
if (!trader) {
trader = { Name: "", id: 0 }
}
_setAutocomplete('TraderId', ylotc.traders, { Name: trader.Name });
}
if (!pageVue.ClientUsedForCalc) {
var width = 300;
for (var i = 0; i < ylotc.clients.length; i++) {
let ele = document.createElement('span')
ele.innerText = ylotc.clients[i].Name;
ele.style.fontSize = '14px';
document.documentElement.append(ele);
var charLength = ele.offsetWidth + 28;//滚动条
document.documentElement.removeChild(ele);
if (charLength > width) {
width = charLength
}
}
_setAutocomplete('ClientId', ylotc.clients, null, (pageVue.SecuritiesEnvironment ? _getMainProtocolCode : null), width);
}
//组合标的控件
synthenticPriceCtrl.init({
getSynthetic(input) {
return consSyntheticMap[input.dataset.calcid];
},
setSynthetic(input, synthetic) {
var calcid = input.dataset.calcid;
_.each(pricingVue.getTradeVues(), x => !x.updateSynthetic(calcid, synthetic));
}
});
//销售提成控件
_salesCommissionCtrl = new SalesCommissionCtrl(document.getElementById('salesCommissionCtrl'), pageVue.SalesCommission);
//累计
_setAutocomplete('accumulatorAssetId', ylotc.assetunits);
if (pageVue.CanSelectTrader) {
let trader = pageVue.Trade.TraderId > 0 ? ylotc.traders.find(x => x.id === pageVue.Trade.TraderId) : null;
if (!trader) {
trader = { Name: "", id: 0 }
}
_setAutocomplete('accumulatorTradeID', ylotc.traders, { Name: trader.Name });
}
if (!pageVue.ClientUsedForCalc) {
var width = 300;
for (var i = 0; i < ylotc.clients.length; i++) {
let ele = document.createElement('span')
ele.innerText = ylotc.clients[i].Name;
ele.style.fontSize = '14px';
document.documentElement.append(ele);
var charLength = ele.offsetWidth + 28;//滚动条
document.documentElement.removeChild(ele);
if (charLength > width) {
width = charLength
}
}
_setAutocomplete('accumulatorClientId', ylotc.clients, null, (pageVue.SecuritiesEnvironment ? _getMainProtocolCode : null), width);
}
//销售提成控件
_salesCommissionCtrl = new SalesCommissionCtrl(document.getElementById('salesaccumulatorCommissionCtrl'), pageVue.SalesCommission);
_setSalesman();
$('#btnSave').on('click', _save);
$('#btnAccumulatorSave').on('click', _saveAccumulator);
if (pageData.is厦门象屿) {
$("#SettlementMode").val("现金实物合并结算");
$("#SettlementMode1").val("现金实物合并结算");
$("#SettlementMode2").val("现金实物合并结算");
$("#SettlementMode3").val("现金实物合并结算");
$("#ForwardPriceType").val("远期开仓现价");
$("#ForwardPriceType1").val("远期开仓现价");
$("#ForwardPriceType2").val("远期开仓现价");
$("#ForwardPriceType3").val("远期开仓现价");
$("#ForwardDateType option").each(function (i, el) {
if ($(el).text() == "标的交割月前一交易日") {
$("#ForwardDateType").val("标的交割月前一交易日");
}
})
$("#ForwardDateType1 option").each(function (i, el) {
if ($(el).text() == "标的交割月前一交易日") {
$("#ForwardDateType1").val("标的交割月前一交易日");
}
})
$("#ForwardDateType2 option").each(function (i, el) {
if ($(el).text() == "标的交割月前一交易日") {
$("#ForwardDateType2").val("标的交割月前一交易日");
}
})
$("#ForwardDateType3 option").each(function (i, el) {
if ($(el).text() == "标的交割月前一交易日") {
$("#ForwardDateType3").val("标的交割月前一交易日");
}
})
$("#AccumuType").attr("disabled", false);
$("#AccumuType option").each(function (i, el) {
if ($(el).text() == "子弹") {
$(this).attr("disabled", true);
} else {
$(this).attr("disabled", false);
}
})
}
else {
$("#ForwardPriceType").attr("disabled", true);
$("#ForwardDateType").attr("disabled", true);
$("#ForwardPriceType1").attr("disabled", true);
$("#ForwardDateType1").attr("disabled", true);
$("#ForwardPriceType2").attr("disabled", true);
$("#ForwardDateType2").attr("disabled", true);
$("#ForwardPriceType3").attr("disabled", true);
$("#ForwardDateType3").attr("disabled", true);
$("#AccumuType").attr("disabled", true);
}
$("#SettlementMode").change(function () {
$("#AccumuType").val('');
$("#AccumuType").attr("selected", true);
if ($("#SettlementMode").val() == "实物交割" || $("#SettlementMode").val() == "现金实物合并结算") {
$("#AccumuType").attr("disabled", false);
$("#ForwardPriceType").attr("disabled", false);
$("#ForwardDateType").attr("disabled", false);
$("#AccumuType option").each(function (i, el) {
if ($(el).text() == "子弹") {
$(this).attr("disabled", true);
} else {
$(this).attr("disabled", false);
}
})
} else {
$("#AccumuType").attr("disabled", true);
$("#ForwardPriceType").attr("disabled", true);
$("#ForwardDateType").attr("disabled", true);
}
if ($("#SettlementMode").val() == "现金期末") {
$("#AccumuType").attr("disabled", false);
$("#AccumuType option").each(function (i, el) {
if ($(el).text() == "区间现金结算") {
$(this).attr("disabled", true);
} else {
$(this).attr("disabled", false);
}
})
}
})
$("#SettlementMode1").change(function () {
if ($("#SettlementMode1").val() == "实物交割" || $("#SettlementMode1").val() == "现金实物合并结算") {
$("#ForwardPriceType1").attr("disabled", false);
$("#ForwardDateType1").attr("disabled", false);
} else {
$("#ForwardPriceType1").attr("disabled", true);
$("#ForwardDateType1").attr("disabled", true);
}
})
$("#SettlementMode2").change(function () {
if ($("#SettlementMode2").val() == "实物交割" || $("#SettlementMode2").val() == "现金实物合并结算") {
$("#ForwardPriceType2").attr("disabled", false);
$("#ForwardDateType2").attr("disabled", false);
} else {
$("#ForwardPriceType2").attr("disabled", true);
$("#ForwardDateType2").attr("disabled", true);
}
})
$("#SettlementMode3").change(function () {
if ($("#SettlementMode3").val() == "实物交割" || $("#SettlementMode3").val() == "现金实物合并结算") {
$("#ForwardPriceType3").attr("disabled", false);
$("#ForwardDateType3").attr("disabled", false);
} else {
$("#ForwardPriceType3").attr("disabled", true);
$("#ForwardDateType3").attr("disabled", true);
}
})
$("#btnCloseInputTrade").click(function () {
$('#modalTradeSave').modal('hide');
$(".tag-context .tag-item").remove();
});
$("#btnAccumulatorCloseInputTrade").click(function () {
$('#accumulatormodalTradeSave').modal('hide');
$(".tag-context .tag-item").remove();
})
$('#MainProtocolCode').on('change', _changeMainProtocolCode);
$('#modalTradeSave').on('show.bs.modal', function () {
$('#TradeNumber').val('');
_salesCommissionCtrl.reset();
});
$('#accumulatormodalTradeSave').on('show.bs.modal', function () {
$('#TradeNumber').val('');
_salesCommissionCtrl.reset();
});
}
};
}());
//截图
const screenshoter = (function () {
var _layerIndex;
function execute(tradeVue) {
if (!tradeVue.floating) {
floatVue.show(tradeVue, true);
}
pageVue.viewState.SS_SinglePrincipalWrite = tradeVue.datas.reduce((p, x) => p + (parseFloat(x.trade.SinglePrincipalWrite) || 0), 0);
pageVue.viewState.SS_PrincipalSum = tradeVue.datas.reduce((p, x) => p + (parseFloat(x.trade.OriginalPrincipalSum) || 0), 0);
var $fs = $('#for-screenshot');
$fs.parent().children().addClass('for-screenshot');
$fs.closest('.modal').css('margin-top', -999999);
setTimeout(function () {//OTC-8517 在结构跟香草之间来回切换生成截图时,香草的高度会变成结构的高度,页面需要过段时间才会更新
var opts = { bgcolor: '#fff', width: tradeVue.datas.length * 200 + 140, height: $fs.height() };
domtoimage.toPng($fs[0], opts).then(function (dataUrl) {
$('#screenshot-img').attr('src', dataUrl);
_layerIndex = layer.open({
type: 1, closeBtn: 0, title: false, scrollbar: false, shadeClose: true,
area: ['auto', '50%'], content: $('#screenshot'), offset: '100px',
success: function (layero, index) {
setTimeout(function () {
let height = $('#screenshot-img').height();
height > 100 && layero.children('.layui-layer-content').css('height', height + 100);
}, 100);
}
});
}).catch(function (error) {
main.alert('截图发生错误:' + error);
}).finally(function () {
$fs.closest('.modal').css('margin-top', 0);
$fs.parent().children().removeClass('for-screenshot');
if (!tradeVue.floating) {
$('#floatModal').modal('hide');
}
});
}, 10)
}
function closeShow() {
layer.close(_layerIndex);
}
//保存截图
function download() {
domtoimage.toBlob(document.getElementById('screenshot-img'))
.then(function (blob) {
moment().format();
window.saveAs(blob, '报价' + moment().format('YYYYMMDDHHmmss') + '.png');
});
}
return {
execute: execute,
download: download,
closeShow: closeShow
};
}());
//#singleprice
const singlePricer = (function () {
const _sumDatas = [];
//datas:[{Pv,Notional}]
function _calcSinglePrice(datas) {
let tradeSinglePrice = 0;
var result = _.reduce(datas, (acc, data) => {
if (Array.isArray(data)) {
_.each(data, item => {
acc.totalPv += parseFloat(item.Pv) || 0;
var notional = parseFloat(item.Notional) || 0;
tradeSinglePrice += parseFloat(pricingFormat.tradeSinglePrice((parseFloat(item.Pv) || 0) / notional));
if (acc.minNotional > notional) {
acc.minNotional = notional;
}
});
} else if (data) {
acc.totalPv += parseFloat(data.Pv) || 0;
var notional = parseFloat(data.Notional) || 0;
tradeSinglePrice += parseFloat(pricingFormat.tradeSinglePrice((parseFloat(data.Pv) || 0) / notional));
if (acc.minNotional > notional) {
acc.minNotional = notional;
}
}
return acc;
}, { totalPv: 0, minNotional: Number.MAX_SAFE_INTEGER });
var singlePrice = Math.abs(result.minNotional) < 1e-5 ? "0.00"
: pricingFormat.tradeSinglePrice(Math.abs(result.totalPv) / result.minNotional);
if (pageObj.IsTradeSinglePriceCalcu) {
return pageVue.CompanyName + (tradeSinglePrice >= 0 ? "付" : "收") + pricingFormat.tradeSinglePrice(Math.abs(tradeSinglePrice));
} else {
return pageVue.CompanyName + (result.totalPv >= 0 ? "付" : "收") + singlePrice;
}
}
//重设统计单价
function _reset() {
var singlePrice = _calcSinglePrice(_sumDatas);
$('#singleprice').text(singlePrice);
}
const _debounceReset = _.debounce(_reset, 300);
return {
//data:[{Pv,Notional}]
reset(index, data) {
_sumDatas[index] = !data || Array.isArray(data) ? data : [data];
_debounceReset();
},
//datas:[{Pv,Notional}]
calcSinglePrice: _calcSinglePrice
};
}());
//pageVue状态
(function () {
const viewState = { VolType: '交易', structureType: '', SS_PrincipalSum: 0, SS_SinglePrincipalWrite: 0 };
_.extend(pageVue, {
viewState: viewState,
getVolType() { return viewState.VolType; },
setVolType(value) { viewState.VolType = value; },
getStructureType() { return viewState.structureType; },
setStructureType(value) { viewState.structureType = value; }
});
//冻结修改
_.each([pageVue], x => Object.freeze(x));
}());
//一个简单的事件总线
const EventBus = (new function () {
var _bus;
function getBus() {
return _bus || (_bus = document.createElement('div'));
}
//增加事件监听
this.addEventListener = function (event, callback) {
getBus().addEventListener(event, callback);
};
//移除事件监听
this.removeEventListener = function (event, callback) {
getBus().removeEventListener(event, callback);
};
//激发事件
this.triggerEvent = function (event, detail = {}) {
getBus().dispatchEvent(new CustomEvent(event, { detail }));
};
//仅供调试用
this.getEventListeners = function () {
return getEventListeners(getBus());
};
}())
//顶部组件
const topVue = (function () {
return new Vue({
el: '#pricing-top',
data: {
viewState: pageVue.viewState,
simpleMode: pageVue.SimpleMode,
calcMargin: pageVue.CalcMargin && pageVue.ShowInitialMargin,
calcAutocallGreeks: pageVue.CalcAutocallGreeks,
},
mounted() {
},
methods: {
changeVolType() {
pricingVue.changeVolType();
},
addStructure(type, typeCn) {
pageVue.setStructureType(typeCn);
var url = "/trade/structureoptionV2?name=" + type;
main.open("添加策略", url, { area: ['500px', '800px'] });
},
normOtcTrade(td) {
if (!pageData.is厦门象屿 && td.TradeType !== "Risky期权") {
td.PremiumPayDate = '';
}
td.Notional = pricingFormat.notional(td.Notional);
td.TradeAmount = pricingFormat.notional(td.TradeAmount);
td.TradePrice = pricingFormat.tradePrice(td.TradePrice);
td.StockEqvNotional = pricingFormat.StockEqvNotional(td.StockEqvNotional);
td.StockEqvNotionalReal = pricingFormat.StockEqvNotional(td.StockEqvNotionalReal);
tradeUtils.normalizeTrade(td);
return td;
},
importTrade() {
let tradeNumber = $('#importTradeNumber').val().trim();
if (!tradeNumber) return;
var self = this;
main.post('/pricing/AjaxGetOtcTradeFull?tradeNumber=' + encodeURIComponent(tradeNumber)).done(function (resp) {
if (resp.obj) {
pricingVue.addTrade(self.normOtcTrade(resp.obj));
} else {
main.alert('没有找到交易数据');
}
}).always(function () {
});
},
toggleSimpleMode() {
this.simpleMode = !this.simpleMode;
EventBus.triggerEvent('simpleMode.changed');
main.post("/sysuserConfig/AjaxSaveOtcWebConfig", { name: 'Pricing_SimpleMode', value: this.simpleMode }, false);
},
toggleCalcMargin() {
this.calcMargin = !this.calcMargin;
main.post("/sysuserConfig/AjaxSaveOtcWebConfig", { name: 'Pricing_CalcMargin', value: this.calcMargin }, false);
},
toggleCalcAutocallGreeks() {
this.calcAutocallGreeks = !this.calcAutocallGreeks;
main.post("/sysuserConfig/AjaxSaveOtcWebConfig", { name: 'Pricing_CalcAutocallGreeks', value: this.calcAutocallGreeks }, false);
}
}
})
}());
//统计组件
const summaryVue = (function () {
const _summaryDatas = [];
const summary = _.reduce(consCalcFields, (acc, cur) => {
acc[cur] = 0;
return acc;
}, {});
//重设统计合计
function _resetSummary() {
var datas = _.flatMap(_summaryDatas, x => x && x.length > 0 ? x : []);
var UnderlyingCode = '';
var isSameCode = _.every(datas, x => {
return !x.UnderlyingCode ? true : (UnderlyingCode ? x.UnderlyingCode === UnderlyingCode : UnderlyingCode = x.UnderlyingCode);
});
if (isSameCode) {
_.each(summary, (val, key) => {
summary[key] = 0;
});
_.each(datas, data =>
_.each(consCalcFields, field => summary[field] += parseFloat(data[field]) || 0)
);
} else {
_.each(summary, (val, key) => {
summary[key] = 'NaN';
});
summary.Pv = summary.TotalMargin = summary.Rho = 0;
_.each(datas, data => {
summary.Pv += parseFloat(data.Pv) || 0;
summary.TotalTradePrice += parseFloat(data.TradePrice) || 0;
summary.Rho += parseFloat(data.Rho) || 0;
summary.TotalMargin += parseFloat(data.TotalMargin) || 0;
});
}
if (!pageVue.TwoSideMargin) {
//如果为负数,则显示0
summary.TotalMargin < 0 && (summary.TotalMargin = 0);
}
}
const _debounceReset = _.debounce(_resetSummary, 300);
const _vue = new Vue({
el: '#pricing-summary',
data: {
summary: summary
},
computed: {
DeltaHands() {
var delta = this.summary.DeltaInLots;
return typeof delta !== 'number' ? delta
: (delta > 0 ? "卖" : "买") + pricingFormat.greek(Math.abs(delta)) + '手';
}
},
filter: {
greekFmt(val) {
return typeof val !== 'number' ? val : pricingFormat.greek(val);
}
}
});
return {
getVue() {
return _vue;
},
//data:consCalcFields
reset(index, data) {
_summaryDatas[index] = !data || Array.isArray(data) ? data : [data];
_debounceReset();
}
};
}());
//视图呈现器
const renders = (function () {
function _getHtml($tpl, removeClass) {
var html = $tpl.html();
var $temp = $('<div>').append(html);
$temp.find(removeClass).remove();
$temp.find('template').each(function () {
html = _getHtml($(this), removeClass);
$(this).html(html);
});
return $temp.html();
}
//定价视图呈现器
const title = Vue.compile(_getHtml($('#pricingItem_tpl'), '.pitem,.pitem-cash'));
const item = Vue.compile(_getHtml($('#pricingItem_tpl'), '.ptitle,.pitem-cash:not(.pitem)'));
const itemCash = Vue.compile(_getHtml($('#pricingItem_tpl'), '.ptitle,.pitem:not(.pitem-cash)'));
const items = Vue.compile($('#pricingItems_tpl').html() || '');
return {
title(forStatic) {
return forStatic ? title.staticRenderFns : title.render;
},
item(forStatic) {
return forStatic ? item.staticRenderFns : item.render;
},
itemCash(forStatic) {
return forStatic ? itemCash.staticRenderFns : itemCash.render;
},
items(forStatic) {
return forStatic ? items.staticRenderFns : items.render;
}
};
}());
//单个定价组件
const vueTrade = function () {
return {
props: ['trade', 'viewState', 'calcResult', 'floating'],
data() {
return {
isTitle: false,
canEditEngineName: true,
...consVueTrade.data(),
fieldState: tradeFieldMgr.getFieldState(this.floating),
tradeMarginTemplates: ylotc.tradeMarginTemplates,
binaryPayoffTypes: this.trade.ExerciseMode === 'European' ?
consBinaryPayoffTypes.European : consBinaryPayoffTypes.American,
engineNames: tradeUtils.getEngineNames(this.trade),
ExerciseModes: this.trade.TradeType === '障碍期权' ? [{ value: 'European', text: '欧式' }] : tradeHelper.ExerciseModes
};
},
watch: {
'trade.Notional': {
handler(newVal, oldVal) {
this.resetSummary(resetSummaryFlags.notional);
},
immediate: false
},
'trade.TradeType': {
handler(newVal, oldVal) {
this.updateKey.KIPayoffType = new Date().getTime();
this.fieldState.onTradeTypeChanged(this.trade, oldVal, this);
this.fieldState.setFieldState('TradeAmount', (newVal === '累计期权'));
if (this.trade.TradeType === '累计期权') {
this.trade.IsUsePremiumRate = false;
if (this.trade.AccumulatorStructureType == '1') {
this.trade.EarlyTerminate = false;
if (this.trade.PayoffType === '固定' && this.trade.OptionType === '看涨') {
this.trade.Multiplier2 = 1;
this.trade.Multiplier3 = 1;
}
if (this.trade.PayoffType === '固定' && this.trade.OptionType === '看跌') {
this.trade.Multiplier1 = 1;
this.trade.Multiplier2 = 1;
}
}
}
if (this.trade.TradeType === '障碍期权') {
this.ExerciseModes = [{ value: 'European', text: '欧式' }];
} else {
this.ExerciseModes = tradeHelper.ExerciseModes;
}
this.changeEngineName();
},
immediate: true
},
'trade.ExerciseDate': {
handler(newVal, oldVal) {
this.trade.SettlementDate = newVal;
this.changeIsAnnualized();
},
immediate: false
},
'trade.AccumulatorStructureType': {
handler(newVal, oldVal) {
if (this.trade.AccumulatorStructureType == '1') {
this.trade.EarlyTerminate = false;
}
},
immediate: false
},
'trade.PayoffType': {
handler(newVal, oldVal) {
if (this.trade.TradeType == "累计期权" && this.trade.AccumulatorStructureType == '1' && this.trade.PayoffType === '固定') {
if (this.trade.OptionType === '看涨') {
this.trade.Multiplier = 1;
this.trade.Multiplier2 = 1;
this.trade.Multiplier3 = 1;
}
if (this.trade.OptionType === '看跌') {
this.trade.Multiplier = 1;
this.trade.Multiplier2 = 1;
this.trade.Multiplier3 = 1;
}
}
this.changeEngineName();
},
immediate: false
},
'trade.OptionType': {
handler(newVal, oldVal) {
if (this.trade.TradeType == "累计期权" && this.trade.AccumulatorStructureType == '1' && this.trade.PayoffType === '固定') {
if (this.trade.OptionType === '看涨') {
this.trade.Multiplier = 1;
this.trade.Multiplier2 = 1;
this.trade.Multiplier3 = 1;
}
if (this.trade.OptionType === '看跌') {
this.trade.Multiplier = 1;
this.trade.Multiplier2 = 1;
this.trade.Multiplier3 = 1;
}
}
},
immediate: false
},
'trade.EnhancedPrice': {
handler(newVal, oldVal) {
this.changeEngineName();
},
immediate: true
},
'trade.StrikeType': {
handler(newVal, oldVal) {
this.changeEngineName();
},
immediate: false
}
},
created: consVueTrade.created,
mounted() {
consSyntheticMap[this.trade.CalcId] = this.viewState.synthetic;
if (pageVue.ClientUsedForCalc) {
if (!this.trade.ClientId) {
ylotc.clients.length && (this.trade.ClientId = ylotc.clients[0].id);
if (this.trade.ClientId) {
this.changeClient();
}
} else {
this.updateKey.client = new Date().getTime();
}
}
this.$nextTick(function () {
switch (this.viewState.initFlag) {
case 'first':
this.viewState.initFlag = '';
this.changeInstrumentType();
break;
case 'import1':
case 'import2':
case 'template':
!this.floating && this.updateUnderlying({ UnderlyingCode: this.trade.UnderlyingCode });
break;
}
});
topVue.simpleMode && (this.trade.UnderlyingPrice = '');
!this.floating && EventBus.addEventListener('simpleMode.changed', this.onSimpleModeChanged);
},
methods: {
...consVueTrade.methods,
//变更客户
changeClient() {
this.$emit('change-client', this.trade.ClientId);
},
//变更期权类型
changeTradeType() {
this.viewState.Observation.hasValue = false;
this.viewState.KOObservation.hasValue = false;
this.changeExerciseMode('TradeType');
this.refreshEngineNames();
if (this.trade.TradeType === "现金流交易") {
tradeUtils.resetCashFlow(this.trade);
} else if (this.trade.TradeType === "Risky期权") {
tradeUtils.resetRisky(this.trade);
}
},
//变更标的类型
changeInstrumentType() {
if (new Date().getTime() < this.updateKey.underlying + 300) return;
let instType = this.trade.UnderlyingInstrumentType;
this.viewState.variety = tradeHelper.getEmptyVariety(instType);
this.updateUnderlying({ InstrumentType: instType });
},
//变更标的品种
changeVariety(variety) {
this.viewState.variety = variety;
$("#QuoteCurrency").val(this.viewState.variety.QuoteCurrency);
this.updateUnderlying({ VarietyId: variety.id });
},
//变更标的
changeUnderlying(underlying) {
if (underlying.Disallow) {
if (underlying.IsCombined) {
main.alert(underlying.BlackWhiteState === 1 ? "该组合中包含存在于黑名单的标的" : "该组合中包含不在白名单中的标的");
}
else {
main.alert(underlying.BlackWhiteState === 1 ? "该标的存在于黑名单中" : "该标的不在白名单中");
return;
}
}
this.viewState.underlying = underlying;
this.updateUnderlying({ UnderlyingCode: underlying.Code }, true);
this.changeEffectRatio();
},
//变更定价模型
changeEngineName() {
// 增强亚式期权,在执行价格和增强价格不一致的情况下,默认只支持使用蒙特卡洛计算引擎
if (tradeUtils.changeEngineName(this.trade)) {
this.canEditEngineName = false;
} else {
this.canEditEngineName = true;
}
},
//更新标的
updateUnderlying(reqData, fromSelect) {
let self = this;
// EQD-7049:新建空白页未选标的/品种/类型时,跳过必然失败的后端默认标的查询,避免报“标的信息缺失”
var hasQueryKey = !!(reqData.UnderlyingCode || reqData.InstrumentType || reqData.VarietyId > 0);
if (!hasQueryKey) {
!fromSelect && (self.viewState.underlying = tradeHelper.getEmptyUnderlying());
return;
}
var instTypeChanged = !!reqData.InstrumentType;
!fromSelect && (self.viewState.underlying = tradeHelper.getEmptyUnderlying());
main.post("/pricing/AjaxGetUnderlying", reqData).done(function (resp) {
let trade = self.trade;
let um = resp.obj.underlying;
if (!fromSelect) {
self.viewState.underlying = {
id: um.id, Code: um.UnderlyingCode, Name: um.UnderlyingName,
InstrumentType: um.UnderlyingInstrumentType, VarietyId: um.UnderlyingTypeId,
QuoteUnitString: um.QuoteUnitString
};
}
self.updateKey.underlying = new Date().getTime();
instTypeChanged || (instTypeChanged = trade.UnderlyingInstrumentType !== um.UnderlyingInstrumentType);
trade.UnderlyingId = um.id;
trade.UnderlyingCode = um.UnderlyingCode;
trade.UnderlyingName = um.UnderlyingName;
trade.UnderlyingInstrumentType = um.UnderlyingInstrumentType;
trade.VarietyId = um.UnderlyingTypeId;
trade.CountRatio = um.CountRatio;
self.viewState.variety = _.clone(ylotc.varieties.find(x => x.id === um.UnderlyingTypeId))
|| tradeHelper.getEmptyVariety(trade.UnderlyingInstrumentType);
self.updateKey.variety = new Date().getTime();
if (self.viewState.initFlag === 'import1') {
self.getTTM(false, false);
return self.viewState.initFlag = '';
}
if (self.viewState.initFlag === 'template') {
return self.viewState.initFlag = '';
}
trade.DividendRate = um.DividendRate;
self.viewState.synthetic = consSyntheticMap[trade.CalcId] = resp.obj.synthetic;
//初始预付金
trade.InitialMargin = 0;
//加载结构化交易
if (self.viewState.initFlag === 'import2') {
trade.SettlementDate = trade.ExerciseDate;
(trade.TradeOpenVolatility !== '') && (self.viewState.VolState = 'user');
(trade.TradeCloseVolatility !== '') && (self.viewState.CloseVolState = 'user');
self.changeTradeDate('import2');
if (trade.PremiumRate !== '' || trade.TradeSinglePrice !== '') {
trade.PremiumRate !== '' ? self.changePremiumRate() : self.changeTradeSinglePrice();
} else {
trade.PremiumRate = trade.TradeSinglePrice = trade.TradePrice = 0;
}
return self.viewState.initFlag = '';
}
//重置权利金
trade.PremiumRate = trade.TradeSinglePrice = trade.TradePrice = 0;
trade.SpotPrice = pricingFormat.umprice(um.Price);
//重置视图状态
_.each(tradeFieldMgr.defaultData.viewState, (val, key) => {
if (key === 'VolState' && self.viewState['VolLockState'] !== 'system') {
val = 'user';
}
else if (key !== 'VolLockState') {
val === 'system' && (self.viewState[key] = "system");
}
});
//根据标的类型切换,权益类默认名义本金成交方式
if (um.UnderlyingInstrumentType === "Stock" || um.UnderlyingInstrumentType === "StockIndex") {
if (!trade.DividendRate) {
trade.DividendRate = 0;
}
trade.IsUsePremiumRate = trade.TradeType!=='累计期权';
//名义本金影响交易数量
self.changeStockEqvNotional(1e6);
if (trade.IsMoneynessOption !== "是" || !trade.Strike) {
trade.Strike = pricingFormat.umprice(um.Price);
self.showPercentStrike();
instTypeChanged = true;
}
} else {
trade.IsUsePremiumRate = false;
self.changeTradeAmount(instTypeChanged ? 1 : null);
if (trade.IsMoneynessOption === "是" || !trade.Strike) {
trade.Strike = "1";
self.showAbsStrike();
instTypeChanged = true;
}
}
//如果资产大类变更则清除掉IsMoneynessOption和IsUsePremiumRate关联的字段值
instTypeChanged && tradeUtils.onChangeInstrumentType(trade);
//到期日ExerciseDate默认为1个月之后,股票到期日不显示
trade.TradeDate = pageVue.SysDate;
trade.ExerciseDate = new moment(um.ExerciseDate).format("YYYY-MM-DD");
trade.MaturityDate = new moment(um.MaturityDate || "2029-01-01").format("YYYY-MM-DD");
trade.TradeDate > trade.ExerciseDate && (trade.TradeDate = trade.ExerciseDate);
if (trade.TradeType === "Risky期权") {
if (trade.IsMoneynessOption === "是") {
trade.Strike1 = "";
trade.Strike2 = "";
trade.Strike3 = 1;
} else {
trade.Strike1 = "";
trade.Strike2 = "";
trade.Strike3 = um.Price;
}
}
self.changeTradeDate(true, true);
if (pageData.is厦门象屿 || trade.TradeType === "Risky期权") {
trade.PremiumPayDate = trade.ExerciseDate;
}
//重置计算结果
self.calcResult.reset();
if (fromSelect) {
self.resetSummary(resetSummaryFlags.all);
}
});
},
//刷新波动率,影响波动率的属性:SpotPrice,Strike,TradeDate,ExerciseDate,UnderlyingId
getVol(debounce) {
if (this.trade.TradeType === "现金流交易") return;
if (pageVue.IsTradeVol) {
let flag = 0;
if (!pageVue.SkewMapVol) {
this.viewState.VolState !== 'user' && (flag |= 1);
this.viewState.CloseVolState !== 'user' && (flag |= 2);
if (flag === 0) return;
} else {
flag = 1 | 2;
}
if (debounce === true) {
if (!this.debounceGetVol) {
this.debounceGetVol = _.debounce(function (t) {
(t.flag & 1) > 0 && t.vue.getTradeOpenVolatility();
(t.flag & 2) > 0 && t.vue.getTradeCloseVolatility();
}, 1000, { trailing: true });
}
this.debounceGetVol({ vue: this, flag: flag });
} else {
(flag & 1) > 0 && this.getTradeOpenVolatility();
(flag & 2) > 0 && this.getTradeCloseVolatility();
}
} else if (this.viewState.VolState !== 'user') {
this.getTradeOpenVolatility();
}
},
//重置统计数据
resetSummary(flag) {
this.$emit('reset-summary', flag);
},
//获取标的价格(计算用)
getUnderlyingPrice() {
var self = this;
return main.post("/pricing/AjaxGetUnderlyingPrice", { underlyingCode: this.trade.UnderlyingCode, tradeDate: this.trade.ValueDate })
.done(function (resp) {
self.trade.UnderlyingPrice = pricingFormat.umprice(resp.obj.price);
});
},
//精简模式切换时的处理
onSimpleModeChanged() {
this.trade.UnderlyingPrice = '';
}
},
computed: { ...consVueTrade.computed },
components: {
'vue-margintemplatename': vueMarginTemplateName(),
'vue-niceselect': FastVue.vueNiceSelect(),
'vue-variety': vueVariety(),
'vue-tradetype': vueTradeType(),
'vue-underlying': vueUnderlying(),
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
'vue-daycount': vueDayCount(),
'vue-client': vueClient(),
},
render: renders.item(),
staticRenderFns: renders.item(true),
destroyed() {
delete consSyntheticMap[this.trade.calcId];
topVue.simpleMode && (this.trade.UnderlyingPrice = '');
EventBus.removeEventListener('simpleMode.changed', this.onSimpleModeChanged);
}
};
};
//单个定价组件(现金流)
const vueTrade2 = function () {
return {
props: ['trade', 'viewState', 'calcResult', 'floating'],
data() {
return {
isTitle: false,
...consVueTrade.data(),
fieldState: tradeFieldMgr.getFieldState(this.floating),
};
},
watch: {
'trade.ExerciseDate': {
handler(newVal, oldVal) {
this.trade.SettlementDate = newVal;
},
immediate: false
}
},
mounted() {
if (pageVue.ClientUsedForCalc) {
if (!this.trade.ClientId) {
ylotc.clients.length && (this.trade.ClientId = ylotc.clients[0].id);
if (this.trade.ClientId) {
this.changeClient();
}
} else {
this.updateKey.client = new Date().getTime();
}
}
this.fieldState.onTradeTypeChanged(this.trade, null, this);
this.trade.IsUsePremiumRate = true;
},
methods: {
...consVueTrade.methods,
//变更客户
changeClient() {
this.$emit('change-client', this.trade.ClientId);
},
//重置统计数据
resetSummary(flag) {
this.$emit('reset-summary', flag);
}
},
computed: { ...consVueTrade.computed },
components: {
'vue-niceselect': FastVue.vueNiceSelect(),
'vue-client': vueClient(),
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
'vue-daycount': vueDayCount(),
},
render: renders.itemCash(),
staticRenderFns: renders.itemCash(true),
destroyed() {
}
};
};
//主视图定价头部拖动处理
const mainDragScroll = dragScroll.create({ container: '.pricing-main', yscroll: false, throttle: _.throttle });
//定价组件组合
function createVue(index, baseVue, floating) {
var datas = baseVue.datas;
var fromLocal = baseVue.fromLocal === true;
if (datas.length < 1) {
return main.alert('缺少数据');
}
var structureType = baseVue.combining && datas.length > 1 ? '结构化交易' : baseVue.structureType || '';
_.each(datas, (data, index2) => {
data.trade.CalcId = index + '-' + (index2 + 1);
if (!data.calcResult) {
data.calcResult = {
sourceData: null,
reset(data) {
this.sourceData = data;
if (!data) {
_.each(consCalcFields, x => this[x] = '');
}
}
};
_.each(consCalcFields, x => data.calcResult[x] = '');
} else if (baseVue.combining) {
data.calcResult = _.cloneDeep(data.calcResult);
}
if (!data.trade.UnderlyingInstrumentType) {
data.trade.UnderlyingInstrumentType = pageVue.StockFirst ? 'Stock' : 'CommodityFutures';
}
data.trade.StructureType = structureType;
});
if (datas.length === 1) {
datas[0].trade.CalcId = index.toString();
}
var debounceFloatSinglePrice = _.debounce(singlePricer.calcSinglePrice, 300);
var vue = new Vue({
data: {
index: index,
datas: datas,
floating: floating,
isSelected: !!baseVue.isSelected,
structureType: structureType,
showFloatingIcon: !structureType || datas.every(x => x.trade.TradeType === '香草期权')
},
computed: {
},
mounted() {
if (this.floating) {
var singlePrice = singlePricer.calcSinglePrice(this.convertForSinglePrice());
singlePrice && $('#singleprice2').text(singlePrice);
} else {
pricingVue.onMountd(this);
}
},
methods: {
getData(index) {
return this.datas[index || 0];
},
getVol() {
_.each(this.$children, x => x.getVol());
},
remove(blRemoveChain) {
this.$destroy();
this.$el.remove();
pricingVue.remove(this, blRemoveChain);
},
saveTrade() {
tradeSaver.saveTrades([this]);
},
showFloatVue() {
floatVue.show(this);
let td = this.getData(0);
setTimeout(function () {//交易详情页-定价增强价格不显示问题
if (td && td.trade.TradeType == "亚式期权" && td.trade.StrikeType != "Floating" && td.trade.PayoffType == 'EnhancedArithmeticAverage') {
$("#EnhancedPriceTitle").show();
}
}, 500);
},
screenshot() {
screenshoter.execute(this);
},
uncouple() {
pricingVue.uncouple(this);
},
convertForSinglePrice() {
return _.reduce(this.datas, (result, data) => {
var sdata = data.calcResult.sourceData;
sdata && (result || (result = [])).push({ Pv: sdata.Pv, Notional: data.trade.Notional });
return result;
}, null);
},
//重置统计数据
resetSummary(flag) {
//浮窗页面
if (this.floating && flag < resetSummaryFlags.ten) {
var singlePrice = singlePricer.calcSinglePrice(this.convertForSinglePrice());
singlePrice && $('#singleprice2').text(singlePrice);
}
//主页面
if (this.isSelected) {
if (flag === resetSummaryFlags.initialMargin) {
var data = this.datas[this.datas.length - 1];
data.calcResult.TotalMargin = pageVue.GetTotalMargin(_.map(this.datas, x => x.trade), this.structureType);
return summaryVue.reset(this.index, this.datas.map(x => x.calcResult));
}
singlePricer.reset(this.index, this.convertForSinglePrice());
if (flag !== resetSummaryFlags.notional) {
summaryVue.reset(this.index, this.datas.map(x => x.calcResult));
}
}
else if (flag === true) {
summaryVue.reset(this.index, null);
singlePricer.reset(this.index, null);
}
},
setCalcResult(result) {
var data = _.find(this.datas, x => x.trade.CalcId === result.CalcId);
if (!data) {
return main.alert('系统错误');
}
var trade = data.trade;
if (topVue.calcMargin) {
if (data.viewState.InitialMargin !== 'user' || (data.viewState.InitialMargin === 'user' && trade.InitialMargin === '')) {
if (pageVue.ClientUsedForCalc && pageVue.TwoSideMargin &&
!data.viewState.TwoSideMargin && result.initialMargin < 0
&& !trade.StructureType) {
trade.InitialMargin = 0;
}
else {
trade.InitialMargin = pricingFormat.tradePrice(result.initialMargin);
}
data.viewState.InitialMargin = "system";
}
} else {
trade.InitialMargin = '';
}
var calcResult = data.calcResult;
var contractSize = result.contractSize;
//对象缩小为具体计算结果
result = result.calcResult;
calcResult.reset(result);
//用于统计
calcResult.UnderlyingCode = trade.UnderlyingCode;
if (trade.IsUsePremiumRate) {
trade.TradePrice = result.Pv * (trade.BuySell == "买入" ? 1 : -1);
if (trade.TradeType !== "现金流交易") {
//根据总额算出期权费率
tradePricing.tradeCalc(trade, tradePricing.calcReason.Pv);
//由于期权费率会有精度损失,进行了四舍五入处理,需要再根据期权费率反算出期权费总额
//因为录入交易时是根据期权费率作为标准的
tradePricing.tradeCalc(trade, tradePricing.calcReason.PremiumRate);
}
else {
trade.TradePrice = pricingFormat.tradePrice(trade.TradePrice);
}
}
else {
let notional = trade.Notional;
if (trade.TradeType == "累计期权") {
var datas = {
kOObservationDates: trade.KOObservationDates,
valueDate: trade.ValueDate || trade.TradeDate,
tradeDate: trade.TradeDate,
exerciseDate: trade.ExerciseDate,
}
var dayCount = 0;
main.post("/trade_cash/GetAccTradeUnwindDayCount", datas, { async: false }).done(
function (res) {
dayCount = res.obj;
}
);
notional = dayCount * trade.AccumuTradeAmount;
trade.Notional = notional;
}
var pv = result.Pv * (trade.BuySell == "买入" ? 1 : -1);
trade.TradeSinglePrice = notional ? pv / notional : 0;
tradePricing.tradeCalc(trade, tradePricing.calcReason.TradeSinglePrice);
}
//result.Pv = (result.Pv < 0 ? -1 : 1) * trade.TradePrice;
if (pageObj.IsPVIncludePrincipal && trade.OriginalPrincipalSum > 0) {
result.Pv += trade.OriginalPrincipalSum * (trade.BuySell === '卖出' ? -1 : 1);
result.PvContainsKnockOut += trade.OriginalPrincipalSum * (trade.BuySell === '卖出' ? -1 : 1);
}
//todo:光子模式下是否要重设TradeOpenVolatility的值
// delta gamma 用手数,其它份额 Vegapho份额*100 qdp用的是份额计算
//现在计算的是数量 份额数量比
//手数 = 交易数量 / 交易单位 (5吨 / 手)
//交易数量 = 份额 / 比率
//手数 = 份额 / (比率 * 交易单位)
//TradeUnitValue 是手数对份额的比率 鸡蛋时为 10
var variety = data.viewState.variety;
var fe_ration = 1;
!contractSize && (contractSize = variety && variety.ContractSize ? variety.ContractSize : 1);
calcResult.Pv = pricingFormat.tradePrice(result.Pv);
calcResult.Delta = pricingFormat.greek(result.Delta);
calcResult.Gamma = pricingFormat.greek(result.Gamma);
calcResult.DeltaInLots = pricingFormat.greek(result.Delta / contractSize);
calcResult.GammaInLots = pricingFormat.greek(result.Gamma / contractSize);
calcResult.Theta = pricingFormat.greek(fe_ration * result.Theta);
calcResult.Vega = pricingFormat.greek(fe_ration * result.Vega);
calcResult.Rho = pricingFormat.greek(fe_ration * result.Rho * 100);
calcResult.DeltaCash = pricingFormat.greek(result.DeltaCash);
calcResult.GammaCash = pricingFormat.greek(result.GammaCash);
calcResult.VegaCash = pricingFormat.greek(result.VegaCash);
calcResult.PvContainsKnockOut = pricingFormat.tradePrice(result.PvContainsKnockOut);
calcResult.DeltaContainsKnockOut = pricingFormat.greek(result.DeltaContainsKnockOut);
calcResult.GammaContainsKnockOut = pricingFormat.greek(result.GammaContainsKnockOut);
calcResult.Delta_r = result.Delta_r ? pricingFormat.greek(result.Delta_r) : "";
calcResult.Delta_r_1bp = result.Delta_r_1bp ? pricingFormat.greek(result.Delta_r_1bp) : "";
calcResult.Dv01 = result.Dv01 ? pricingFormat.greek(result.Dv01) : "";
calcResult.Gamma_r = result.Gamma_r ? pricingFormat.greek(result.Gamma_r) : "";
calcResult.Gamma_r_1bp = result.Gamma_r_1bp ? pricingFormat.greek(result.Gamma_r_1bp) : "";
calcResult.Vega_r = result.Vega_r ? pricingFormat.greek(result.Vega_r) : "";
calcResult.Vega_r_1bp = result.Vega_r_1bp ? pricingFormat.greek(result.Vega_r_1bp) : "";
calcResult.TotalMargin = 0;
if (data === this.datas[this.datas.length - 1]) {
calcResult.TotalMargin = pageVue.GetTotalMargin(_.map(this.datas, x => x.trade), this.structureType);
}
this.resetSummary(resetSummaryFlags.all);
},
changeClient(clientId) {
let client = null;
if (pageVue.ClientUsedForCalc && pageVue.TwoSideMargin) {
client = ylotc.clients.find(y => y.id === clientId);
}
_.each(this.datas, x => {
x.trade.ClientId = clientId;
x.trade.MarginOptionType = client.MarginOptionType;
x.viewState.TwoSideMargin = client && client.MarginOptionType === 1;
x.trade.MarginTemplateName = client.MarginOptionType === 3 ? "无预付金" : "系统默认";
tradeUtils.changeMarginTemplate(x.trade, []);
});
},
updateSynthetic(calcId, synthetic) {
var index = this.datas.findIndex(x => x.trade.CalcId === calcId);
if (index < 0) return false;
this.datas[index].trade.SpotPrice = synthetic.Price;
this.$children[index].changeSpotPrice(true);
return true;
},
copyThis() {
pricingVue.copyItem(this);
}
},
components: {
'vue-trade': vueTrade(),
'vue-trade2': vueTrade2(),
},
destroyed() {
if (!this.floating && this.isSelected) {
summaryVue.reset(this.index, null);
singlePricer.reset(this.index, null);
}
},
render: renders.items(),
staticRenderFns: renders.items(true)
});
if (!baseVue.combining && !baseVue.selfMount) {
if (vue.floating) {
vue.$mount($('<div>').appendTo('#pricing-items2').get(0));
} else if (fromLocal) {
vue.$mount($('<div>').appendTo('#pricing-items').get(0));
} else {
vue.$mount($('<div>').prependTo('#pricing-items').get(0));
}
}
!floating && mainDragScroll.reset();
return vue;
}
function _setAutocomplete(elId, datas, initData, onSelectFn) {
initData = initData || {};
if (elId === "GroupClientId") {
groupVue.trade.ClientId = initData.id;
groupVue.trade.ClientName = initData.Name;
}
else if (elId === "GroupAssetId") {
groupVue.trade.AssetId = initData.id;
groupVue.trade.AssetBookName = initData.Name;
}
else if (elId === "GroupTraderId") {
groupVue.trade.TraderId = initData.id;
groupVue.trade.TraderName = initData.Name;
}
FastVue.autocomplete(document.getElementById(elId), {
valueField: 'Name', searchField: ['Name', 'PinYin'], lookup: datas,
onSelect(data) {
$('#' + elId).data('id', data.id);
if (elId === "ClientId" || elId === "GroupClientId") {
if (!pageVue.ClientUsedForCalc || elId === "GroupClientId") {
$("#selIsCentralClearing").val(data.IsCentralClearing);
$("#selCentralClearingPaltform").val(data.CentralClearingPaltform);
$("#selTradingPaltform").val(data.TradingPaltform);
}
_setSalesman();
}
onSelectFn && onSelectFn(data);
},
zIndex: 300000
}).setData(initData);
$('#' + elId).data('id', initData.id);
}
function _setSalesman() {
if (pageVue.ClientUsedForCalc) {
var IsCentralClearing = $("#txtCurrentClient").attr("data-IsCentralClearing");
var CentralClearingPaltform = $("#txtCurrentClient").attr("data-CentralClearingPaltform");
var TradingPaltform = $("#txtCurrentClient").attr("data-TradingPaltform");
$("#IsCentralClearing").val(IsCentralClearing);
$("#CentralClearingPaltform").val(CentralClearingPaltform);
$("#TradingPaltform").val(TradingPaltform);
}
if ($("#ClientId").data('id') && _salesCommissionCtrl) {
_salesCommissionCtrl.changeSalesmen($("#ClientId").data('id'));
_getMainProtocolCode($("#ClientId").data('id'));
}
}
function _changeMainProtocolCode() {
_getSupProtocolCode();
}
function _getMainProtocolCode(client) {
$("#MainProtocolCode option").remove();
if (client) {
let clientId = typeof client === 'object' ? client.id : client;
main.post("/Client/getMainProtocolCodes", { clientId: clientId }, { async: false }).done(function (resp) {
var obj = $("#MainProtocolCode");
_.forEach(resp, (v) => {
obj.append("<option >" + v.Text + "</option>");
})
});
}
_getSupProtocolCode()
}
function getSelectTags() {
var tags = new Array();
$(".tag-context .tag-item").each(function (i, v) {
var exist = false;
var name = $(v).data("name");
tags.forEach(function (o) {
if (o.Name == name) {
exist = true;
}
});
if (!exist) {
tags.push({ Id: $(v).data("id"), Name: name });
}
});
return tags;
}
function _getSupProtocolCode() {
$("#SupProtocolCode option").remove();
if ($("#MainProtocolCode").val()) {
main.post("/Client/getSideProtocols", { mainProtocol: $("#MainProtocolCode").val() }, { async: false }).done(function (resp) {
var obj = $("#SupProtocolCode");
_.forEach(resp, (v) => {
obj.append("<option >" + v + "</option>");
})
});
}
}
function CalcResultShowCfg() {
var srcurl = "/CalcPriceShowCfg/Index";
main.open("计算指标显示设置", srcurl, { area: ["800px", "700px"] });
}
//定价组件
const pricingVue = (function () {
//创建定价标题组件
function createTitleVue(el, floating) {
var vue = new Vue({
el: el,
data: {
trade: {},
isTitle: true,
floating: floating,
fieldState: tradeFieldMgr.getTitleState(floating)
},
render: renders.title(),
staticRenderFns: renders.title(true)
});
return vue;
}
createTitleVue('#pricing-titles', false);
createTitleVue('#pricing-titles2', true);
var _index = 1;
//定价组件集合
const _tradeVues = [];
function __clear() {
if (!_tradeVues.length) return;
_index = 0;
_tradeVues.splice(0, _tradeVues.length).forEach(x => x.remove());
$('#pricing-items').parent().floatingScroll('update');
}
//清空
function clear(force) {
if (!_tradeVues.length) return;
if (force) {
__clear();
} else {
main.confirmV2("确认清空吗?").done(__clear);
}
}
//移除
function remove(tradeVue, blRemoveChain) {
if (blRemoveChain && tradeVue.floating) {
var baseVue = _tradeVues.find(x => x.index === tradeVue.index);
baseVue && baseVue.remove();
}
_.pull(_tradeVues, tradeVue);
$('#pricing-items').parent().floatingScroll('update');
}
//新增单腿
function addTrade(trade, tradeType) {
_index += 1;
let baseVue = _tradeVues[0] || { datas: [tradeFieldMgr.defaultData] };
if (trade && typeof trade === 'object') {
let viewState = _.cloneDeep(tradeFieldMgr.defaultData.viewState);
viewState.initFlag = 'import1';
baseVue = { datas: [{ trade: trade, viewState: viewState }] };
} else if (tradeType === "现金流交易") {
let data = tradeFieldMgr.defaultData;
data = {
trade: _.cloneDeep(data.trade),
viewState: _.cloneDeep(data.viewState)
};
_tradeVues.length < 1 && (data.viewState.initFlag = 'first');
data.trade.IsUsePremiumRate = true;
baseVue = { datas: [data] };
trade = data.trade;
}
else {
let data = baseVue.datas[0];
data = {
trade: _.cloneDeep(data.trade),
viewState: _.cloneDeep(data.viewState)
};
_tradeVues.length < 1 && (data.viewState.initFlag = 'first');
baseVue = { datas: [data] };
trade = data.trade;
}
if (typeof tradeType === 'string' && trade.TradeType !== tradeType) {
trade.TradeType = tradeType;
tradeFieldMgr.initFieldValue(trade);
}
if (trade.TradeAmount && !trade.TradeAmountV) {
trade.TradeAmountV = tradeHelper.getTradeAmountV(trade);
}
let vue = createVue(_index, baseVue);
_tradeVues.unshift(vue);
if (pageVue.IsImport || !new Array('香草期权', '合成价差期权').includes(trade.TradeType)) {
floatVue.show(vue);
}
}
//复制项目
function copyItem(tradeVue) {
var arrIndex = _.indexOf(_tradeVues, tradeVue);
if (arrIndex < 0) {
throw '系统错误';
}
_index += 1;
let baseVue = tradeVue;
baseVue = { datas: _.cloneDeep(baseVue.datas), structureType: baseVue.structureType, selfMount: true };
var vue = createVue(_index, baseVue);
vue.$mount($('<div>').insertBefore(tradeVue.$el).get(0));
_tradeVues.splice(arrIndex, 0, vue);
}
//新增策略
function addTrades(trades) {
var datas = _.map(trades, trade => {
trade = _.transform(trade, (result, val, key) => {
key in result && (result[key] = val);
}, _.cloneDeep(pageVue.Trade));
if (trade.UnderlyingInstrumentType !== 'Stock' && trade.UnderlyingInstrumentType !== 'StockIndex') {
trade.StockEqvNotionalReal = pricingFormat.StockEqvNotional(trade.Notional * trade.SpotPrice);
trade.StockEqvNotional = trade.StockEqvNotionalReal;
}
else {
trade.StockEqvNotionalReal = trade.StockEqvNotional;
}
trade.SpotPrice = trade.UnderlyingPrice;
trade.NoRiskRate = null;
trade.DividendRate = 0;
trade.ParticipationRate = 1;
trade.AnnualizeFactor = 1;
if (pageVue.NumOfSmoothingDaysCfg === 'ONE' && pageVue.IsTradeVol) {
trade.NumOfSmoothingDays = 1;
}
tradeUtils.normalizeTrade(trade);
let viewState = _.cloneDeep(tradeFieldMgr.defaultData.viewState);
viewState.initFlag = 'import2';
return { trade: trade, viewState: viewState };
});
_index += 1;
var vue = createVue(_index, { datas: datas, structureType: pageVue.getStructureType() });
_tradeVues.unshift(vue);
}
//自由组合
function combine() {
var comVues = _.filter(_tradeVues, x => x.isSelected);
if (comVues.length < 2) {
return main.alert('请选择至少两项进行组合!');
}
var firstVue = comVues[0];
var datas = _.flatMap(comVues.map(x => x.datas));
if (pageVue.ClientUsedForCalc) {
var clientId = parseInt(datas[0].trade.ClientId);
if (!_.every(datas, x => parseInt(x.trade.ClientId) === clientId)) {
return main.alert('所选项客户必须一致!');
}
}
var vue = createVue(firstVue.index, { combining: true, datas: datas, fromLocal: true });
vue.$mount($('<div>').insertBefore(firstVue.$el).get(0));
var index = _.indexOf(_tradeVues, firstVue);
_tradeVues[index] = vue;
_.pullAll(_tradeVues, comVues);
comVues.forEach(x => x.remove());
}
//取消组合
function uncouple(tradeVue) {
if (!tradeVue || tradeVue.floating) {
throw '系统错误';
}
var arrIndex = _.indexOf(_tradeVues, tradeVue);
if (arrIndex < 0) {
throw '系统错误';
}
var index = _index += tradeVue.datas.length;
var map = _.map(tradeVue.datas, data => {
var vue = createVue(index--, { combining: true, datas: [data], fromLocal: true });
vue.$mount($('<div>').insertBefore(tradeVue.$el).get(0));
return vue;
});
var args = [arrIndex, 1].concat(map);
Array.prototype.splice.apply(_tradeVues, args);
tradeVue.remove();
}
//波动率类型变更
function changeVolType() {
_tradeVues.forEach(x => x.getVol());
}
//获取所有交易数据
function getTrades() {
return _.flatMap(_tradeVues.map(x => x.datas)).map(x => x.trade);
}
//录入交易
function saveTrades() {
tradeSaver.saveTrades(_tradeVues.filter(x => x.isSelected));
}
//录入组合交易
function saveGroupTrades() {
tradeSaver.saveGroupTrades(_tradeVues.filter(x => x.isSelected));
}
//定价计算
function calcPrice(tradeVues) {
!tradeVues && (tradeVues = _tradeVues);
if (!tradeVues.length) {
return main.alert("请至少录入一个交易");
}
var trades = _.flatMap(tradeVues, x => x.datas).map(x => x.trade);
//检查并转换数据
trades = tradeUtils.prepareTrades(trades, pageVue.getVolType(), false);
if (trades) {
let data = {
version: pageVue.CalcVersion,
trades: trades, calcMargin: topVue.calcMargin,
calcAutocallGreeks: topVue.calcAutocallGreeks
};
main.post("/pricing/ajaxCalcPrices", data).done(function (resp) {
//tradeVues转换为calcId为key的字典
var map = tradeVues.reduce((result, cur) => {
_.each(cur.datas, x => {
result[x.trade.CalcId] = cur;
});
return result;
}, {});
//设置计算结果
_.each(resp.obj, item => {
map[item.CalcId].setCalcResult(item);
});
});
}
}
//显示组合到期收益曲线图形
function showPayoffLineChart(tradeVues) {
var selectVues = _.filter(_tradeVues, x => x.isSelected);
!tradeVues && (tradeVues = selectVues);
if (!tradeVues.length) {
return main.alert("请至少录入一个交易");
}
var trades = _.flatMap(tradeVues, x => x.datas).map(x => x.trade);
//检查并转换数据
trades = tradeUtils.prepareTrades(trades, pageVue.getVolType(), false);
window.sessionStorage.removeItem("pricing_payoff_line");
if (trades) {
main.post("/pricing/GetTradesPayoffLine", { trades: trades }).done(function (resp) {
//resp.obj
window.sessionStorage.setItem("pricing_payoff_line", JSON.stringify(resp));
window.open("/Statics/html/PayoffChart.html");
});
}
}
//显示组合Pv曲线
function showPvChart(tradeVues) {
var selectVues = _.filter(_tradeVues, x => x.isSelected);
!tradeVues && (tradeVues = selectVues);
if (!tradeVues.length) {
return main.alert("请至少录入一个交易");
}
var trades = _.flatMap(tradeVues, x => x.datas).map(x => x.trade);
//检查并转换数据
trades = tradeUtils.prepareTrades(trades, pageVue.getVolType(), false);
window.sessionStorage.removeItem("pricing_pv_line");
if (trades) {
main.post("/pricing/GetTradesPvLine", { trades: trades }).done(function (resp) {
//resp.obj
window.sessionStorage.setItem("pricing_pv_line", JSON.stringify(resp));
window.open("/Statics/html/PvChart.html");
});
}
}
function showLifeLineChart(tradeVues) {
var selectVues = _.filter(_tradeVues, x => x.isSelected);
!tradeVues && (tradeVues = selectVues);
if (!tradeVues.length) {
return main.alert("请至少选择一笔交易");
}
var trades = _.flatMap(tradeVues, x => x.datas).map(x => x.trade);
//检查并转换数据
trades = tradeUtils.prepareTrades(trades, pageVue.getVolType(), false);
window.sessionStorage.removeItem("pricing_life_lines");
if (trades) {
main.post("/pricing/GetTradesLifePvLine", { trades: trades }).done(function (resp) {
//resp.obj
window.sessionStorage.setItem("pricing_life_lines", JSON.stringify(resp));
window.open("/Statics/html/PvLifeChart.html");
});
}
}
//显示Greeks变化曲线
function showGreeksChart(tradeVues) {
var selectVues = _.filter(_tradeVues, x => x.isSelected);
!tradeVues && (tradeVues = selectVues);
if (!tradeVues.length) {
return main.alert("请至少选择一笔交易");
}
var trades = _.flatMap(tradeVues, x => x.datas).map(x => x.trade);
//检查并转换数据
trades = tradeUtils.prepareTrades(trades, pageVue.getVolType(), false);
window.sessionStorage.removeItem("pricing_greeks_line");
if (trades) {
main.post("/pricing/GetTradesGreeksForLifetime", { trades: trades }).done(function (resp) {
//resp.obj
window.sessionStorage.setItem("pricing_greeks_line", JSON.stringify(resp));
window.open("/Statics/html/GreeksChart.html");
});
}
}
//打开历史回测页面
function openHistoricalBacktest(tradeVues) {
layer.open({
type: 2, title: "报价管理-历史回测工具", shadeClose: false, shade: 0.4,
area: ['1200px', '560px'], content: "/pricing/HistoricalBacktest?isLayer=true"
});
}
//设置观察数据
function setObservation(observationNum, observationUnit, observationHolidayType, observationDates, alignEnd, calcId, couponDayInterval) {
if (!calcId) return;
let _data = null, calcId2 = calcId.replace(/#.*$/, "");
_.each(_tradeVues, vue => {
return !(_data = _.find(vue.datas, data => data.trade.CalcId === calcId2));
});
_data && consVueTrade.methods.setObservation.apply(_data, arguments);
}
//对冲下单
function hedgingOrder() {
var comVues = _.filter(_tradeVues, x => x.isSelected);
if (comVues.length < 1) {
return main.alert('请至少选择一项!');
}
var datas = _.flatMap(comVues.map(x => x.datas));
var instType = datas[0].trade.UnderlyingInstrumentType;
if (!_.every(datas, x => x.trade.UnderlyingInstrumentType === instType)) {
return main.alert('所选项标的类型必须一致!');
}
var rd = _.reduce(datas, (acc, cur) => {
var code = cur.trade.UnderlyingCode;
var delta = acc[code];
acc[code] = (delta || 0) + (parseFloat(cur.calcResult.Delta) || 0);
return acc;
}, {});
var items = _.reduce(rd, (acc, value, key) => {
var index = acc.length / 2;
acc.push('<input type="hidden" name="Items[' + index + '].UnderlyingCode" value="' + key + '" />');
acc.push('<input type="hidden" name="Items[' + index + '].DeltaInLots" value="' + value + '" />');
return acc;
}, []);
items.push('<input type="hidden" name="InstType" value="' + instType + '" />');
$('#orderForm').html(items.join("")).submit();
}
//浏览器本地数据缓存
const localData = (new function () {
if (pageVue.IsImport) {
this.save = $.noop;
this.load = $.noop;
return;
}
this.save = function () {
var vueDatas = _tradeVues.map(x => new Object({
index: x.index,
structureType: x.structureType,
datas: x.datas.map(data => new Object({ trade: data.trade, viewState: data.viewState }))
}));
var data = {
index: _index,
VolType: pageVue.getVolType(),
SysDate: pageVue.SysDate,
vueDatas: vueDatas,
time: new Date().getTime()
};
var json = JSON.stringify(data);
localStorage.setItem("pricing-structure-" + pageVue.UserId, json);
};
this.load = function () {
//设置默认值
var saveKey = "pricing-structure-" + pageVue.UserId;
var storage = localStorage.getItem(saveKey);
if (!storage) return;
var data = JSON.parse(storage);
if (pageVue.SysDate !== data.SysDate ||
new Date().getHours > 18 && new Date(data.time).getHours() < 18) {
//需要清空缓存
localStorage.removeItem(saveKey);
}
else {
_index = data.index;
pageVue.setVolType(data.VolType);
_.each(data.vueDatas, function (x) {
x.fromLocal = true;
var vue = createVue(x.index, x);
_tradeVues.push(vue);
});
}
};
}());
//持久化定价数据
$(window).on('beforeunload', localData.save);
$(localData.load);
return {
clear: clear,
remove: remove,
addTrade: addTrade,
copyItem: copyItem,
combine: combine,
changeVolType: changeVolType,
saveTrades: saveTrades,
saveGroupTrades: saveGroupTrades,
calcPrice: calcPrice,
showPayoffLineChart: showPayoffLineChart,
showPvChart: showPvChart,
showGreeksChart: showGreeksChart,
showLifeLineChart: showLifeLineChart,
openHistoricalBacktest: openHistoricalBacktest,
getTradeVues(onlySelected) {
return onlySelected ? _tradeVues.filter(x => x.isSelected) : _tradeVues;
},
getTradeVue(index) { return _tradeVues[index || 0]; },
saveLocalData: localData.save,
setOption: addTrades, //用于和老版兼容
setObservation: setObservation,
uncouple: uncouple,
hedgingOrder: hedgingOrder,
onMountd(vue) {
_tradeVues.length && $('#pricing-items').parent().floatingScroll();
},
swap(oldIndex, newIndex) {
if (oldIndex === newIndex) return;
let vue = _tradeVues[oldIndex];
_tradeVues.splice(oldIndex, 1);
_tradeVues.splice(newIndex, 0, vue);
},
//新增模板
addTemplate(tplItems) {
tplItems.forEach(x => {
x.datas.forEach(d => {
d.viewState = _.cloneDeep(tradeFieldMgr.defaultData.viewState);
d.viewState.initFlag = 'template';
});
_index += 1;
var vue = createVue(_index, x);
_tradeVues.unshift(vue);
});
}
};
}());
//浮窗定价组件
const floatVue = (function () {
var _tradeVue;
//关闭浮窗
function hide() {
if (_tradeVue) {
_tradeVue.remove();
_tradeVue = null;
}
$('#floatModal').modal('hide');
$(document.body).removeClass('has-float');
if (pageVue.IsImport) {
layer.closeMe();
}
}
//显示浮窗index, trade, viewState
function show(baseVue, forScreenshot) {
_tradeVue && _tradeVue.remove();
_tradeVue = createVue(baseVue.index, baseVue, true);
$(document.body).toggleClass('has-float', !forScreenshot);
$('#floatModal').modal('show');
}
function screenshot() {
screenshoter.execute(_tradeVue);
}
return {
show: show,
hide: hide,
calcPrice() {
_tradeVue && pricingVue.calcPrice([_tradeVue]);
},
saveTrade() {
_tradeVue && _tradeVue.saveTrade();
},
screenshot: screenshot,
getVue() { return _tradeVue; }
};
}());
//dom ready function
$(function () {
tradeSaver.init();
groupVue.init();
//解决上层popover不能编辑的问题
$('#floatModal').on('shown.bs.modal', function () {
$(document).off('focusin.modal');
});
$(".search-label").addClass("formlabel");
$(".formlabel").addClass("search-label");
var sortable = Sortable.create(document.getElementById('pricing-items'), {
handle: '.pricing-index-drag',
onEnd: function (evt) {
pricingVue.swap(evt.oldIndex, evt.newIndex);
},
});
if (pageVue.IsImport) {
let trade = _.cloneDeep(pageVue.Trade);
pricingVue.addTrade(trade);
setTimeout(function () {//交易详情页-定价增强价格不显示问题
if (trade.TradeType == "亚式期权" && trade.StrikeType != "Floating" && trade.PayoffType == 'EnhancedArithmeticAverage') {
$("#EnhancedPriceTitle").show();
}
}, 500);
}
//#OTC-2651
$('#floatModal>.modal-dialog>.modal-content>.modal-body').on('scroll',
_.debounce(function () { $(this).find('input.hasDatepicker').blur().datepicker('hide'); }, 500, { 'leading': true, 'trailing': false }));
});
//用于和老版兼容
window.vue = pricingVue;
//兼容定价计算页面观察日设置
var getObservationDatesSetting = pricingVue.setObservation;
//连离类型:障碍(Discrete),二元(MonitorType,美式)
//补偿类型:障碍(RebateType),二元(RebateType,美式)
//定价模板
var templateVue = (function () {
if (pageVue.IsImport) return;
var debounceSearch;
return new Vue({
el: '#modalTemplate',
data: {
saveMode: true,
saveData: {
name: '',
id: 0,
_override: true,
_CommonTemplate: false
},
listData: [],
searchText: ''
},
mounted() {
this.refreshList();
debounceSearch = _.debounce(this.searchInner, 500);
},
methods: {
showSave() {
let selVues = pricingVue.getTradeVues(true);
if (!selVues.length) {
return main.alert('请勾选要保存的定价数据');
}
this.saveMode = true;
this.saveData.name = '';
this.saveData.json = '';
$('#modalTemplate').modal('show');
},
showList() {
this.saveMode = false;
$('#modalTemplate').modal('show');
},
saveTemplate() {
let selVues = pricingVue.getTradeVues(true);
if (!selVues.length) {
return main.alert('没有可保存的定价数据');
}
let name = (this.saveData.name).trim();
if (!name) {
return main.alert('请填写模板名称');
}
let self = this;
let vueDatas = selVues.map(x => new Object({
structureType: x.structureType,
datas: x.datas.map(data => new Object({ trade: data.trade }))
}));
let dataJson = JSON.stringify(vueDatas);
main.post('/pricing/AjaxSaveTemplate/v2', { name, dataJson, _override: this.saveData._override, _CommonTemplate: this.saveData._CommonTemplate }).done(function () {
$('#modalTemplate').modal('hide');
self.refreshList();
self.searchInner();
});
},
removeTemplate(sysUserConfigId) {
let $item = $(event.target).closest('.yt-template-item');
if (!$item) {
return main.alert('系统错误,没有找到所选项');
}
let self = this;
let index = $item.prevAll().length;
let names = [$item.children('a').text()];
main.confirmPost('确认要删除所选项"' + names[0] + '"吗?', '/pricing/AjaxRemoveTemplate', { sysUserConfigId }).done(function () {
self.listData.splice(index, 1);
});
},
loadTemplate() {
let name = $(event.target).text();
let TemplateType = $(event.target).next().text();
function __do() {
pricingVue.clear(true);
main.post('/pricing/ajaxGetTemplate/v2', { name, TemplateType }).done(function (resp) {
let items = JSON.parse(resp.obj);
pricingVue.addTemplate(items);
$('#modalTemplate').modal('hide');
});
}
if (pricingVue.getTradeVues().length) {
main.confirm("加载自定义模板将清空页面现有交易,是否继续?", __do);
} else {
__do();
}
},
refreshList() {
let self = this;
this.searchText = '';
main.post('/pricing/AjaxGetTemplateList').done(function (resp) {
self.listData = resp.obj.map(x => new Object({ id: x.id, name: x.ConfigName, show: true, UserId: x.UserId, ConfigType: x.ConfigType }));
});
},
searchInner() {
console.log('searchInner');
let text = this.searchText ? this.searchText.toLowerCase() : '';
this.listData.forEach(x => {
x.show = !text || x.name.toLowerCase().indexOf(text) >= 0;
});
},
searchList(action) {
if (action === 'reset') {
debounceSearch.cancel();
this.searchText = '';
this.searchInner();
} else {
debounceSearch();
}
}
}
});
}());
const customNumberFormat = { precision: 6, negative: true, };
const customNumberPercentFormat = { precision: 6, negative: true, append: '%' };
var groupVue = new Vue({
el: '#modalGroupTradeSave',
data: {
viewState: pageVue.viewState,
...consVueTrade.data(),
trade: ylotc.trade,
options: ylotc.options,
structureTypes: pageObj.structureTypes,
PropertyMap: pageObj.PropertyMap,
},
computed: { ...consVueTrade.computed },
methods: {
...consVueTrade.methods,
closeModal: function () {
$('#modalGroupTradeSave').modal('hide');
$(".tag-context .tag-item").remove();
},
saveGroupTrade: function () {
if (!_trades) return;
_trades.forEach(x => {
x.AssetId = this.trade.AssetId;
x.AssetBookName = this.trade.AssetBookName;
x.TraderId = this.trade.TraderId;
x.TraderName = this.trade.TraderName;
x.TradeNumber = this.trade.TradeNumber;
x.SalesCommission = this.trade.salesCommission;
x.ClientId = this.trade.ClientId;
x.ClientName = this.trade.ClientName;
if (x.TradePremium) {
x.MetaDic["交易溢价"] = x.TradePremium;
}
x.MetaDic["交易场所"] = this.trade.TradingPlace;
x.MetaDic["清算机构"] = this.trade.ClearingAgency;
x.MetaDic["主协议编号"] = this.trade.MainProtocolCode;
x.MetaDic["补充协议编号"] = this.trade.SupProtocolCode;
x.MetaDic["中央对手方清算"] = $("#selIsCentralClearing").val();
x.MetaDic["中央清算平台"] = $("#selCentralClearingPaltform").val();
x.MetaDic["ExchangeRate"] = $("#selExchangeRate").val();
x.MetaDic["交易平台"] = $("#selTradingPaltform").val();
x.TradeType === '现金流交易' && tradeUtils.resetCashFlow(x);
});
this.trade.Tags = getSelectTags();
if (this.trade.StructureType == "气囊结构") {
this.trade.trade_airbag.KIParticipationRate = 1;
}
this.setExtendInfo();
main.post("/pricing/AjaxSaveGroupTrade", { trade: this.trade, subTrades: _trades }).done(function (resp) {
if (pageVue.IsImport) {
let url = "#/trade/tradeview?abstract=1&enid=" + resp.obj[0].EncryptId;
layer.closeMe(url);//必须以#开头
} else {
floatVue.hide();
$('#modalTradeSave').modal('hide');
//showTradeView(resp.obj);
_.each(_tradeVues, x => x.remove(true));
}
$(".tag-context .tag-item").remove();
});
},
addNewProperty: function () {
this.PropertyMap[this.trade.StructureType].push({ isNew: true, ColumnName: "", ColumnDefaultValue: "", ColumnType: 0 });//0:文本
},
deleteProperty: function (index) {
this.PropertyMap[this.trade.StructureType].splice(index, 1);
},
setExtendInfo: function () {
var propertyList = [];
this.PropertyMap[this.trade.StructureType].forEach((item, index) => {
var note = { name: item.name || item.ColumnName, value: item.ColumnType !== 4 || (item.value || item.ColumnDefaultValue + "").indexOf("%") > 0 ? ((item.value || item.ColumnDefaultValue) + "") : (((item.value || item.ColumnDefaultValue) * 100) + "%") };
if (note.name) {
propertyList.push(note);
}
});
this.trade.ExtendInfo = this.trade.StructureType == "气囊结构" ? null : JSON.stringify(propertyList);
return this.trade.ExtendInfo;
},
changeStrucTureType: function () {
if (groupVue.trade.TradeType == "气囊结构") {
groupVue.trade.trade_airbag.KIParticipationRate = 1;
}
else {
groupVue.trade.OptionType = null;
groupVue.trade.Strike = null;
}
},
changeBuySell: function () {
groupVue.trade.TradePrice *= -1;
groupVue.trade.TradeSinglePrice *= -1;
groupVue.trade.PremiumRate *= -1;
},
changeIsUsePremiumRate: function () {
if (groupVue.trade.IsUsePremiumRate) {
groupVue.changeStockEqvNotional();
}
else {
groupVue.changeTradeAmount();
}
},
changeStockEqvNotional: function () {
var notional = Math.abs(groupVue.trade.StockEqvNotional / groupVue.trade.SpotPrice);
groupVue.trade.Notional = pricingFormat.notional(notional);
groupVue.trade.TradeAmount = pricingFormat.notional(notional / groupVue.viewState.variety.CountRatio);
groupVue.trade.TradeSinglePrice = pricingFormat.tradeSinglePrice(groupVue.trade.TradePrice / groupVue.trade.Notional);
groupVue.trade.PremiumRate = pricingFormat.premiumRate(groupVue.trade.TradePrice / groupVue.trade.StockEqvNotional);
},
changeTradeAmount: function () {
var notional = groupVue.trade.TradeAmount * groupVue.viewState.variety.CountRatio;
groupVue.trade.Notional = pricingFormat.notional(notional);
groupVue.trade.StockEqvNotional = pricingFormat.stockEqvNotional(Math.abs(notional * groupVue.trade.SpotPrice));
groupVue.trade.TradeSinglePrice = pricingFormat.tradeSinglePrice(groupVue.trade.TradePrice / groupVue.trade.Notional);
groupVue.trade.PremiumRate = pricingFormat.premiumRate(groupVue.trade.TradePrice / groupVue.trade.StockEqvNotional);
},
init: function () {
_setAutocomplete('GroupAssetId', ylotc.assetunits, null, function (data) {
groupVue.trade.AssetId = data.id;
groupVue.trade.AssetBookName = data.Name;
});
var traders = $.grep(ylotc.traders, function (e) { return e.Name == pageVue.Trade.TraderName; });
let trader = pageVue.Trade.TraderId > 0 ? ylotc.traders.find(x => x.id === pageVue.Trade.TraderId) : null;
if (!trader) {
trader = { Name: "", id: 0 }
}
_setAutocomplete('GroupTraderId', ylotc.traders, { Name: trader.Name, id: trader.id }, function (data) {
groupVue.trade.TraderId = data.id;
groupVue.trade.TraderName = data.Name;
});
var groupClientInitData = null;
if (this.trade.ClientId > 0) {
groupClientInitData = { id: this.trade.ClientId, Name: "" };
var client = ylotc.clients.find(y => y.id === this.trade.ClientId);
groupClientInitData.Name = client.Name;
$("#selIsCentralClearing").val(client.IsCentralClearing);
$("#selCentralClearingPaltform").val(client.CentralClearingPaltform);
$("#selTradingPaltform").val(client.TradingPaltform);
}
_setAutocomplete('GroupClientId', ylotc.clients, groupClientInitData, function (data) {
pageVue.SecuritiesEnvironment ? _getMainProtocolCode : null;
groupVue.trade.ClientId = data.id;
groupVue.trade.ClientName = data.Name;
});
},
changeOption: function () {
this.PropertyMap[this.trade.StructureType].forEach(d => {
if (d.ColumnName != undefined) {
d.name = d.ColumnName;
}
if (d.ColumnDefaultValue != undefined) {
d.value = d.ColumnDefaultValue;
}
});
}
},
components: {
'vue-niceselect': FastVue.vueNiceSelect(),
'vue-client': vueClient(),
'vue-variety': vueVariety(),
'vue-margintemplatename': vueMarginTemplateName(),
'vue-tradetype': vueTradeType(),
'vue-underlying': vueUnderlying(),
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
'vue-daycount': vueDayCount(),
},
});
var extendVue = new Vue({
el: "#tradeSave_ExtendInfo",
data: {
ExtendMap: pageObj.ExtendMap,
ExtendInfos: "",
},
methods: {
addNewProperty: function () {
var map = this.ExtendMap[this.ExtendInfos];
map.push({ isNew: true, ColumnName: "", ColumnDefaultValue: "", ColumnType: 0 });//0:文本
},
deleteProperty: function (index) {
var map = this.ExtendMap[this.ExtendInfos];
map.splice(index, 1);
},
changeOption: function (index) {
var map = this.ExtendMap[this.ExtendInfos];
map.forEach(d => {
if (d.ColumnName != undefined) {
d.name = d.ColumnName;
}
if (d.ColumnDefaultValue != undefined) {
d.value = d.ColumnDefaultValue;
}
});
},
setExtendInfo: function (trade) {
var propertyList = [];
var key = this.ExtendInfos;
if (key) {
var map = this.ExtendMap;
if (map[key]) {
map[key].forEach((item, index) => {
var note = { name: item.name || item.ColumnName, value: item.ColumnType !== 4 || (item.value || item.ColumnDefaultValue + "").indexOf("%") > 0 ? ((item.value || item.ColumnDefaultValue) + "") : (((item.value || item.ColumnDefaultValue) * 100) + "%") };
if (note.name) {
propertyList.push(note);
}
});
}
}
trade.ExtendInfo = propertyList.length === 0 ? null : JSON.stringify(propertyList);
if (trade.ExtendInfo) {
trade.MetaDic["自定义要素模板"] = key;
} else {
trade.MetaDic["自定义要素模板"] = "";
}
return trade.ExtendInfo;
},
},
components: {
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
}
});
var extendVue2 = new Vue({
el: "#tradeSave_ExtendInfo2",
data: {
ExtendMap: pageObj.ExtendMap,
ExtendInfos: "",
},
methods: {
addNewProperty: function () {
var map = this.ExtendMap[this.ExtendInfos];
map.push({ isNew: true, ColumnName: "", ColumnDefaultValue: "", ColumnType: 0 });//0:文本
},
deleteProperty: function (index) {
var map = this.ExtendMap[this.ExtendInfos];
map.splice(index, 1);
},
changeOption: function (index) {
var map = this.ExtendMap[this.ExtendInfos];
map.forEach(d => {
if (d.ColumnName != undefined) {
d.name = d.ColumnName;
}
if (d.ColumnDefaultValue != undefined) {
d.value = d.ColumnDefaultValue;
}
});
},
setExtendInfo: function (trade) {
var propertyList = [];
var key = this.ExtendInfos;
if (key) {
var map = this.ExtendMap;
if (map[key]) {
map[key].forEach((item, index) => {
var note = { name: item.name || item.ColumnName, value: item.ColumnType !== 4 || (item.value || item.ColumnDefaultValue + "").indexOf("%") > 0 ? ((item.value || item.ColumnDefaultValue) + "") : (((item.value || item.ColumnDefaultValue) * 100) + "%") };
if (note.name) {
propertyList.push(note);
}
});
}
}
trade.ExtendInfo = propertyList.length === 0 ? null : JSON.stringify(propertyList);
if (trade.ExtendInfo) {
trade.MetaDic["自定义要素模板"] = key;
} else {
trade.MetaDic["自定义要素模板"] = "";
}
return trade.ExtendInfo;
},
},
components: {
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
}
});