def get_primary_instrument_id(db_session, instrument_id, trade_date, is_primary): if InstrumentService.is_commodity_variety_type(db_session, instrument_id): # 如果传入的是大宗合约类型, 则直接获取当天的主力合约代码 variety_type = instrument_id else: if is_primary is False: return instrument_id # 如果传入的是具体的大宗标的代码, 则直接获取当天的主力合约代码 variety_type = InstrumentService.get_commodity_variety_type( db_session, instrument_id) # 如果获取到的合约种类为空, 则说明该标的不是大宗商品, 直接返回标的代码 if variety_type is None: instrument = InstrumentRepo.get_instrument(db_session, instrument_id) if instrument is None: raise CustomException('不支持标的%s' % instrument_id) return instrument_id else: future_contract = CommodityFutureContractRepo.get_commodity_future_contract( db_session, variety_type, trade_date) if future_contract is None or future_contract.primaryContractId is None: raise CustomException( "合约类型%s在%s下无主力合约数据" % (variety_type, DateTimeUtils.date2str(trade_date))) return future_contract.primaryContractId
def get_instrument_quote_close_list_by_period(db_session, instrument_id, start_date, end_date, is_primary=False): if not InstrumentService.is_commodity_variety_type(db_session, instrument_id): variety_type = None if is_primary: # 如果是大宗商品标的,则直接使用variety_type variety_type = InstrumentService.get_commodity_variety_type(db_session, instrument_id) if variety_type is None: instrument = InstrumentRepo.get_instrument(db_session, instrument_id) if instrument is None: raise CustomException('暂不支持标的物%s,请导入该标的物行情' % instrument_id) quote_close_dbo_list = QuoteCloseRepo.\ get_instrument_quote_close_list_by_period(db_session, instrument_id, start_date, end_date) else: quote_close_dbo_list = QuoteCloseService.\ get_commodity_future_quote_close_list_by_period(db_session, variety_type, start_date, end_date) else: quote_close_dbo_list = QuoteCloseService.\ get_commodity_future_quote_close_list_by_period(db_session, instrument_id, start_date, end_date) return QuoteCloseService.to_dtos(quote_close_dbo_list)
def get_instrument_atm_quote_list_by_period(db_session, underlyer, start_date, end_date, is_primary): if not InstrumentService.is_commodity_variety_type( db_session, underlyer): variety_type = None if is_primary: # 如果是大宗商品标的,则直接使用variety_type variety_type = InstrumentService.get_commodity_variety_type( db_session, underlyer) if variety_type is None: instrument = InstrumentRepo.get_instrument( db_session, underlyer) if instrument is None: raise CustomException('暂不支持标的物%s,请导入该标的物行情' % underlyer) atm_quote_dbo_list = OtcAtmQuoteRepo.\ get_instrument_atm_quote_list_by_period(db_session, underlyer, start_date, end_date) else: atm_quote_dbo_list = OtcAtmQuoteRepo.\ get_commodity_future_atm_quote_list_by_period(db_session, variety_type, start_date, end_date) else: atm_quote_dbo_list = OtcAtmQuoteRepo.\ get_commodity_future_atm_quote_list_by_period(db_session, underlyer, start_date, end_date) return OtcAtmQuoteService.to_dtos(atm_quote_dbo_list)
def calc_instrument_otc_implied_vol_points( db_session, instrument, trade_date, strike_type, contract_order=FutureContractOrder.PRIMARY.name, percents=[0.8, 0.9, 0.95, 1, 1.05, 1.1, 1.2]): last_trade_date = trade_date logging.info("现在计算%s的vol surface" % instrument) quote_close_instrument = QuoteCloseService.get_instrument_quote_close_list_by_period( db_session, instrument, last_trade_date, last_trade_date, is_primary=True)[0] instrument = InstrumentRepo.get_instrument(db_session, instrument) if not quote_close_instrument: raise Exception('trading_date: %s, instrument_id: %s的收盘价信息为空' % (instrument.instrumentId, last_trade_date)) if not quote_close_instrument.closePrice: raise Exception('标的instrument_id: %s,trading_date: %s没有收盘价' % (instrument.instrumentId, last_trade_date)) if strike_type is None: strike_type = VolSurfaceStrikeType.PERCENT if strike_type == VolSurfaceStrikeType.PERCENT: # 根据 percentage 计算vor grid percents = percents elif strike_type == VolSurfaceStrikeType.STRIKE: # 根据 strike 计算 vor grid ,需要获取instrument last_trade_date时的spot_price 也就是 quote_close表的close_price percents = [ quote_close_instrument.closePrice * i for i in percents ] instrument_id = instrument.instrumentId start_date = TradingDayService.go_trading_day(db_session, last_trade_date, 132, -1) end_date = last_trade_date default_windows = [44, 66, 132] default_percentiles = [50] realised_vol_dto_list, realised_vol_log = HistoricalVolService.calc_instrument_realized_vol( db_session, instrument_id, last_trade_date, [1, 3, 5, 10, 22], contract_order) if realised_vol_log: logging.warning(realised_vol_log) realised_vol = {} for item in realised_vol_dto_list: realised_vol[item.window] = item.vol rolling_vol_dto_list, rolling_vol_log = HistoricalVolService.calc_instrument_rolling_vol( db_session, instrument_id, start_date, end_date, 22, contract_order) if rolling_vol_log: logging.warning(rolling_vol_log) vol_cone_dto_list, vol_cone_log = HistoricalVolService.calc_instrument_vol_cone( db_session, instrument_id, start_date, end_date, default_windows, default_percentiles, contract_order) if vol_cone_log: logging.warning(vol_cone_log) vol_cone = {} for item in vol_cone_dto_list: vol_cone[item.window] = {} for vol_item in item.vols: vol_cone[item.window][vol_item.percentile] = vol_item.vol # 按日期从小到大排序 rolling_vol_list = [ item.vol for item in sorted( rolling_vol_dto_list, key=lambda x: x.tradeDate, reverse=True) ] vol_surface = { '2W': (realised_vol[1] * 40 + realised_vol[3] * 20 + realised_vol[5] * 20 + realised_vol[10] * 10 + realised_vol[22] * 10) / 100, '1M': ((sum(rolling_vol_list) / len(rolling_vol_list)) * 30 + realised_vol[1] * 30 + realised_vol[3] * 20 + realised_vol[5] * 20) / 100, '2M': (vol_cone[44][50] * 60 + realised_vol[1] * 10 + realised_vol[22] * 30) / 100, '3M': (vol_cone[66][50] * 80 + realised_vol[1] * 10 + realised_vol[22] * 10) / 100, '6M': (vol_cone[132][50] * 90 + realised_vol[1] * 5 + realised_vol[22] * 5) / 100 } dto_vol_surface = VolSurfaceDTO() dto_vol_surface.instrumentId = instrument_id dto_vol_surface.valuationDate = last_trade_date dto_vol_surface.strikeType = strike_type.name dto_vol_surface.instance = InstanceType.INTRADAY.name # TODO WHAT IS T-A-G? # dto_vol_surface.tag = # get model_info dto_model_info = VolSurfaceModelInfoDTO() dto_model_info.daysInYear = 245 dto_model_info.modelName = 'TRADER_VOL' dto_underlyer = VolSurfaceUnderlyerDTO() dto_underlyer.instrumentId = instrument_id dto_underlyer.quote = quote_close_instrument.closePrice # dto_underlyer.field = dto_underlyer.instance = InstanceType.INTRADAY.name dto_model_info.underlyer = dto_underlyer dto_model_info.save = True dto_vol_grids = OtcModelService.calc_vol_grid_item( vol_surface, percents) dto_vol_grid_list = [] for tenor, quote in vol_surface.items(): dto_vol_grid = VolGridItemDTO() # vol_grid_item.expiry = dto_vol_grid.tenor = tenor dto_vol_grid.vols = [ x.vols for x in dto_vol_grids if x.tenor == tenor ][0] dto_vol_grid_list.append(dto_vol_grid) dto_model_info.instruments = dto_vol_grid_list dto_vol_surface.model_name = 'TRADER_VOL' dto_vol_surface.field = 'LAST' dto_vol_surface.modelInfo = dto_model_info dto_fitting_model_list = [] for item in dto_model_info.instruments: dto_fitting_model = FittingModelDTO() dto_fitting_model.scatter = item.vols dto_fitting_model.daysInYear = dto_model_info.daysInYear dto_fitting_model_list.append(dto_fitting_model) dto_vol_surface.fittingModels = dto_fitting_model_list return dto_vol_surface
def get_commodity_variety_type(db_session, instrument_id): instrument = InstrumentRepo.get_instrument(db_session, instrument_id) # 不是大宗商品主力合约为空 if instrument is None: return None return instrument.contractType