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_corresponding_close(db_session, contract_type, listed_date,
                             delisted_date):
     contract_instruments = InstrumentRepo.get_instrument_by_contract_in_range(
         db_session, contract_type, listed_date, delisted_date)
     # 找到上面找出的instrmentsId所对应的QuoteClose数据
     quote_close_list = QuoteCloseRepo.get_instrument_quote_close_list_by_range(
         db_session, contract_instruments, listed_date, delisted_date)
     return quote_close_list
 def update_days_instrument_realized_vol(start_date,
                                         end_date,
                                         force_update=False):
     """
     保存不同交易日的标的历史波动率
     :param start_date:
     :param end_date:
     :param force_update:
     :return:
     """
     db_session = create_db_session
     while start_date <= end_date:
         try:
             valuation_date = start_date
             # 获取全量instrument表数据
             instrument_id_dict = {}
             for instrument in InstrumentRepo.get_all_instrument(
                     db_session):
                 instrument_id_dict[
                     instrument.instrumentId] = instrument.instrumentType
             # 获取instrument id list
             instruments = InstrumentRepo.get_instruments_by_trade_date(
                 db_session, valuation_date)
             # 获取valuation_date的标的历史波动率
             realized_vol_dict, failed_instrument_id_dict = RealizedVolService. \
                 update_day_instrument_realized_vol(db_session, instrument_id_dict, instruments, valuation_date)
             # 获取valuation_date已经存在的标的历史波动率
             existed_realized_vol_dict = RealizedVolRepo. \
                 get_realized_vol_dict_by_valuation_date(db_session, valuation_date)
             # 保存历史波动率
             RealizedVolService. \
                 save_realized_vol(db_session, valuation_date, realized_vol_dict, existed_realized_vol_dict,
                                   force_update)
             start_date = start_date + timedelta(days=1)
             if len(failed_instrument_id_dict) != 0:
                 failed_length = len(failed_instrument_id_dict)
                 total_length = len(instruments)
                 logging.error('交易日为: %s, 计算历史波动率失败为 %d of %d, 标的id为: %s' %
                               (valuation_date, failed_length, total_length,
                                failed_instrument_id_dict))
         except Exception as e:
             db_session.close()
             raise e
     db_session.close()
Beispiel #4
0
 def update_all_future_contract_info(start_date,
                                     end_date,
                                     force_update=False,
                                     active_only=True):
     db_session = std.create_db_session()
     variety_types = InstrumentRepo.get_commodity_variety_types(
         db_session, active_only)
     exist_dict = CommodityFutureContractRepo.get_exist_future_contract_info(
         db_session, force_update, start_date, end_date, variety_types)
     for variety_type in variety_types:
         logging.info('正在处理的合约类型为:%s' % variety_type)
         fc_list = CommodityFutureContractService.get_future_contract_order(
             db_session, variety_type, exist_dict.get(variety_type),
             start_date, end_date)
         CommodityFutureContractRepo.insert_fc_info_list(
             db_session, fc_list)
 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)
Beispiel #6
0
    def get_heat_map(db_session, trade_date):
        redis_session = RedisUtils.get_redis_session()
        # 获取当天所主力合约
        primary_contracts = CommodityFutureContractRepo.get_all_primary_contracts_by_date(
            db_session, trade_date)
        primary_contract_ids = [
            primary_contract.primaryContractId
            for primary_contract in primary_contracts
        ]
        # 获取instruments
        instruments = InstrumentRepo.get_instruments_by_ids(
            db_session, primary_contract_ids)
        # 默认开始日期向前半年
        start_date = trade_date - timedelta(days=183)
        end_date = trade_date

        heat_map_list, diagnostic_list = [], []
        for index, instrument in enumerate(instruments):
            instrument_id = instrument.instrumentId
            short_name = instrument.shortName
            contract_type = instrument.contractType
            key = (contract_type + DateTimeUtils.date2str(trade_date))
            heat_map_bytes = redis_session.get(key)

            if heat_map_bytes:
                heat_map_schema = HeatMapSchema(many=False, exclude=[])
                heat_map_dto = heat_map_schema.loads(heat_map_bytes).data
                heat_map_list.append(heat_map_dto)
            else:
                heat_map_dto, diagnostics = OtcAtmQuoteService.calc_one_instrument_heat_map(
                    db_session, short_name, contract_type, instrument_id,
                    start_date, end_date)
                heat_map_schema = HeatMapSchema(many=False, exclude=[])
                heat_map_str = heat_map_schema.dumps(heat_map_dto).data
                redis_session.set(key, heat_map_str)
                heat_map_list.append(heat_map_dto)
                diagnostic_list.append(diagnostics)
        return heat_map_list, diagnostic_list
Beispiel #7
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)
 def load_instruments(self, db_session, active_only):
     return InstrumentRepo.get_active_instruments(db_session, active_only)
Beispiel #9
0
 def load_instruments(self, db_session, active_only):
     return InstrumentRepo.load_instruments_in_option_conf(db_session)
Beispiel #10
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
Beispiel #11
0
 def is_commodity_variety_type(db_session, instrument_id):
     variety_types = InstrumentRepo.get_commodity_variety_types(db_session)
     if instrument_id in variety_types:
         return True
     else:
         return False
Beispiel #12
0
 def get_grouped_instrument_id_list(db_session, trade_date):
     return InstrumentRepo.get_grouped_instrument_id_list(
         db_session, trade_date)
Beispiel #13
0
 def get_instrument_id_list(db_session, trade_date, filtering=True):
     return InstrumentRepo.get_instrument_id_list(db_session, trade_date,
                                                  filtering)
Beispiel #14
0
 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
Beispiel #15
0
 def get_commodity_variety_types(db_session):
     variety_types = InstrumentRepo.get_commodity_variety_types(db_session)
     return variety_types