def load_volgrids(self): self.logger.info('loading volgrids') dtoday = datetime2xl(datetime.datetime.now()) for prod in self.volgrids.keys(): logfile = self.folder + 'volgrids_' + prod + '.csv' self.volgrids[prod].dtoday = dtoday if os.path.isfile(logfile): with open(logfile, 'rb') as f: reader = csv.reader(f) for row in enumerate(reader): inst = row[0] expiry = datetime.date.strptime(row[1], '%Y%m%d') fwd = float(row[2]) atm = float(row[3]) v90 = float(row[4]) v75 = float(row[5]) v25 = float(row[6]) v10 = float(row[7]) if len(row) > 8: ccy = str(row[8]) else: ccy = 'CNY' dexp = date2xl(expiry) + 15.0 / 24.0 self.volgrids[prod].underlier[expiry] = inst self.volgrids[prod].df[expiry] = discount( self.irate[ccy], dtoday, dexp) self.volgrids[prod].fwd[expiry] = fwd self.volgrids[prod].dexp[expiry] = dexp self.volgrids[prod].volparam[expiry] = [ atm, v90, v75, v25, v10 ] self.volgrids[prod].volnode[ expiry] = pyktlib.Delta5VolNode( dtoday, dexp, fwd, atm, v90, v75, v25, v10, self.volgrids[prod].accrual) else: for expiry in self.volgrids[prod].option_insts: dexp = date2xl(expiry) + 15.0 / 24.0 under_instID = self.volgrids[prod].underlier[expiry] fwd = self.instruments[under_instID].price ccy = self.instruments[under_instID].ccy if self.volgrids[prod].spot_model: fwd = fwd / self.volgrids[prod].df[expiry] self.volgrids[prod].fwd[expiry] = fwd self.volgrids[prod].dexp[expiry] = dexp self.volgrids[prod].df[expiry] = discount( self.irate[ccy], dtoday, dexp) atm = self.volgrids[prod].volparam[expiry][0] v90 = self.volgrids[prod].volparam[expiry][1] v75 = self.volgrids[prod].volparam[expiry][2] v25 = self.volgrids[prod].volparam[expiry][3] v10 = self.volgrids[prod].volparam[expiry][4] self.volgrids[prod].volnode[ expiry] = pyktlib.Delta5VolNode( dtoday, dexp, fwd, atm, v90, v75, v25, v10, self.volgrids[prod].accrual) return
def set_market_data(self, market_data): self.today = misc.datetime2xl(datetime.datetime.strptime(market_data['MarketDate'], '%Y-%m-%d')) misc.Date.set_origin(*[int(s) for s in market_data['MarketDate'].split('-')][::-1]) super(FXOptionPricer, self).set_market_data(market_data) fwd_quotes = market_data["FXFwd_" + self.ccypair] fwdtenors = [misc.datetime2xl(datetime.datetime.strptime(knot[2], '%Y-%m-%d')) for knot in fwd_quotes] spot_date = misc.Date(str(market_data['MarketDate'])) fwds = [knot[1] for knot in fwd_quotes] self.fx_spot = fwds[0] fwdcurve = curve.ForwardCurve.from_array(fwdtenors, fwds) self.fx_fwd = fwdcurve(self.expiry) vol_field = "FXVOL_" + self.ccypair calendar = misc.Calendar.US voltenors = [ float(calendar.advance(spot_date, misc.Period(str(knot[0]))) - spot_date) for knot in market_data[vol_field]['ATM']] volmark = {} volmark['tenor'] = voltenors for field in ['ATM', 'RRd25', 'RRd10', 'BFd25', 'BFd10']: volmark[field] = [market_data[vol_field][field][i][1] for i in range(len(voltenors))] tom = self.expiry - self.today volpts = {} for field in ['ATM', 'RRd25', 'RRd10', 'BFd25', 'BFd10']: if field == 'ATM': mode = curve.VolCurve.InterpMode.LinearTime else: mode = curve.VolCurve.InterpMode.SqrtTime vcurve = curve.VolCurve.from_array( volmark['tenor'], volmark[field], interp_mode = mode ) volpts[field] = vcurve(tom) self.atm = volpts['ATM'] self.v10 = volpts['BFd10'] + volpts['RRd10']/2.0 self.v90 = volpts['BFd10'] - volpts['RRd10']/2.0 self.v25 = volpts['BFd25'] + volpts['RRd25']/2.0 self.v75 = volpts['BFd25'] - volpts['RRd25']/2.0 self.volnode = pyktlib.Delta5VolNode(self.today, self.expiry, self.fx_fwd, self.atm, self.v90, self.v75, self.v25, self.v10, "act365")
def load_state(self): logfile = self.folder + 'strat_status.csv' if not os.path.isfile(logfile): return self.logger.info('load state for strat = %s' % (self.name)) with open(logfile, 'rb') as f: reader = csv.reader(f) for idx, row in enumerate(reader): if row[0] == 'VolNode': expiry = datetime.datetime.strptime( row[1], '%Y%m%d %H:%M:%S') fwd = float(row[2]) atm = float(row[3]) v90 = float(row[4]) v75 = float(row[5]) v25 = float(row[6]) v10 = float(row[7]) dtoday = datetime2xl(datetime.datetime.now()) dexp = datetime2xl(expiry) self.volgrids[expiry] = pyktlib.Delta5VolNode( dtoday, dexp, fwd, atm, v90, v75, v25, v10, self.accrual) elif row[0] == 'Pos': instID = str(row[1]) self.option_map.loc[instID, 'pos'] = int(row[2]) return
def reset_newvol(self, expiry): vn = self.volgrid.volnode[expiry] self.new_volnode[expiry] = pyktlib.Delta5VolNode(vn.expiry_(), vn.fwd_(), vn.atmVol_(), vn.d90Vol_(), vn.d75Vol_(), vn.d25Vol_(), vn.d10Vol_(), vn.accrual_()) vol_params = [vn.atmVol_(), vn.d90Vol_(), vn.d75Vol_(), vn.d25Vol_(), vn.d10Vol_()] for vlbl, vol_data in zip(['Atm', 'V90', 'V75', 'V25', 'V10'], vol_params): self.stringvars['NewVolParam'][expiry][vlbl].set(keepdigit(vol_data, 4))
def __init__(self, strat, app, master): self.pricer = strat.pricer self.root = master self.name = strat.name self.app = app self.underliers = strat.underliers self.option_insts = strat.option_insts.keys() self.expiries = strat.expiries self.spot_model = strat.spot_model self.cont_mth = [] if len(self.underliers) == 1: self.cont_mth = [ d.year*100+d.month for d in self.expiries] else: self.cont_mth = [ 201000 + int(inst[-3:]) for inst in self.underliers] self.strikes = strat.strikes self.opt_dict = strat.opt_dict self.canvas = None self.pos_canvas = None self.frame = None self.pos_frame = None #vol_labels = ['Expiry', 'Under', 'Df', 'Fwd', 'Atm', 'V90', 'V75', 'V25', 'V10', 'Updated'] self.volgrids = {} self.fwds = {} self.vol_params = {} self.curr_insts = {} self.rf = strat.irate for expiry in self.expiries: vol = strat.volgrids[expiry] dtoday = vol.dtoday_() dexp = vol.dexp_() fwd = vol.fwd_() self.fwds[expiry] = fwd atm = vol.atmVol_() v90 = vol.d90Vol_() v75 = vol.d75Vol_() v25 = vol.d25Vol_() v10 = vol.d10Vol_() self.vol_params = [atm, v90, v75, v25, v10] accr= strat.accrual #print dtoday, dexp, fwd, atm, v90, v75, v25, v10, accr self.volgrids[expiry] = pyktlib.Delta5VolNode(dtoday, dexp, fwd, atm, v90, v75, v25, v10, accr) self.entries = {} self.option_map = {} self.group_risk = {} self.stringvars = {'Insts':{}, 'Volgrid':{}} self.entry_fields = [] self.status_fields = [] self.field_types = {}
def copy_volgrid(vg): volgrid = VolGrid(vg.name, accrual=vg.accrual, is_spot=vg.spot_model) volgrid.main_cont = vg.main_cont volgrid.dtoday = vg.dtoday for expiry in vg.option_insts: volgrid.df[expiry] = vg.df[expiry] volgrid.fwd[expiry] = vg.fwd[expiry] volgrid.volnode[expiry] = pyktlib.Delta5VolNode( vg.dtoday, vg.dexp[expiry], vg.fwd[expiry], vg.volparam[expiry][0], vg.volparam[expiry][1], vg.volparam[expiry][2], vg.volparam[expiry][3], vg.volparam[expiry][4], vg.accrual) volgrid.volparam[expiry] = copy.copy(vg.volparam[expiry]) volgrid.underlier[expiry] = copy.copy(vg.underlier[expiry]) volgrid.dexp[expiry] = vg.dexp[expiry] volgrid.option_insts[expiry] = copy.copy(vg.option_insts[expiry]) return volgrid
def initialize(self): self.load_state() dtoday = date2xl(self.agent.scur_day) + max( self.agent.tick_id - 600000, 0) / 2400000.0 for idx, expiry in enumerate(self.expiries): dexp = datetime2xl(expiry) self.DFs[idx] = self.get_DF(dtoday, dexp) fwd = self.get_fwd(idx) self.last_updated[expiry]['fwd'] = fwd self.last_updated[expiry]['dtoday'] = dtoday if self.spot_model: self.option_map.loc[self.underliers[0], 'delta'] = 1.0 self.option_map.loc[self.underliers[0], 'df'] = 1.0 else: self.option_map.loc[self.underliers[idx], 'delta'] = self.DFs[idx] self.option_map.loc[self.underliers[idx], 'df'] = self.DFs[idx] if self.volgrids[expiry] == None: self.volgrids[expiry] = pyktlib.Delta5VolNode( dtoday, dexp, fwd, 0.24, 0.0, 0.0, 0.0, 0.0, self.accrual) self.volgrids[expiry].setFwd(fwd) self.volgrids[expiry].setToday(dtoday) self.volgrids[expiry].setExp(dexp) self.volgrids[expiry].initialize() if self.spot_model: cont_mth = expiry.year * 100 + expiry.month else: cont_mth = self.agent.instruments[ self.underliers[idx]].cont_mth indices = self.option_map[(self.option_map.cont_mth == cont_mth) & (self.option_map.otype != 0)].index for inst in indices: strike = self.option_map.loc[inst].strike otype = self.option_map.loc[inst].otype if not self.spot_model: self.option_map.loc[inst, 'df'] = self.DFs[idx] self.option_insts[inst] = self.pricer(dtoday, dexp, fwd, self.volgrids[expiry], strike, self.irate, otype) self.update_greeks(inst) self.update_pos_greeks() self.update_group_risk() self.update_margin() self.is_initialized = True return
def copy_volgrid(vg): volgrid = VolGrid(vg.name, accrual=vg.accrual, is_spot=vg.spot_model, ccy=vg.ccy) volgrid.main_cont = vg.main_cont for expiry in vg.option_insts: volgrid.df[expiry] = vg.df[expiry] volgrid.fwd[expiry] = vg.fwd[expiry] volgrid.last_update[expiry] = vg.last_update[expiry] volgrid.volnode[expiry] = pyktlib.Delta5VolNode( vg.t2expiry[expiry] / BDAYS_PER_YEAR, vg.fwd[expiry], vg.volparam[expiry][0], vg.volparam[expiry][1], vg.volparam[expiry][2], vg.volparam[expiry][3], vg.volparam[expiry][4], vg.accrual) volgrid.volparam[expiry] = copy.copy(vg.volparam[expiry]) volgrid.underlier[expiry] = copy.copy(vg.underlier[expiry]) volgrid.t2expiry[expiry] = vg.t2expiry[expiry] volgrid.option_insts[expiry] = copy.copy(vg.option_insts[expiry]) return volgrid
def load_volgrids(self): self.logger.info('loading volgrids') for prod in self.volgrids.keys(): logfile = self.folder + 'volgrids_' + prod + '.csv' if os.path.isfile(logfile): with open(logfile, 'rb') as f: reader = csv.reader(f) for row in reader: inst = row[0] expiry = datetime.datetime.strptime( row[1], '%Y%m%d %H%M%S') fwd = float(row[2]) atm = float(row[3]) v90 = float(row[4]) v75 = float(row[5]) v25 = float(row[6]) v10 = float(row[7]) last_update = float(row[8]) if len(row) > 9: ccy = str(row[9]) else: ccy = 'CNY' if len(row) > 10: mark_date = datetime.datetime.strptime( row[10], '%Y%m%d') if self.scur_day > mark_date.date(): last_update = 0 dexp = datetime2xl(expiry) vg = self.volgrids[prod] vg.underlier[expiry] = inst vg.df[expiry] = discount(self.irate[ccy], self.dtoday(), dexp) vg.fwd[expiry] = fwd vg.volparam[expiry] = [atm, v90, v75, v25, v10] vg.volnode[expiry] = pyktlib.Delta5VolNode( self.dtoday(), dexp, fwd, atm, v90, v75, v25, v10, self.volgrids[prod].accrual) vg.t2expiry[expiry] = vg.volnode[expiry].expiry_( ) * BDAYS_PER_YEAR vg.last_update[expiry] = last_update else: for expiry in self.volgrids[prod].option_insts: dexp = datetime2xl(expiry) vg = self.volgrids[prod] under_instID = vg.underlier[expiry] fwd = self.instruments[under_instID].price ccy = self.instruments[under_instID].ccy if vg.spot_model: fwd = fwd / vg.df[expiry] vg.fwd[expiry] = fwd vg.df[expiry] = discount(self.irate[ccy], self.dtoday(), dexp) atm = vg.volparam[expiry][0] v90 = vg.volparam[expiry][1] v75 = vg.volparam[expiry][2] v25 = vg.volparam[expiry][3] v10 = vg.volparam[expiry][4] vg.volnode[expiry] = pyktlib.Delta5VolNode( self.dtoday(), dexp, fwd, atm, v90, v75, v25, v10, self.volgrids[prod].accrual) vg.t2expiry[expiry] = vg.volnode[expiry].expiry_( ) * BDAYS_PER_YEAR vg.last_update[expiry] = 0
def __init__(self, vg, app, master): all_insts = app.agent.instruments self.root = master self.name = vg.name self.app = app self.option_style = 'EU' if self.name in product_code['CFFEX'] else 'AM' if self.option_style == 'EU': self.iv_func = pyktlib.BlackImpliedVol else: self.iv_func = pyktlib.AmericanImpliedVol self.iv_steps = 40 self.iv_tol = 1e-5 self.expiries = vg.underlier.keys() self.expiries.sort() self.underliers = [vg.underlier[expiry] for expiry in self.expiries] opt_insts = list(set().union(*vg.option_insts.values())) self.option_insts = {} for inst in opt_insts: self.option_insts[inst] = (all_insts[inst].cont_mth, all_insts[inst].otype, all_insts[inst].strike) self.spot_model = vg.spot_model self.cont_mth = list(set([ all_insts[inst].cont_mth for inst in self.option_insts])) self.cont_mth.sort() self.strikes = [list(set([ all_insts[inst].strike for inst in vg.option_insts[expiry]])) for expiry in self.expiries] for idx in range(len(self.strikes)): self.strikes[idx].sort() self.opt_dict = {v: k for k, v in self.option_insts.iteritems()} self.volgrid = instrument.copy_volgrid(vg) self.rf = app.agent.irate.get(vg.ccy, 0.0) self.vm_figure = {} self.vm_lines = dict([(exp, {}) for exp in self.expiries]) self.vm_ax = {} self.otype_selector = {} self.cbbox = {} self.strike_selector = {} self.stringvars = {'Insts': {}, 'Volgrid': {}, 'NewVolParam': {}, 'TheoryVol': {}, 'NewVol': {}, 'DiffVol': {},\ 'Selected': {}, 'ArbStatus': {}} self.new_volnode = {} self.curr_insts = {} self.option_map = {} self.group_risk = {} inst_labels = ['Name', 'Price', 'BidPrice', 'BidVol', 'BidIV', 'AskPrice','AskVol','AskIV', 'MidIV', 'TheoryVol', 'Intrinsic', \ 'Volume', 'OI', 'Updated', 'PV', 'Delta', 'Gamma','Vega', 'Theta', 'RiskPrice', 'RiskUpdated'] inst_types = ['string', 'float', 'float', 'int', 'float', 'float', 'int', 'float', 'float', 'float', 'float', \ 'int', 'int', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float'] for inst in self.option_insts: if inst not in self.stringvars: self.stringvars[inst] = {} for lbl, itype in zip(inst_labels, inst_types): self.stringvars[inst][lbl] = get_type_var(itype) under_labels = ['Name', 'Price', 'MidPrice', 'BidPrice','BidVol','AskPrice','AskVol','UpLimit','DownLimit', 'Volume', 'OI', 'Updated'] under_types = ['string', 'float', 'float', 'float', 'int', 'float', 'int', 'float', 'float', 'int', 'int', 'int'] for inst in list(set(self.underliers)): if inst not in self.stringvars: self.stringvars[inst] = {} for ulbl, utype in zip(under_labels, under_types): self.stringvars[inst][ulbl] = get_type_var(utype) vol_labels = ['Expiry', 'Under', 'Df', 'Fwd', 'Atm', 'V90', 'V75', 'V25', 'V10', 'T2expiry', 'Updated' ] vol_types = ['string', 'string', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float'] self.combobox_choices = ['C-BidIV', 'C-MidIV', 'C-AskIV', 'P-BidIV', 'P-MidIV', 'P-AskIV'] for strikes, expiry in zip(self.strikes, self.expiries): self.stringvars['Volgrid'][expiry] = {} self.stringvars['NewVolParam'][expiry] = {} self.stringvars['Selected'][expiry] = {} self.stringvars['ArbStatus'][expiry] = get_type_var('string') self.stringvars['TheoryVol'][expiry] = {} self.stringvars['NewVol'][expiry] = {} self.stringvars['DiffVol'][expiry] = {} self.otype_selector[expiry] = {} self.cbbox[expiry] = {} self.strike_selector[expiry] = {} vn = self.volgrid.volnode[expiry] self.new_volnode[expiry] = pyktlib.Delta5VolNode(vn.expiry_(), vn.fwd_(), vn.atmVol_(), vn.d90Vol_(), vn.d75Vol_(), vn.d25Vol_(), vn.d10Vol_(), vn.accrual_()) for vlbl, vtype in zip(vol_labels, vol_types): self.stringvars['Volgrid'][expiry][vlbl] = get_type_var(vtype) for vlbl in ['Atm', 'V90', 'V75', 'V25', 'V10']: val = self.stringvars['Volgrid'][expiry][vlbl].get() self.stringvars['NewVolParam'][expiry][vlbl] = get_type_var('float') self.stringvars['NewVolParam'][expiry][vlbl].set(keepdigit(val,4)) fwd = vn.fwd_() for strike in strikes: self.otype_selector[expiry][strike] = tk.StringVar() self.strike_selector[expiry][strike] = tk.BooleanVar() iv = self.volgrid.volnode[expiry].GetVolByStrike(strike) self.stringvars['Selected'][expiry][strike] = get_type_var('float') self.stringvars['Selected'][expiry][strike].set(0.0) self.stringvars['TheoryVol'][expiry][strike] = get_type_var('float') self.stringvars['TheoryVol'][expiry][strike].set(keepdigit(iv, 4)) self.stringvars['NewVol'][expiry][strike] = get_type_var('float') self.stringvars['NewVol'][expiry][strike].set(keepdigit(iv, 4)) self.stringvars['DiffVol'][expiry][strike] = get_type_var('float') self.stringvars['DiffVol'][expiry][strike].set(0.0) self.stringvars['FigSetup'] = dict([(exp, {'YLow': get_type_var('float'), 'YHigh': get_type_var('float')}) for exp in self.expiries]) for exp in self.expiries: for key, ylim in zip(['YLow', 'YHigh'], [0.1, 0.8]): self.stringvars['FigSetup'][exp][key].set(ylim)