var abType = ["报价Ask", "报价Bid"]; const consVarieties = ylotc.varieties; var skey = $("#mainlayoutuser").html().trim() + "t_table"; var storedata = JSON.parse(localStorage.getItem(skey)); var default_Model = { OtherInfo: "", OtherInfoObj: {}, WorkDayHTML: "", SelectModel: "波动率", Count: 1, InputVolChange: true, InputChange: false, QuotationModes: [{ Mode: "波动率", value: 0 }, { Mode: "百分比", value: 1 }, { Mode: "绝对价格", value: 2 }], TQuoteRecords: { LatestPrice: 0, quotaList: [{ Strike: 0 }] }, ExerciseDate: "", PricingModel: "BSM", ExerciseMode: "European", QuotationMode: "波动率", DefaultVol: "0.3", ZhiXingJianGe: "", ZhiXingShuLiang: 11, CanSaveLocalCache: false }; if (storedata) { Underlying = storedata["Underlying"]; expireList = storedata["expireList"]; orderStrikes = storedata["orderStrikes"]; default_Model = storedata["Model"]; } const consUnderlyingFlag = (function () { let unSelFlag = tradeHelper.UnderlyingSelectFlag; return unSelFlag.UseForTrading | unSelFlag.IncludeMatured | unSelFlag.UsePinYinFilter; }()); var autoVariety, autoUnderlying, salesCommissionCtrl; function __init(vue) { //标的品种 autoVariety = FastVue.autocomplete(document.getElementById('VarietyId'), { lookup: consVarieties, nameField: 'Name', valueField: 'id', searchField: ['Name', 'Code', 'PinYin'], onSelect: function (data) { vue.changeVariety(data, 'select'); } }); //标的资产 autoUnderlying = tradeHelper.UnderlyingAutoComplete('UnderlyingCode').setFlag(consUnderlyingFlag); autoUnderlying.onSelect(vue.changeunderlying); //标的控件初始化 if (vue.Underlying.UnderlyingName) { autoUnderlying.selectByCode(vue.Underlying.UnderlyingName); } else { autoUnderlying.selectFirst(); } } var vue = new Vue({ el: "#listdiv", data: { Variety: tradeHelper.getEmptyVariety(), Underlying: { ...tradeHelper.getEmptyUnderlying(), Price: 0 }, expireList: [{ Expire: "", IsNew: false, Vol: [{ Strike: "", VolValue: "" }] }], orderStrikes: [{ Vol: "", Strike: "", IsNew: false }], Model: default_Model, on_underlyingGetById: false }, mounted: function () { //设置默认到期日 var thisObj = this; $(window).on('beforeunload', function () { //设置local if (thisObj.CanSaveLocalCache) { var pagedata = JSON.stringify(vue.$data); localStorage.setItem(skey, pagedata); } }); __init(thisObj); main.setTradeDatePicker(); thisObj.setUnderlyingInstrumentType(); }, computed: { attachesFilter: function (d) { var data = $.map(value, function (a, t) { if (a.masterId == oid) return true; }); return data; } }, updated: function () { $(".chosen-select").trigger("chosen:updated"); this.handlechange(); if (this.Model.InputChange) { this.calcTTable(); this.Model.InputChange = false; } }, filters: { SetVolTypeName: function (rawName) { switch (rawName) { case "交易": return "交易Mid"; case "报价Bid": return "交易Bid"; case "报价Ask": return "交易Ask"; default: return rawName; } }, toInt: function (d) { return d.toFixed(0); }, toPercent: function (d) { return (d * 100).toFixed(1) + "%"; }, CallPv: function (tt, iindex, index) { try { return tt[iindex].OVR[index].看涨.Pv.toFixed(2); } catch (e) { // } }, percentVol: function (data) { return numeral(data * 100).format("0.00"); } }, methods: { setTQuoteRecordsProxy: function (TQuoteRecords) { var thisObj = this; var list = TQuoteRecords.quotaList; if (list && list.length) { const proxyProps = ["CallBidVol", "CallAskVol", "PutBidVol", "PutAskVol"]; list.forEach(function (obj) { var propDefines = {}; proxyProps.map(function (pname) { obj[pname + 'Proxy'] = numeral(obj[pname] * 100).format("0.00"); }); }); } return TQuoteRecords; }, FormatProxyValue: function (event) { var vol = $(event.target).val(); $(event.target).val(numeral(vol).format("0.00")); }, handlechange() { var thisObj = this; if (this.Model.SelectModel == "波动率") { $(".datatwo").css('display', 'none'); $(".datathree").css('display', 'none'); $(".dataone").css('display', 'block'); } else if (this.Model.SelectModel == "百分比") { $(".datatwo").css('display', 'block') $(".dataone").css('display', 'none'); $(".datathree").css('display', 'none'); } else if (this.Model.SelectModel == "绝对价格") { $(".datatwo").css('display', 'none'); $(".dataone").css('display', 'none'); $(".datathree").css('display', 'block'); } }, percentVol: function (data) { return numeral(data * 100).format("0.00"); }, setUnderlyingInstrumentType: function () { var Underlying = $("#selUnderlyingInstrumentType").val(); autoUnderlying.selectFirst({ InstrumentTypes: Underlying }); }, changeVariety: function (variety, flag) { if (flag === 'select') { if (this.Model.VarietyId === variety.id) return; //this.Model.UnderlyingInstrumentType = variety.InstrumentType; autoUnderlying.setVarietyId(variety.id); //Object.assign(this.Variety.underlying, tradeHelper.getEmptyUnderlying(variety.id)); autoUnderlying.selectFirst(variety.id); } else { autoVariety.setData(variety); } Object.assign(this.Variety, variety || tradeHelper.getEmptyVariety()); }, changeunderlying: function (data) { var thisObj = this; if (thisObj.on_underlyingGetById) return; thisObj.Underlying.id = data.id; if (thisObj.Underlying.id) { thisObj.on_underlyingGetById = true; thisObj.Underlying.UnderlyingCode = data.Code; thisObj.Underlying.UnderlyingInstrumentType = data.InstrumentType; thisObj.Underlying.UnderlyingTypeId = data.VarietyId; thisObj.Underlying.ContractSize = data.ContractSize; thisObj.Underlying.CountRatio = data.CountRatio; thisObj.Underlying.Price = main.toNumber(data.Price); thisObj.Model.ExerciseDate = main.toDate(data.ExerciseDate); thisObj.Model.ZhiXingJianGe = main.toInt(thisObj.Underlying.Price * 0.05); if (thisObj.Model.ZhiXingJianGe <= 0) thisObj.Model.ZhiXingJianGe = 1; thisObj.changeVariety(data.VarietyId ? ylotc.varieties.find(x => x.id === data.VarietyId) : null); thisObj.Model.InputChange = true; main.setTradeDatePicker(); thisObj.on_underlyingGetById = false; main.post("/Pricing/AjaxGetExerciseDate", { underlyingMaturityDate: data.MaturityDate, tradeDate: thisObj.Model.TradeDate }, { async: false }).done(function (res) { thisObj.Model.ExerciseDate = new moment(res.obj.ExerciseDate).format("YYYY-MM-DD"); }); } }, changeVolMode: function () { var thisObj = this; }, loadVols: function () { //读取波动率 this.Model.InputChange = true; }, changeJianGe: function () { //波动率模式改变 this.Model.InputChange = true; this.Model.ZhiXingJianGe = main.toInt(Math.abs(this.Model.ZhiXingJianGe)); }, checkPayOffType: function () { //行权方式改变 this.Model.InputChange = true; }, changeZhiXingShuLiang: function () { //执行数量改变 this.Model.InputChange = true; }, changeUnderlyingPrice: function () { //执行数量改变 if (main.toNumberExcludingNaN(this.Underlying.Price) == "0.00") { $("#UnderlyingPrice").focus(); main.message("请输入正确的标的价格"); return; } var thisObj = this; setTimeout(function () { thisObj.Model.InputChange = true; }, 10); }, exerciseDateChange: function () { //到期日改变 this.Model.ExerciseDate = $("#Trade_ExerciseDate").val(); if (!this.Model.ExerciseDate) return; var systsemdate = $("#mainsystemvaluedate").html(); var checkMaturityDate = this.Underlying.MaturityDate; if (this.Model.ExerciseDate > checkMaturityDate) { main.message("期权到期日不能大于标的到期日:{0}".template(this.Underlying.MaturityDate)); this.Model.ExerciseDate = null; } if (this.Model.ExerciseDate < systsemdate) { main.message("期权到期日不能小于系统日期"); this.Model.ExerciseDate = null; } this.Model.InputChange = true; }, calcVolTTable: function () { //计算价格 var thisObj = this; if (!thisObj.Model.ExerciseDate) { main.message("请输入期权到期日"); return; } if (!thisObj.Underlying.id) { main.message("请输入标的代码"); return; } //有改动 if (thisObj.Underlying.Price <= 0) { main.message("请输入正数标的价格"); return; } //console.log(thisObj.Underlying.Price); thisObj.FormatVols();//同步Poxy字段和实际字段的值 var reqObj = { Records: thisObj.Model.TQuoteRecords.quotaList, SpotPrice: thisObj.Underlying.Price, UnderlyingCode: thisObj.Underlying.UnderlyingCode, MaturityDate: thisObj.Model.ExerciseDate }; main.post("/volatility/TQuoteWithCustomizedVol", reqObj).done(function (res) { thisObj.Model.TQuoteRecords = thisObj.setTQuoteRecordsProxy(res.obj); thisObj.Model.InputVolChange = false; }); }, FormatVols: function () { var thisObj = this; $.each(thisObj.Model.TQuoteRecords.quotaList, function (i, obj) { obj.CallBidVol = obj.CallBidVolProxy / 100; obj.CallAskVol = obj.CallAskVolProxy / 100; obj.PutBidVol = obj.PutBidVolProxy / 100; obj.PutAskVol = obj.PutAskVolProxy / 100; }); }, FixCenterNumber: function (strike) { var thisObj = this; if (strike == thisObj.Model.TQuoteRecords.LatestPrice) { return "{0}".template(strike); } return strike; }, calcTTable: function () { //读取波动率 其实时间在服务端,永远为当前日期 //检查输入 var thisObj = this; thisObj.CanSaveLocalCache = false; if (!thisObj.Model.ExerciseDate) { main.message("请输入期权到期日"); return; } if (!thisObj.Underlying.id) { main.message("请输入标的代码"); return; } if (thisObj.Underlying.Price <= 0) { main.message("请输入正数标的价格"); return; } thisObj.Model.InputChange = false; var reqObj = { strikeCount: thisObj.Model.ZhiXingShuLiang, strikeInterval: thisObj.Model.ZhiXingJianGe, spotPrice: thisObj.Underlying.Price, underlyingCode: thisObj.Underlying.UnderlyingCode, maturityDate: thisObj.Model.ExerciseDate }; main.post("/volatility/TQuote", reqObj).done(function (res) { if (res.obj.StatusCode != 0) { main.message(res.obj.Info); } else { //TQuote thisObj.Model.TQuoteRecords = thisObj.setTQuoteRecordsProxy(res.obj); thisObj.Model.Count = res.obj.quotaList == undefined ? 0 : res.obj.quotaList.length; thisObj.Model.OtherInfo = res.obj.OtherInfo; thisObj.getWorkDayDesc(); thisObj.CanSaveLocalCache = true; } }); }, getWorkDayDesc: function () { var thisObj = this; var from = moment().format("YYYY-MM-DD"); var to = main.toDate(thisObj.Model.ExerciseDate); var underlying = thisObj.Underlying; main.post("/calendar/DaysInPeriod", { from: from, to: to, varietyid: underlying.UnderlyingTypeId }).done(function (res) { var bidtunning = 0, asktunning = 0; bidtunning += res.obj; asktunning += res.obj; thisObj.Model.WorkDayHTML = "期权交易日天数: {0}".template(res.obj, bidtunning, asktunning); if (bidtunning != res.obj || asktunning != res.obj) { thisObj.Model.WorkDayHTML += "
买入期权交易调整后交易日天数:{1}
卖出期权交易调整后交易日天数:{2}
".template(res.obj, bidtunning, asktunning); } }); }, sortVolTypes: function () { var thisObj = this; //VolTypes 显示排序补丁 var typeSort = ["报价Bid", "交易", "报价Ask"]; thisObj.VolTypes.sort(function (a, b) { var aindex = typeSort.indexOf(a.VolModelName); var bindex = typeSort.indexOf(b.VolModelName); return aindex - bindex; }); }, getCTPdata: function (unid, vueObj) { var thisObj = this; main.post("/pricing/AjaxGetUnderlyingPrice", { underlyingCode: thisObj.Underlying.UnderlyingCode }).done(function (res) { if (typeof res.obj.price !== "undefined") { thisObj.Underlying.Price = main.toNumber(res.obj.price); thisObj.Model.InputChange = true; } else { thisObj.Underlying.Price = 0; } }); }, changeVolInput: function () { var thisObj = this; thisObj.FormatVols();//同步Poxy字段和实际字段的值 var $obj = $(event.srcElement); var thisData = $obj.val() / 100; var type = $obj.attr("recordtype"); var rindex = $obj.attr("recordindex"); thisObj.Model.TQuoteRecords.quotaList[rindex][type] = thisData; thisObj.Model.InputVolChange = true; }, getExpireDay: function (expire) { var mu = expire.substr(expire.length - 1, 1); var data = expire.substr(0, expire.length - 1); var drate = 1; switch (mu) { case "W": drate = 7; break; case "M": drate = 30; break; case "Y": drate = 365; break; } return data * drate; }, checkExpire: function (ex) { return /^\d+(W|Y|M|D)$/.test(ex); }, up: function (type) { var thisObj = this; thisObj.FormatVols();//同步Poxy字段和实际字段的值 thisObj.Model.InputVolChange = true; $.each(thisObj.Model.TQuoteRecords.quotaList, function (i, d) { d[type] = d[type] + 0.001; }); thisObj.setTQuoteRecordsProxy(thisObj.Model.TQuoteRecords); }, down: function (type) { var thisObj = this; thisObj.FormatVols();//同步Poxy字段和实际字段的值 thisObj.Model.InputVolChange = true; $.each(thisObj.Model.TQuoteRecords.quotaList, function (i, d) { d[type] = d[type] - 0.001; //d[type + 'Proxy'] = numeral(d[type] * 100).format("0.00"); }); thisObj.setTQuoteRecordsProxy(thisObj.Model.TQuoteRecords); }, PercentNumber: function (data) { return numeral(data).format("0,0.00%"); }, clearChange: function () { // window.location.href = window.location.href; var thisObj = this; thisObj.changeunderlying(); }, closePage: function (cid) { parent.layer.closeAll(); }, showAlink: function (obj) { var thisObj = this; if (this.Model.SelectModel == "波动率") { $(obj).find("a").css("display", "inline"); } }, hideAlink: function (obj) { $(obj).find("a").css("display", "none"); } } });