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)
Exemple #3
0
 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)
Exemple #4
0
    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