def import_atm_vol_from_csv_file(file_path, run_id): fname, ext = os.path.splitext(file_path) valuation_date = DateTimeUtils.str2date(fname.split('_')[1], pattern='%Y%m%d') df = pd.read_csv(file_path) atm_quote_list = [] current_time = datetime.now() for index, row in df.iterrows(): atm_quote = OtcAtmQuote() atm_quote.uuid = uuid.uuid4() atm_quote.varietyType = row['udly'].strip() atm_quote.underlyer = row['code'].strip() atm_quote.legalEntityName = row['ctpt'].strip() atm_quote.expireDate = DateTimeUtils.str2date(row['exe_date']) if row['type'] == 'am': atm_quote.productType = OptionProductType.VANILLA_AMERICAN.name if row['type'] == 'eu': atm_quote.productType = OptionProductType.VANILLA_EUROPEAN.name atm_quote.ptm = float(row['ptm']) atm_quote.askVol = float(row['ask_vol_cal']) atm_quote.bidVol = float(row['bid_vol_cal']) atm_quote.volEdge = float(row['vol_edge_cal']) atm_quote.source = 'EXCEL_%s' % run_id atm_quote.valuationDate = valuation_date atm_quote.updatedAt = current_time atm_quote_list.append(atm_quote) db_sessin = create_db_session() db_sessin.add_all(atm_quote_list) db_sessin.commit()
def convert_data_to_position_snapshot(clean_position_dict): """ 格式化为otc_position_snapshot表model :param clean_position_dict: :return: """ position_snapshots = [] for trans_code, clean_position in clean_position_dict.items(): # todo 需要删除continue if clean_position is None: continue report_date = DateTimeUtils.str2date( clean_position.get('report_date')) position_date = DateTimeUtils.str2date( clean_position.get('position_date')) item = OTCPositionSnapshot( transCode=clean_position.get('trans_code'), recordId=clean_position.get('record_id'), reportDate=report_date, positionDate=position_date, instrumentId=clean_position.get('underlyer'), mainBodyName=clean_position.get('main_body_name'), tradeNotional=clean_position.get('trade_notional'), impliedVol=clean_position.get('implied_vol'), interestRate=clean_position.get('interest_rate'), dividend=clean_position.get('dividend'), updatedAt=datetime.now()) position_snapshots.append(item) return position_snapshots
async def get_commodity_future_contract_order(self, variety_type, start_date, end_date): with self.make_session() as db_session: fc_info_list = CommodityFutureContractService.get_future_contract_order_dto( db_session, variety_type, [], DateTimeUtils.str2date(start_date), DateTimeUtils.str2date(end_date)) fc_info_schema = FutureContractInfoSchema(many=True) return fc_info_schema.dump(fc_info_list).data
async def get_historical_and_neutral_vol_list(self, instrument_ids, start_date, end_date, window, is_primary=False): with self.make_session() as db_session: start_date_obj = DateTimeUtils.str2date(start_date) end_date_obj = DateTimeUtils.str2date(end_date) neutral_vol_list, diagnostics = HistoricalVolService.calc_historical_and_neutral_vol_list( db_session, instrument_ids, start_date_obj, end_date_obj, window, is_primary) neutral_vol_schema = NeutralVolSchema(many=True) return DiagnosticResponse( neutral_vol_schema.dump(neutral_vol_list).data, diagnostics)
async def get_wing_model( self, contract_type, observed_date, start_strike=None, end_strike=None, point_num=None, step=None, strike_type=FittingModelStrikeType.valueOf('STRIKE'), days_in_year=365, calendar_name=None): with self.make_session() as db_session: observed_date = DateTimeUtils.str2date(observed_date) if OptionStructureRepo.check_commodity(db_session, contract_type): vol_surface_dto = WingModelService.calc_commodity_vol_surface( db_session, contract_type, observed_date, start_strike, end_strike, point_num, step, FittingModelStrikeType.valueOf(strike_type.upper()), days_in_year, calendar_name) else: vol_surface_dto = WingModelService.calc_fund_vol_surface( db_session, contract_type, observed_date, start_strike, end_strike, point_num, step, FittingModelStrikeType.valueOf(strike_type.upper()), days_in_year, calendar_name) vol_surface_schema = VolSurfaceSchema() return vol_surface_schema.dump(vol_surface_dto).data
async def get_instrument_rolling_vol(self, instrument_id, start_date, end_date, window, is_primary=False): with self.make_session() as db_session: start_date_obj = DateTimeUtils.str2date(start_date) end_date_obj = DateTimeUtils.str2date(end_date) realized_vol_dto_list, diagnostics = HistoricalVolService.calc_instrument_rolling_vol( db_session, instrument_id, start_date_obj, end_date_obj, window, is_primary) realized_vol_schema = RealizedVolSchema( many=True, exclude=['instrumentId', 'percentile']) return DiagnosticResponse( realized_vol_schema.dump(realized_vol_dto_list).data, diagnostics)
def import_vol_surface_from_excel_file(): """ 解析excel文件保存到 vol surface表 :return: """ instrument_ids = sys.argv[1].split(",") dir_case = sys.argv[3] valuation_date = DateTimeUtils.str2date(sys.argv[2]) data = xlrd.open_workbook(dir_case) for instrument_id in instrument_ids: try: # 判断是否获取到了spot price instrument_dict = VolSurfaceExcelService.get_instrument_spot( instrument_id) spot_price = instrument_dict.get('lastPrice') if spot_price is None: logging.error('发送请求获取标的: %s的成功, 但是没有spot_price' % instrument_id) continue logging.info('发送请求获取标的: %s的spot price成功' % instrument_id) logging.info('开始解析excel,标的为: %s' % instrument_id) table = data.sheet_by_name(instrument_id) vol_surface_dto = VolSurfaceExcelService.convert_to_vol_surface_dto( instrument_id, valuation_date, table, spot_price) logging.info('解析excel成功,标的为: %s' % instrument_id) vol_surface_schema = VolSurfaceSchema() # 序列化对象 vol_surface = vol_surface_schema.dump(vol_surface_dto).data # 发送请求 VolSurfaceExcelService.send_post_request(vol_surface) except Exception as e: logging.error('标的: %s,出现错误: %s' % (instrument_id, e))
async def get_instrument_id_list(self, trade_date=DateTimeUtils.date2str( date.today()), filtering=True): with self.make_session() as db_session: instrument_id_list = InstrumentService.\ get_instrument_id_list(db_session, DateTimeUtils.str2date(trade_date), filtering) return instrument_id_list
async def get_instrument_realized_vol( self, instrument_id, trade_date, windows=[1, 3, 5, 10, 22, 44, 66, 132], is_primary=False): with self.make_session() as db_session: trade_date_obj = DateTimeUtils.str2date(trade_date) if trade_date_obj > date.today(): raise CustomException('所选日期不能超过今天') realized_vol_dto_list, diagnostics = HistoricalVolService.calc_instrument_realized_vol( db_session, instrument_id, DateTimeUtils.str2date(trade_date), windows, is_primary) realized_vol_schema = RealizedVolSchema( many=True, exclude=['tradeDate', 'instrumentId', 'percentile']) return DiagnosticResponse( realized_vol_schema.dump(realized_vol_dto_list).data, diagnostics)
def get_future_contract_order(db_session, contract_type, exist_dates, start_date, end_date): holidays = TradingCalendarRepo.get_holiday_list(db_session) special_dates = [] if start_date > end_date: logging.error( "日期指定非法:%s 大于 %s" % DateTimeUtils.date2str(start_date), DateTimeUtils.date2str(end_date)) return None else: all_dates = [ DateTimeUtils.str2date(date.strftime("%Y-%m-%d")) for date in rrule(DAILY, dtstart=start_date, until=end_date) ] if exist_dates: missing_dates = list(set(all_dates) - set(exist_dates)) else: missing_dates = all_dates listed_date, delisted_date = DateTimeUtils.offset_trade_date( start_date, end_date, holidays, special_dates) close_dict = CommodityFutureContractService.get_corresponding_close( db_session, contract_type, listed_date, delisted_date) instruments_list = db_session.query(Instrument).filter( Instrument.contractType == contract_type) fc_list = [] if close_dict: for trade_date in missing_dates: if DateTimeUtils.is_trading_day(trade_date, holidays, special_dates): logging.info("处理交易日%s" % DateTimeUtils.date2str(trade_date)) previous_trade_date, _ = DateTimeUtils.offset_trade_date( trade_date, trade_date, holidays, special_dates) pri, sec = FutureContractInfoAlgo.calc_one_future_contract_info( instruments_list, close_dict, contract_type, previous_trade_date) if pri: fc_info = FutureContractInfo( contractType=contract_type, tradeDate=trade_date, primaryContractId=pri, secondaryContractId=sec) logging.info( '合约的主力和次主力为:%s %s %s %s' % (fc_info.contractType, DateTimeUtils.date2str(fc_info.tradeDate), fc_info.primaryContractId, fc_info.secondaryContractId)) fc_list.append(fc_info) else: logging.info("跳过非交易日%s" % DateTimeUtils.date2str(trade_date)) else: fc_list = None return fc_list
async def get_implied_vol_report(self, instrument_id, report_date): with self.make_session() as db_session: report_date_obj = DateTimeUtils.str2date(report_date) if report_date_obj > date.today(): raise CustomException('所选日期不能超过今天') vol_report_dto_list = OTCPositionSnapshotService.get_implied_vol_report( db_session, instrument_id, report_date_obj) implied_vol_report_schema = ImpliedVolReportSchema(many=True, exclude=[]) return implied_vol_report_schema.dump(vol_report_dto_list).data
async def get_instrument_vol_cone( self, instrument_id, start_date, end_date, windows=[1, 3, 5, 10, 22, 44, 66, 132], percentiles=[0, 0.1, 0.25, 0.50, 0.75, 0.90, 1], is_primary=False): with self.make_session() as db_session: start_date_obj = DateTimeUtils.str2date(start_date) end_date_obj = DateTimeUtils.str2date(end_date) vol_cone_dto_list, diagnostics = HistoricalVolService.calc_instrument_vol_cone( db_session, instrument_id, start_date_obj, end_date_obj, windows, [percentile * 100 for percentile in percentiles], is_primary) vol_cone_schema = VolConeSchema( many=True, exclude=['vols.instrumentId', 'vols.tradeDate', 'vols.window']) return DiagnosticResponse( vol_cone_schema.dump(vol_cone_dto_list).data, diagnostics)
def update_eod_date(start_date_str=EODDateConfig.eod_start_date, end_date_str=DateTimeUtils.date2str(date.today()), eod_cutoff_time=EODDateConfig.eod_cutoff_time): end_date = DateTimeUtils.str2date(end_date_str) start_date = DateTimeUtils.str2date(start_date_str) # 获取节假日信息 db_session = create_db_session() # TODO: 需要从配置文件读取 if not TradingDayService.is_trading_day(db_session, end_date): # 如果当天不是交易日则直接计算上一个交易日的值 end_date = TradingDayService.go_trading_day(db_session, end_date, 1, -1) else: # 如果是交易日,小于cutoff time还是返回上一个交易日 if datetime.now().time() < DateTimeUtils.str2time(eod_cutoff_time): end_date = TradingDayService.go_trading_day(db_session, end_date, 1, -1) else: end_date = end_date # 设置变量到airflow variable AirflowVariableUtils.set_eod_start_date(start_date) AirflowVariableUtils.set_eod_end_date(end_date)
async def save_otc_atm_quote_list(self): # 如果标的物代码不为空,则忽略instrument_ids # TODO: 需要完善 with self.make_session() as db_session: atm_quote_list = [] dto = OtcAtmQuoteDTO() dto.uuid = 'f405e2f8-cb14-11e9-80de-00163e08c03e' dto.underlyer = 'RS911.CZC' dto.valuationDate = DateTimeUtils.str2date('2019-09-03') dto.askVol = 0.1 dto.bidVol = 0.2 atm_quote_list.append(dto) atm_quote_dto_list = OtcAtmQuoteService.save_otc_atm_quote_list(db_session, atm_quote_list) otc_atm_quote_schema = OtcAtmQuoteSchema(many=True, exclude=[]) return otc_atm_quote_schema.dump(atm_quote_dto_list).data
async def get_latest_vol_surface( self, instrument_id, valuation_date, strike_type=VolSurfaceStrikeType.PERCENT.name, instance=VolSurfaceInstanceType.CLOSE.name, is_primary=False): with self.make_session() as db_session: vol_surface_dto = ImpliedVolService.get_latest_vol_surface( db_session, instrument_id, DateTimeUtils.str2date(valuation_date), strike_type, instance, is_primary) if vol_surface_dto is None: raise CustomException('没有找到对应的波动率曲面') vol_surface_schema = VolSurfaceSchema(exclude=[]) return vol_surface_schema.dump(vol_surface_dto).data
def recon_one_instrument(self, params): instrument, start_date, end_date, holidays, dry_run, ignore_milestone = params db_session = std.create_db_session() try: logging.info("开始Recon标的物: %s" % instrument.instrumentId) # 获取标的物Milestone milestone = self.get_milestone(db_session, instrument) # 只处理标的物上市日期和退市日期之间的数据 if instrument.listedDate is not None and start_date < instrument.listedDate: start_date = instrument.listedDate if instrument.delistedDate is not None and end_date > instrument.delistedDate: end_date = instrument.delistedDate # 需要Recon的日期由API给出 quote_close_dates = self.request_quote_close_dates(instrument, start_date, end_date) if not quote_close_dates: unchecked_trading_dates = [] else: unchecked_trading_dates = [DateTimeUtils.str2date(x) for x in quote_close_dates] # 对缺数数据进行处理 existing_trading_dates = self.get_existing_trading_dates(db_session, instrument) # 计算出缺失数据 missing_trading_dates = self.get_missing_trading_dates(instrument, unchecked_trading_dates, existing_trading_dates) if not dry_run: self.upsert_missing_trading_dates(db_session, instrument, missing_trading_dates) # TODO 需要对多余的数据进行处理 # 计算出多余数据 extra_trading_dates = [] logging.info("Recon找到多余数据:%s -> %d 个Break" % (instrument.instrumentId, len(extra_trading_dates))) # 如果没有差值,则比较开始日期和Milestone,更新Milestone has_missing_dates = len(missing_trading_dates) != 0 has_extra_dates = len(extra_trading_dates) != 0 if (not has_missing_dates) and (not has_extra_dates) and (not dry_run): if start_date <= end_date: self.upsert_milestone(db_session, instrument, start_date, end_date, milestone) else: logging.info("标的物开始日期大于结束日期,不更新Milestone:%s [%s %s]" % ( instrument.instrumentId, start_date.strftime('%Y%m%d'), end_date.strftime('%Y%m%d'))) return instrument, (not has_missing_dates) and (not has_extra_dates) except Exception as e: logging.error("Recon失败,标的物:%s, 异常:%s" % (instrument.instrumentId, e)) return instrument, False finally: db_session.close()
def get_holidays(): ip = BCTServerConfig.host port = BCTServerConfig.port service = 'reference-data-service' method = 'refTradingCalendarGet' params = {'calendarId': 'DEFAULT_CALENDAR'} holidays = [] try: result = call_request_from_bct(ip, port, service, method, params) if result == 'error': logging.error('发送请求获取trading calendar失败') else: holidays = result.get('result').get('holidays') holidays = [DateTimeUtils.str2date(_.get('holiday')) for _ in holidays] except Exception as e: logging.error('发送请求获取trading calendar失败') return holidays
def get_eod_end_date(): return DateTimeUtils.str2date(Variable.get(Constants.EOD_END_DATE))
async def get_instrument_atm_vol_list(self, underlyder, start_date, end_date, is_primary=False): with self.make_session() as db_session: atm_vol_list, diagnostics = OtcAtmQuoteService.calc_instrument_atm_vol_list( db_session, underlyder, DateTimeUtils.str2date(start_date), DateTimeUtils.str2date(end_date), is_primary) realized_vol_schema = RealizedVolSchema(many=True, exclude=['instrumentId', 'window', 'percentile']) return DiagnosticResponse(realized_vol_schema.dump(atm_vol_list).data, diagnostics)
def get_eod_manual_date(): return DateTimeUtils.str2date(Variable.get(Constants.EOD_MANUAL_DATE))
def get_eod_start_date(): return DateTimeUtils.str2date(Variable.get(Constants.EOD_START_DATE))