const consVarieties = ylotc.varieties; const pricingFormat = otcformat.trading; const consUnderlyingFlag = (function () { let unSelFlag = tradeHelper.UnderlyingSelectFlag; return unSelFlag.UseForTrading | unSelFlag.IncludeMatured | unSelFlag.UsePinYinFilter; }()); var autoVariety, autoUnderlying; 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); //组合标的控件 synthenticPriceCtrl.init({ getSynthetic(input) { return vue.viewState.synthetic; }, setSynthetic(input, synthetic) { vue.viewState.synthetic = synthetic; vue.Model.SpotPrice = synthetic.Price; } }); //标的控件初始化 if (vue.Model.UnderlyingCode) { autoUnderlying.selectByCode(vue.Model.UnderlyingCode); } else { autoUnderlying.selectFirst(); } } var vue = new Vue({ el: "#listdiv", data: { Model: Model, IsMoneynessOption: false }, mounted: function () { var thisObj = this; //设置默认值补丁 thisObj.Model.ExerciseMode = "European"; thisObj.Model.TradeDate = moment(thisObj.Model.TradeDate).format("YYYY-MM-DD"); thisObj.Model.UnderlyingInstrumentType = "CommodityFutures"; $("#selUnderlyingInstrumentType").val("CommodityFutures"); __init(thisObj) thisObj.setUnderlyingInstrumentType(); }, computed: { inputFormatStrike: function () { let fmt = {}; if (this.Model.UnderlyingInstrumentType === 'Stock') { fmt.append = '%'; fmt.negative = false; fmt.precision = pricingFormat.premiumRateP.precision; } else { fmt.append = ''; fmt.negative = true; fmt.precision = pricingFormat.umprice.precision; } return fmt; } }, filters: { ShowUnit: function (m) { return m && m.Variety ? m.Variety.QuoteUnitSingle : ""; } }, methods: { ExerciseDateChange: function (data) { var thisObj = this; thisObj.Model.ExerciseDate = data; }, ExerciseDateChange2: function (data) { var thisObj = this; thisObj.Model.ExerciseDate2 = data; }, TradeDateChange: function (data) { var thisObj = this; thisObj.Model.TradeDate = data; }, changeUnderlyingPrice: function () { this.Model.UnderlyingPriceType = "User"; if (this.Model.UnderlyingInstrumentType !== "Stock") { this.Model.StockEqvNotional = otcformat.trading.StockEqvNotional(this.Model.Notional * this.Model.Price); this.Model.Price = otcformat.trading.umprice(this.Model.Price); } else { this.Model.Notional = otcformat.trading.notional(this.Model.StockEqvNotional / this.Model.Price); var CountRatio = this.Model.Variety.CountRatio || 1; this.Model.TradeAmount = otcformat.trading.notional(this.Model.Notional / CountRatio); } }, refreshUnderlyingPrice: function () { var thisObj = this; main.post("/underlying_manager/underlyingGetById", { id: thisObj.Model.UnderlyingId }).done(function (res) { thisObj.Model.Price = otcformat.trading.umprice(res.underlying_manager.Price); if (thisObj.Model.UnderlyingInstrumentType !== "Stock") { thisObj.Model.StockEqvNotional = otcformat.trading.StockEqvNotional(thisObj.Model.Notional * thisObj.Model.Price); } else { thisObj.Model.Notional = otcformat.trading.notional(thisObj.Model.StockEqvNotional / thisObj.Model.Price); var CountRatio = thisObj.Model.Variety.CountRatio || 1; thisObj.Model.TradeAmount = otcformat.trading.notional(thisObj.Model.Notional / CountRatio); } thisObj.$forceUpdate(); }); }, setUnderlyingInstrumentType: function () { var Underlying = $("#selUnderlyingInstrumentType").val(); autoUnderlying.selectFirst({ InstrumentTypes: Underlying }); }, changeunderlying: function (data) { var thisObj = this; thisObj.Model.VarietyId = data.VarietyId; thisObj.Model.UnderlyingId = data.id; thisObj.Model.UnderlyingCode = data.Code; thisObj.Model.Variety = data; thisObj.Model.Price = data.Price; if (!data.Code) return; thisObj.Model.UnderlyingInstrumentType = data.InstrumentType; main.post("/Pricing/AjaxGetExerciseDate", { underlyingMaturityDate: data.MaturityDate, tradeDate: thisObj.Model.TradeDate }).done(function (res) { thisObj.Model.ExerciseDate = new moment(res.obj.ExerciseDate).format("YYYY-MM-DD"); }); $.each(thisObj.Model.trades, function (i, d) { d.MaturityDate = data.MaturityDate; d.UnderlyingPrice = data.Price; }); autoUnderlying.setVarietyId(data.VarietyId); thisObj.changeVariety(data.VarietyId ? ylotc.varieties.find(x => x.id === data.VarietyId) : null); thisObj.Model.Price = otcformat.trading.umprice(data.Price); main.setTradeDatePicker("", "#ModelTradeDate", thisObj.Model.TradeDate, thisObj.TradeDateChange); main.setTradeDatePicker("", "#ModelExerciseDate", thisObj.Model.ExerciseDate, thisObj.ExerciseDateChange); main.setTradeDatePicker("", "#ModelExerciseDate2", thisObj.Model.ExerciseDate, thisObj.ExerciseDateChange2); thisObj.IsMoneynessOption = thisObj.Model.UnderlyingInstrumentType === "Stock"; if (thisObj.IsMoneynessOption) { thisObj.Model.StockEqvNotional = 1e6; thisObj.changeStockEqvNotional(); } else { thisObj.changeAmount(); } }, setStrike: function (strikeType) { if (this.Model.Name === "Condor") { if (this.Model.Strike2 && this.Model.Strike3) { if (this.Model.Strike2 >= this.Model.Strike3) { if (strikeType === "Strike2") { main.message("执行价格2需要小于执行价格3"); this.Model.Strike2 = ""; } else if (strikeType === "Strike3") { main.message("执行价格3需要大于执行价格2"); this.Model.Strike3 = ""; } return; } var diff = this.Model.Strike3 - this.Model.Strike2; this.Model.Strike = this.Model.Strike2 - diff; this.Model.Strike4 = parseFloat(this.Model.Strike3) + diff; } } this.setStrike1(); }, setStrike1: function () { this.Model.Strike = otcformat.trading.umprice(this.Model.Strike); this.Model.Strike2 = otcformat.trading.umprice(this.Model.Strike2); this.Model.Strike3 = otcformat.trading.umprice(this.Model.Strike3); this.Model.Strike4 = otcformat.trading.umprice(this.Model.Strike4); }, submitstructure: function () { var thisObj = this; if (thisObj.checkTrades()) { thisObj.setModelTrades(); window.parent.vue.setOption(thisObj.Model.trades); window.parent.layer.closeAll(); } }, close: function () { window.parent.layer.closeAll(); }, checkTrades: function () { var thisObj = this; var pass = true; var checkModel = { Strike12: true, Strike12Empty: true, CheckExerciseDate: true }; switch (thisObj.Model.Name) { case "Butterfly": checkModel.Strike12 = false; checkModel.Strike12Empty = false; thisObj.Model.MidStrike = thisObj.Model.Price; if (!thisObj.Model.StrikeGap || !thisObj.Model.MidStrike) { main.message("执行价格间距必填!"); pass = false; } if (parseFloat(thisObj.Model.MidStrike) <= parseFloat(thisObj.Model.StrikeGap)) { main.message("标的价格必须大于行权价间隔!"); pass = false; //中间行权价 即 标的价格 } break; case "Condor": checkModel.Strike12 = false; checkModel.Strike12Empty = false; //验证行权价是否相同,从小到大排序,中间两个行权价允许相同,其他行权价不能相同 if (!thisObj.Model.Strike3 || !thisObj.Model.Strike4) { main.message("行权价3,4必需输入!"); pass = false; } var strikes = [thisObj.Model.Strike, thisObj.Model.Strike2, thisObj.Model.Strike3, thisObj.Model.Strike4]; strikes.sort(); if (strikes[0] == strikes[1] || strikes[3] == strikes[2]) { main.message("中间两个行权价允许相同,其他行权价不能相同!"); pass = false; } break; //case "Preplicating Underlying": case "Straddle": //跨式组合的 执行价格 永远和标的价格一致 if (thisObj.Model.UnderlyingInstrumentType === "Stock") { thisObj.Model.Strike = 100; } else { thisObj.Model.Strike = thisObj.Model.Price; } checkModel.Strike12 = false; checkModel.Strike12Empty = false; if (!thisObj.Model.Strike) { main.message("行权价必需输入!"); pass = false; } break; case "Ratio Spread": break; case "Calender Spread"://ExerciseDate2 checkModel.Strike12 = false; checkModel.Strike12Empty = false; if (!thisObj.Model.ExerciseDate || !thisObj.Model.ExerciseDate2) { main.message("两个到期日必需输入!"); pass = false; } if ((new Date(thisObj.Model.ExerciseDate)).getTime() <= (new Date(thisObj.Model.ExerciseDate2)).getTime()) { main.message("到期日期2须早于到期日期1!"); pass = false; } if (!thisObj.Model.Strike) { main.message("请输入行权价!"); pass = false; } break; case "Collar": checkModel.Strike12 = false; checkModel.Strike12Empty = false; if (!thisObj.Model.Strike || !thisObj.Model.Strike2 || !thisObj.Model.Strike3) { main.message("执行价格1,2,3必需输入!"); pass = false; } if ((thisObj.Model.Strike == thisObj.Model.Strike2) || thisObj.Model.Strike == thisObj.Model.Strike3 || thisObj.Model.Strike3 == thisObj.Model.Strike2) { main.message("执行价格1,2,3两两不能相等!"); pass = false; } break; } if (!thisObj.Model.TradeAmount) { main.message("请输入交易数量!"); pass = false; } if (thisObj.Model.TradeAmount < 0) { main.message("交易数量不能小于0!"); pass = false; } if (checkModel.CheckExerciseDate) { if (!main.isDate(thisObj.Model.ExerciseDate)) { main.message("请输入正确的到期日!"); pass = false; } } if (checkModel.Strike12Empty && (!thisObj.Model.Strike || !thisObj.Model.Strike2)) { // Butterfly Condor 不必 main.message("执行价格1,2必需输入!"); pass = false; } return pass; }, setModelTrades: function () { var thisObj = this; $.each(thisObj.Model.trades, function (i, d) { d.VarietyId = thisObj.Model.VarietyId; d.UnderlyingId = thisObj.Model.UnderlyingId; d.UnderlyingCode = thisObj.Model.UnderlyingCode; d.UnderlyingInstrumentType = thisObj.Model.UnderlyingInstrumentType; d.Notional = thisObj.Model.Notional; d.TradeAmount = otcformat.trading.notional(thisObj.Model.TradeAmount); d.StockEqvNotional = thisObj.Model.StockEqvNotional; d.ExerciseMode = thisObj.Model.ExerciseMode; d.SettlementType = thisObj.Model.SettlementType; if (thisObj.Model.OptionType) d.OptionType = thisObj.Model.OptionType; d.ExerciseDate = thisObj.Model.ExerciseDate; d.TradeDate = thisObj.Model.TradeDate; d.UnderlyingPrice = d.SpotPrice = thisObj.Model.Price; d.NoRiskRateType = "System"; }); switch (thisObj.Model.Name) { case "Bull Spread": if (thisObj.Model.Strike < thisObj.Model.Strike2) { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; } else { thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[1].BuySell = "买入"; } thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; break; case "Bear Spread": if (thisObj.Model.Strike < thisObj.Model.Strike2) { thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[1].BuySell = "买入"; } else { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; } thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; thisObj.Model.Strike = thisObj.Model.Price; break; case "Straddle": thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "买入"; if (thisObj.Model.UnderlyingInstrumentType === "Stock") { thisObj.Model.Strike = 100; thisObj.Model.trades[0].Strike = 100; thisObj.Model.trades[1].Strike = 100; } else { thisObj.Model.Strike = thisObj.Model.Price; thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike; } break; case "Preplicating Underlying": //交易方向“买入” 0看涨,1看跌 //两条leg 分别是: 买入执行价格高的看涨和卖出执行价格低看跌; //交易方向为“卖出”: //两条leg分别是:买入执行价格低的看跌和卖出执行价格高的看涨 //debugger; thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; if (thisObj.Model.BuySell === "买入") { if (thisObj.Model.trades[0].Strike > thisObj.Model.trades[1].Strike) { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[0].OptionType = "看涨"; thisObj.Model.trades[1].BuySell = "卖出"; thisObj.Model.trades[1].OptionType = "看跌"; } else { thisObj.Model.trades[1].BuySell = "买入";//买入执行价格高的看涨 thisObj.Model.trades[1].OptionType = "看涨"; thisObj.Model.trades[0].BuySell = "卖出"; //看跌?? thisObj.Model.trades[0].OptionType = "看跌"; } } else { if (thisObj.Model.trades[0].Strike > thisObj.Model.trades[1].Strike) { thisObj.Model.trades[0].BuySell = "买入"; //相对客户说?? thisObj.Model.trades[0].OptionType = "看涨"; thisObj.Model.trades[1].BuySell = "卖出"; thisObj.Model.trades[1].OptionType = "看跌"; } else { thisObj.Model.trades[1].BuySell = "买入"; thisObj.Model.trades[1].OptionType = "看涨"; thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[0].OptionType = "看跌"; } } thisObj.Model.Strike = thisObj.Model.Price; break; case "Strangle": thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "买入"; //thisObj.Model.Strike = thisObj.Model.Price; thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; if (thisObj.Model.Strike >= thisObj.Model.Strike2) { thisObj.Model.trades[0].OptionType = "看涨"; thisObj.Model.trades[1].OptionType = "看跌"; } else { thisObj.Model.trades[0].OptionType = "看跌"; thisObj.Model.trades[1].OptionType = "看涨"; } break; case "Butterfly": thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; thisObj.Model.trades[2].BuySell = "买入"; thisObj.Model.trades[0].Notional = thisObj.Model.Notional; var CountRatio = thisObj.Model.Variety.CountRatio || 1; thisObj.Model.trades[0].TradeAmount = otcformat.trading.notional(thisObj.Model.trades[0].Notional / CountRatio); thisObj.Model.trades[1].Notional = thisObj.Model.Notional * 2; thisObj.Model.trades[1].TradeAmount = otcformat.trading.notional(thisObj.Model.trades[1].Notional / CountRatio); thisObj.Model.trades[2].Notional = thisObj.Model.Notional; thisObj.Model.trades[2].TradeAmount = otcformat.trading.notional(thisObj.Model.trades[2].Notional / CountRatio); //中间行权价-行权价间隔,中间行权价,中间行权价+行权价间隔 thisObj.Model.trades[0].Strike = thisObj.Model.MidStrike - thisObj.Model.StrikeGap; thisObj.Model.trades[1].Strike = thisObj.Model.MidStrike; thisObj.Model.trades[2].Strike = parseFloat(thisObj.Model.MidStrike) + parseFloat(thisObj.Model.StrikeGap); break; case "Condor": thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; thisObj.Model.trades[2].Strike = thisObj.Model.Strike3; thisObj.Model.trades[3].Strike = thisObj.Model.Strike4; thisObj.Model.trades[0].OptionType = thisObj.Model.OptionType; thisObj.Model.trades[1].OptionType = thisObj.Model.OptionType; thisObj.Model.trades[2].OptionType = thisObj.Model.OptionType; thisObj.Model.trades[3].OptionType = thisObj.Model.OptionType; thisObj.Model.trades.sort(thisObj.strikeSort); thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; thisObj.Model.trades[2].BuySell = "卖出"; thisObj.Model.trades[3].BuySell = "买入"; break; case "Ratio Spread": if (thisObj.Model.OptionType === "看涨") { if (thisObj.Model.Strike < thisObj.Model.Strike2) { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; } else { thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[1].BuySell = "买入"; } } else if (thisObj.Model.OptionType === "看跌") { if (thisObj.Model.Strike < thisObj.Model.Strike2) { thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[1].BuySell = "买入"; } else { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; } } thisObj.Model.trades[0].Notional = thisObj.Model.Notional; var CountRatio = thisObj.Model.Variety.CountRatio || 1; thisObj.Model.trades[0].TradeAmount = otcformat.trading.notional(thisObj.Model.trades[0].Notional / CountRatio); thisObj.Model.trades[1].Notional = thisObj.Model.Notional2; thisObj.Model.trades[1].TradeAmount = otcformat.trading.notional(thisObj.Model.trades[1].Notional / CountRatio); thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; break; case "Calender Spread": if (thisObj.Model.ExerciseDate < thisObj.Model.ExerciseDate2) { thisObj.Model.trades[0].BuySell = "卖出"; thisObj.Model.trades[1].BuySell = "买入"; } else { thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; } thisObj.Model.trades[0].ExerciseDate = thisObj.Model.ExerciseDate; thisObj.Model.trades[1].ExerciseDate = thisObj.Model.ExerciseDate2; thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike; break; case "Box Spread": thisObj.Model.trades[0].BuySell = "买入"; thisObj.Model.trades[1].BuySell = "卖出"; thisObj.Model.trades[2].BuySell = "买入"; thisObj.Model.trades[3].BuySell = "卖出"; thisObj.Model.trades[0].OptionType = "看涨"; thisObj.Model.trades[1].OptionType = "看跌"; thisObj.Model.trades[2].OptionType = "看跌"; thisObj.Model.trades[3].OptionType = "看涨"; if (thisObj.Model.Strike < thisObj.Model.Strike2) { thisObj.Model.trades[0].Strike = thisObj.Model.Strike; thisObj.Model.trades[1].Strike = thisObj.Model.Strike; thisObj.Model.trades[2].Strike = thisObj.Model.Strike2; thisObj.Model.trades[3].Strike = thisObj.Model.Strike2; } else { thisObj.Model.trades[0].Strike = thisObj.Model.Strike2; thisObj.Model.trades[1].Strike = thisObj.Model.Strike2; thisObj.Model.trades[2].Strike = thisObj.Model.Strike; thisObj.Model.trades[3].Strike = thisObj.Model.Strike; } break; case "Risk Reversal": thisObj.Model.trades[0].Strike = Math.max(thisObj.Model.Strike, thisObj.Model.Strike2); thisObj.Model.trades[1].Strike = Math.min(thisObj.Model.Strike, thisObj.Model.Strike2); break; case "Collar": thisObj.Model.trades[0].OptionType = "看跌"; thisObj.Model.trades[1].OptionType = "看跌"; thisObj.Model.trades[2].OptionType = "看涨"; if (thisObj.Model.SeagullType === "Bullish") { thisObj.Model.trades[1].OptionType = "看涨"; } var strikes = [parseFloat(thisObj.Model.Strike), parseFloat(thisObj.Model.Strike2), parseFloat(thisObj.Model.Strike3)]; strikes.sort((x1, x2) => x1 - x2) thisObj.Model.trades[0].Strike = strikes[0]; thisObj.Model.trades[1].Strike = strikes[1]; thisObj.Model.trades[2].Strike = strikes[2]; break; } //设置初始化信息 $.each(thisObj.Model.trades, function (i, d) { if (d.UnderlyingInstrumentType === "Stock") { d.IsMoneynessOption = "是"; d.TradeSinglePriceType = "%"; d.IsUsePremiumRate = true; } d.Strike = otcformat.trading.umprice(d.Strike); }); thisObj.buySellCalc(); }, strikeSort: function (tr1, tr2) { return tr1.Strike - tr2.Strike; }, buySellCalc: function () { var thisObj = this; if (thisObj.Model.BuySell === "卖出") { //相反 $.each(thisObj.Model.trades, function (i, d) { d.BuySell = d.BuySell === "卖出" ? "买入" : "卖出"; }); } }, addStructureOption: function () { //增加交易策略 var thisObj = this; main.open("/trade/GetStructureOption", thisObj.Model.Option).done(function (res) { }); }, changeAmount: function () { //交易数量= 份额 / 比率 var thisObj = this; thisObj.Model.TradeAmount = otcformat.trading.notional(thisObj.Model.TradeAmount); thisObj.Model.Notional = thisObj.Model.TradeAmount * (thisObj.Model.Variety.CountRatio || 1); thisObj.Model.StockEqvNotional = otcformat.trading.StockEqvNotional(thisObj.Model.Notional * thisObj.Model.Price); }, changeVariety: function (variety, flag) { if (flag === 'select') { if (this.Model.VarietyId === variety.id) return; autoUnderlying.setVarietyId(variety.id); autoUnderlying.selectFirst(variety.id); } else { autoVariety.setData(variety); } }, changeStockEqvNotional: function () { var thisObj = this; thisObj.Model.Notional = otcformat.trading.notional(thisObj.Model.StockEqvNotional / thisObj.Model.Price); if (thisObj.Model.Notional) { thisObj.Model.TradeAmount = otcformat.trading.notional(thisObj.Model.Notional / (thisObj.Model.Variety.CountRatio || 1)); } else { thisObj.Model.TradeAmount = ""; } }, //绝对值执行价格 showAbsStrike() { this.IsMoneynessOption = false; this.moneynessSwitch(this.trade); }, //百分比执行价格 showPercentStrike() { this.IsMoneynessOption = true; this.moneynessSwitch(this.trade); }, moneynessSwitch(trade) { let spotPrice = parseFloat(this.Model.Price) || 0; let isSpotZero = Math.abs(spotPrice) < 1e-4; let strikes = ["Strike", "Strike2", "Strike3", "Strike4"]; for (var key of strikes) { if (this.IsMoneynessOption) { this.Model[key] = pricingFormat.premiumRate(isSpotZero ? 1 : this.Model[key] / spotPrice); } else { this.Model[key] = pricingFormat.umprice(this.Model[key] * spotPrice); } } } }, components: { 'vue-number-input': FastVue.vueNumberInput() } });