Files
zszq-trs/YLErpWeb/wwwroot/Scripts/app/pricing/t_table.js
T
2024-05-09 14:06:26 +08:00

408 lines
17 KiB
JavaScript

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 "<span style='background:green'>{0}</span>".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 += "</br>买入期权交易调整后交易日天数:{1}</br>卖出期权交易调整后交易日天数:{2}</br>".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");
}
}
});