示例#1
0
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 1m(1m) 3m(3m) 1y(1y)',
            'Run_Date': rundate,
            'Currency': 'ZAR',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        old_cx = AdaptivContext()
        # load marketdata
        old_cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketData.json'))
        # load up the CVA marketdata file
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(old_cx.params['Price Factors'])
        # load trade
        self.cx.parse_json(
            os.path.join(self.input_path, self.rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'ZAR')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve
        # set the survival curve to a default value
        self.crb_default = self.cx.deals['Attributes']['Reference']
        self.cx.params['Price Factors'].setdefault(
            'SurvivalProb.' + self.crb_default, {
                'Recovery_Rate':
                0.5,
                'Curve':
                Curve([], [[0.0, 0.0], [.5, .01], [1, .02], [3, .07], [5, .15],
                           [10, .35], [20, .71]]),
                'Property_Aliases':
                None
            })
示例#2
0
def load_market_data(rundate,
                     path,
                     json_name='MarketData.json',
                     cva_default=True):
    """
    Loads a json marketdata file and corresponding calendar (assumed to be named 'calendars.cal')
    :param rundate: folder inside path where the marketdata file resides
    :param path: root folder for the marketdata, calendar and trades
    :param json_name: name of the marketdata json file (default MarketData.json)
    :param cva_default: loads a survival curve with recovery 50% (useful for testing)
    :return: a context object with the data and calendars loaded
    """
    from riskflow.adaptiv import AdaptivContext as Context

    context = Context()
    context.parse_json(os.path.join(path, rundate, json_name))
    context.parse_calendar_file(os.path.join(path, 'calendars.cal'))

    context.params['System Parameters']['Base_Date'] = pd.Timestamp(rundate)

    if cva_default:
        context.params['Price Factors']['SurvivalProb.DEFAULT'] = {
            'Recovery_Rate':
            0.5,
            'Curve':
            utils.Curve([],
                        [[0.0, 0.0], [.5, .01], [1, .02], [3, .07], [5, .15],
                         [10, .35], [20, .71], [30, 1.0]]),
            'Property_Aliases':
            None
        }

    return context
示例#3
0
    def start(self, rundate, input_path, calendar, outfile='CVAMarketDataCal'):
        # disable gpus
        os.environ['CUDA_VISIBLE_DEVICES'] = "-1"
        # set the log level for the parent
        os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
        # set the logger
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s %(levelname)-8s %(message)s',
                            datefmt='%m-%d %H:%M')

        from riskflow.adaptiv import AdaptivContext

        # create the context
        self.cx = AdaptivContext()
        # load calendars
        self.cx.parse_calendar_file(calendar)
        # store the path
        self.path = input_path
        # load marketdata
        if rundate is None:
            self.daily = True
            self.path = os.path.split(input_path)[0]
            self.outfile = outfile
            self.cx.parse_json(input_path)
            # load up the old file if present
            old_output_name = os.path.join(self.path, outfile + '.json')
            if os.path.isfile(old_output_name):
                self.ref = AdaptivContext()
                self.ref.parse_json(old_output_name)
                params_to_bootstrap = self.cx.params[
                    'Bootstrapper Configuration'].keys()
                for factor in [
                        x for x in self.ref.params['Price Factors'].keys()
                        if x.split('.', 1)[0] in params_to_bootstrap
                ]:
                    # override it
                    self.cx.params['Price Factors'][factor] = self.ref.params[
                        'Price Factors'][factor]
            rundate = pd.Timestamp.now().strftime('%Y-%m-%d')
        elif os.path.isfile(
                os.path.join(self.path, rundate, 'MarketDataCal.json')):
            self.cx.parse_json(
                os.path.join(self.path, rundate, 'MarketDataCal.json'))
        elif os.path.isfile(os.path.join(self.path, rundate,
                                         'MarketData.json')):
            self.cx.parse_json(
                os.path.join(self.path, rundate, 'MarketData.json'))
        else:
            logging.error(
                'Cannot find market data for rundate {}'.format(rundate))
            return

        # update the rundate if necessary
        if self.cx.params['System Parameters']['Base_Date'] is None:
            logging.info('Setting  rundate {}'.format(rundate))
            self.cx.params['System Parameters']['Base_Date'] = pd.Timestamp(
                rundate)

        # load the params
        price_factors = self.manager.dict(self.cx.params['Price Factors'])
        price_models = self.manager.dict(self.cx.params['Price Models'])
        sys_params = self.manager.dict(self.cx.params['System Parameters'])
        holidays = self.manager.dict(self.cx.holidays)

        logging.info("starting {0} workers in {1}".format(
            self.NUMBER_OF_PROCESSES, input_path))
        self.workers = [
            Process(target=work,
                    args=(i, self.queue, self.result, price_factors,
                          price_models, sys_params, holidays))
            for i in range(self.NUMBER_OF_PROCESSES)
        ]

        for w in self.workers:
            w.start()

        # load the bootstrapper on to the queue - note - order is important here - hence python 3.6
        for bootstrapper_name, params in self.cx.params[
                'Bootstrapper Configuration'].items():
            # get the market price id and any options for bootstrapping
            market_price, _, *options = params.split(',', 2)
            # get the market prices for this bootstrapper
            market_prices = {
                k: v
                for k, v in self.cx.params['Market Prices'].items()
                if k.startswith(market_price)
            }
            # number of return statuses needed
            status_required = 0
            for market_price in market_prices.keys():
                status_required += 1
                self.queue.put((bootstrapper_name, options, {
                    market_price: market_prices[market_price]
                }))

            for i in range(status_required):
                logging.info(self.result.get())

        # tell the children it's over
        self.queue.put(None)
        # store the results back in the parent context
        self.cx.params['Price Factors'] = price_factors.copy()
        self.cx.params['Price Models'] = price_models.copy()
        # finish up
        # close the queues
        self.queue.close()
        self.result.close()

        # join the children to this process
        for i in range(self.NUMBER_OF_PROCESSES):
            self.workers[i].join()

        # write out the data
        logging.info('Parent: All done - saving data')

        if self.daily:
            # write out the calibrated data
            self.cx.write_marketdata_json(
                os.path.join(self.path, self.outfile + '.json'))
            self.cx.write_market_file(
                os.path.join(self.path, self.outfile + '.dat'))
            logfilename = os.path.join(self.path, self.outfile + '.log')
        else:
            self.cx.write_marketdata_json(
                os.path.join(self.path, rundate, 'MarketDataCal.json'))
            self.cx.write_market_file(
                os.path.join(self.path, rundate, 'MarketDataCal.dat'))
            logfilename = os.path.join(self.path, rundate, 'MarketDataCal.log')

        # copy the logs across
        with open(logfilename, 'wb') as wfd:
            for f in glob.glob('bootstrap*.log'):
                with open(f, 'rb') as fd:
                    shutil.copyfileobj(fd, wfd)
示例#4
0
def bootstrap(path, rundate, reuse_cal=True):
    from riskflow.adaptiv import AdaptivContext

    context = AdaptivContext()

    if reuse_cal and os.path.isfile(
            os.path.join(path, rundate, 'CVAMarketData.json')):
        context.parse_json(os.path.join(path, rundate, 'CVAMarketData.json'))
    else:
        context.parse_json(os.path.join(path, rundate, 'MarketData.json'))

    context.params['System Parameters']['Base_Date'] = pd.Timestamp(rundate)
    context.parse_calendar_file(os.path.join(path, 'calendars.cal'))

    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(levelname)-8s %(message)s',
                        datefmt='%m-%d %H:%M')

    context.bootstrap()
    context.write_marketdata_json(
        os.path.join(path, rundate, 'MarketDataCal.json'))
    context.write_market_file(os.path.join(path, rundate, 'MarketDataCal.dat'))
示例#5
0
class CVAVega(JOB):
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 3m(1m) 2y(3m)',
            'Run_Date': rundate,
            'Currency': 'ZAR',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        self.noshift = AdaptivContext()
        self.noshift.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataNoShift.json'))
        self.shift = AdaptivContext()
        self.shift.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataShift.json'))

        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(
            self.noshift.params['Price Factors'])

        self.cx.parse_json(
            os.path.join(self.input_path, rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'ZAR')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve
        # set the survival curve to a default value
        self.crb_default = self.cx.deals['Attributes']['Reference']
        self.cx.params['Price Factors'].setdefault(
            'SurvivalProb.' + self.crb_default, {
                'Recovery_Rate':
                0.5,
                'Curve':
                Curve([], [[0.0, 0.0], [.5, .01], [1, .02], [3, .07], [5, .15],
                           [10, .35], [20, .71]]),
                'Property_Aliases':
                None
            })

    def valid(self):
        if not self.cx.deals['Deals']['Children'][0]['Children']:
            return False
        else:
            return True

    def run_calc(self, calc):
        from riskflow.calculation import construct_calculation

        self.params['CVA'] = {
            'Deflation':
            self.cx.deals['Calculation'].get('Deflation_Interest_Rate',
                                             'ZAR-SWAP'),
            'Gradient':
            'No'
        }

        if self.cx.deals['Deals']['Children'][0]['instrument'].field.get(
                'Collateralized') == 'True':
            self.logger(self.netting_set, 'is collateralized')
            self.params['Simulation_Batches'] = 20
            self.params['Batch_Size'] = 256
        else:
            self.params['Simulation_Batches'] = 10
            self.params['Batch_Size'] = 512
            self.logger(self.netting_set, 'is uncollateralized')

        # get the calculation parameters for CVA
        default_cva = {
            'Deflate_Stochastically': 'Yes',
            'Stochastic_Hazard_Rates': 'No',
            'Counterparty': self.crb_default
        }
        cva_sect = self.cx.deals.get('Calculation', {
            'Credit_Valuation_Adjustment': default_cva
        }).get('Credit_Valuation_Adjustment', default_cva)

        # update the params
        self.params['CVA']['Counterparty'] = cva_sect['Counterparty']
        self.params['CVA']['Deflate_Stochastically'] = cva_sect[
            'Deflate_Stochastically']
        self.params['CVA']['Stochastic_Hazard'] = cva_sect[
            'Stochastic_Hazard_Rates']

        try:
            out = calc.execute(self.params)
            self.cx.params['Price Factors'].update(
                self.shift.params['Price Factors'])
            calcshift = construct_calculation('Credit_Monte_Carlo', self.cx)
            outshift = calcshift.execute(self.params)
        except Exception as e:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            traceback.print_exception(exc_type,
                                      exc_value,
                                      exc_traceback,
                                      limit=2,
                                      file=sys.stdout)

            self.logger(self.netting_set, 'Exception: ' + str(e.args))
        else:
            stats = out['Stats']
            stats.update({
                'CVA': out['Results']['cva'],
                'CVA_Shift': outshift['Results']['cva'],
                'Currency': self.params['Currency']
            })
            self.stats.setdefault('Stats', {})[self.netting_set] = stats
            # log the netting set
            self.logger(
                self.netting_set,
                'CVA calc complete NoShift:{}, Shift:{}'.format(
                    out['Results']['cva'], outshift['Results']['cva']))
示例#6
0
class FVADEFAULT(JOB):
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 1m(1m) 3m(3m) 1y(1y)',
            'Run_Date': rundate,
            'Currency': 'USD',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        old_cx = AdaptivContext()
        # load marketdata
        old_cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketData.json'))
        # load up the CVA marketdata file
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(old_cx.params['Price Factors'])
        # load trade
        self.cx.parse_json(
            os.path.join(self.input_path, self.rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'USD')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve

        def makeflatcurve(curr, bps, tenor=30):
            return {
                'Currency':
                curr,
                'Curve':
                Curve([],
                      [[0, bps * 0.01 * 0.01], [tenor, bps * 0.01 * 0.01]]),
                'Day_Count':
                'ACT_365',
                'Property_Aliases':
                None,
                'Sub_Type':
                'None'
            }

            # set the survival curve to a default value

        self.crb_default = self.cx.deals['Attributes']['Reference']
        # set up funding curves - ???
        # self.cx.params['Price Factors']['InterestRate.ZAR-SWAP.OIS'] = makeflatcurve('ZAR',-15)
        # self.cx.params['Price Factors']['InterestRate.ZAR-SWAP.FUNDING'] = makeflatcurve('ZAR', 10)

        self.cx.params['Price Factors'][
            'InterestRate.USD-LIBOR-3M.FUNDING'] = makeflatcurve('USD', 65)

        self.cx.params['Price Factors'].setdefault(
            'SurvivalProb.' + self.crb_default, {
                'Recovery_Rate':
                0.5,
                'Curve':
                Curve([], [[0.0, 0.0], [.5, .01], [1, .02], [3, .07], [5, .15],
                           [10, .35], [20, .71], [30, 1.0]]),
                'Property_Aliases':
                None
            })

    def valid(self):
        if not self.cx.deals['Deals']['Children'][0]['Children']:
            return False
        else:
            return True

    def run_calc(self, calc):
        filename = 'FVA_' + self.params[
            'Run_Date'] + '_' + self.crb_default + '.csv'

        if os.path.isfile(os.path.join(self.outputdir, 'Greeks', filename)):
            self.logger(self.netting_set,
                        'Warning: skipping FVA calc as file already exists')
        else:
            self.params['FVA'] = {
                'Funding_Interest_Curve': 'USD-LIBOR-3M.FUNDING',
                'Risk_Free_Curve': 'USD-OIS',
                'Stochastic_Funding': 'Yes',
                'Counterparty': self.crb_default,
                'Gradient': 'Yes'
            }

            if self.cx.deals['Deals']['Children'][0]['instrument'].field.get(
                    'Collateralized', 'False') != 'True':
                # only calc FVA for uncollateralized counterparties
                self.params['Simulation_Batches'] = 10
                self.params['Batch_Size'] = 512
                self.logger(self.netting_set, 'is uncollateralized')

                try:
                    out = calc.execute(self.params)
                except Exception as e:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    traceback.print_exception(exc_type,
                                              exc_value,
                                              exc_traceback,
                                              limit=2,
                                              file=sys.stdout)
                    self.logger(self.netting_set, 'Exception: ' + str(e.args))
                else:
                    stats = out['Stats']
                    if 'grad_fva' in out['Results']:
                        grad_fva = calc.gradients_as_df(
                            out['Results']['grad_fva']).rename(columns={
                                'Gradient':
                                self.cx.deals['Attributes']['Reference']
                            })
                        grad_fva.to_csv(
                            os.path.join(self.outputdir, 'Greeks', filename))
                    # store the FVA as part of the stats
                    out['Stats'].update({
                        'FVA': out['Results']['fva'],
                        'Currency': self.params['Currency']
                    })
                    self.stats.setdefault('Stats',
                                          {})[self.netting_set] = out['Stats']
                    # log the netting set
                    self.logger(self.netting_set, 'FVA calc complete')
示例#7
0
class CVADEFAULT(JOB):
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 1m(1m) 3m(3m) 1y(1y)',
            'Run_Date': rundate,
            'Currency': 'ZAR',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        old_cx = AdaptivContext()
        # load marketdata
        old_cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketData.json'))
        # load up the CVA marketdata file
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(old_cx.params['Price Factors'])
        # load trade
        self.cx.parse_json(
            os.path.join(self.input_path, self.rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'ZAR')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve
        # set the survival curve to a default value
        self.crb_default = self.cx.deals['Attributes']['Reference']
        self.cx.params['Price Factors'].setdefault(
            'SurvivalProb.' + self.crb_default, {
                'Recovery_Rate':
                0.5,
                'Curve':
                Curve([], [[0.0, 0.0], [.5, .01], [1, .02], [3, .07], [5, .15],
                           [10, .35], [20, .71]]),
                'Property_Aliases':
                None
            })

    def valid(self):
        if not self.cx.deals['Deals']['Children'][0]['Children']:
            return False
        else:
            return True

    def run_calc(self, calc):
        filename = 'CVA_' + self.params[
            'Run_Date'] + '_' + self.crb_default + '.csv'

        if os.path.isfile(os.path.join(self.outputdir, 'Greeks', filename)):
            self.logger(self.netting_set,
                        'Warning: skipping CVA calc as file already exists')
        else:
            self.params['CVA'] = {
                'Deflation':
                self.cx.deals['Calculation'].get('Deflation_Interest_Rate',
                                                 'ZAR-SWAP'),
                'Gradient':
                'Yes'
            }

            if self.cx.deals['Deals']['Children'][0]['instrument'].field.get(
                    'Collateralized') == 'True':
                self.logger(self.netting_set, 'is collateralized')
                # make sure the margin period of risk is 10 business days (approx 12 calendar days)
                self.cx.deals['Deals']['Children'][0]['instrument'].field[
                    'Liquidation_Period'] = 12.0
                self.params['Simulation_Batches'] = 20
                self.params['Batch_Size'] = 256
            else:
                self.params['Simulation_Batches'] = 10
                self.params['Batch_Size'] = 512
                self.logger(self.netting_set, 'is uncollateralized')

            # get the calculation parameters for CVA
            default_cva = {
                'Deflate_Stochastically': 'Yes',
                'Stochastic_Hazard_Rates': 'No',
                'Counterparty': self.crb_default
            }
            cva_sect = self.cx.deals.get(
                'Calculation', {
                    'Credit_Valuation_Adjustment': default_cva
                }).get('Credit_Valuation_Adjustment', default_cva)

            # update the params
            self.params['CVA']['Counterparty'] = cva_sect['Counterparty']
            self.params['CVA']['Deflate_Stochastically'] = cva_sect[
                'Deflate_Stochastically']
            self.params['CVA']['Stochastic_Hazard'] = cva_sect[
                'Stochastic_Hazard_Rates']
            # now adjust the survival curve - need intervals of .25 years
            sc = self.cx.params['Price Factors'][
                'SurvivalProb.' +
                cva_sect['Counterparty']]['Curve'].array.copy()
            tenors = np.arange(0, sc[-1][0], .25)
            self.cx.params['Price Factors'][
                'SurvivalProb.' +
                cva_sect['Counterparty']]['Curve'].array = np.array(
                    list(zip(tenors, np.interp(tenors, sc[:, 0], sc[:, 1]))))

            try:
                out = calc.execute(self.params)
            except Exception as e:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                traceback.print_exception(exc_type,
                                          exc_value,
                                          exc_traceback,
                                          limit=2,
                                          file=sys.stdout)

                self.logger(self.netting_set, 'Exception: ' + str(e.args))
            else:
                stats = out['Stats']
                grad_cva = calc.gradients_as_df(
                    out['Results']['grad_cva']).rename(columns={
                        'Gradient':
                        self.cx.deals['Attributes']['Reference']
                    })
                # store the CVA as part of the stats
                out['Stats'].update({
                    'CVA': out['Results']['cva'],
                    'Currency': self.params['Currency']
                })
                grad_cva.to_csv(
                    os.path.join(self.outputdir, 'Greeks', filename))
                self.stats.setdefault('Stats',
                                      {})[self.netting_set] = out['Stats']
                # log the netting set
                self.logger(self.netting_set, 'CVA calc complete')
示例#8
0
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 1m(1m) 3m(3m) 1y(1y)',
            'Run_Date': rundate,
            'Currency': 'ZAR',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        old_cx = AdaptivContext()
        # load marketdata
        old_cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketData.json'))
        # load up the CVA marketdata file
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(old_cx.params['Price Factors'])
        # load trade
        self.cx.parse_json(
            os.path.join(self.input_path, self.rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'ZAR')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve
        # change the currency
        self.params['Currency'] = self.agreement_currency

        def makeflatcurve(curr, bps, tenor=30):
            return {
                'Currency':
                curr,
                'Curve':
                Curve([],
                      [[0, bps * 0.01 * 0.01], [tenor, bps * 0.01 * 0.01]]),
                'Day_Count':
                'ACT_365',
                'Property_Aliases':
                None,
                'Sub_Type':
                'None'
            }

        if self.agreement_currency == 'ZAR':
            self.cx.params['Price Factors'][
                'InterestRate.ZAR-SWAP.OIS'] = makeflatcurve('ZAR', -15)
            self.cx.params['Price Factors'][
                'InterestRate.ZAR-SWAP.FUNDING'] = makeflatcurve('ZAR', 10)
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Collateral_Rate'] = 'ZAR-SWAP.OIS'
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Funding_Rate'] = 'ZAR-SWAP.FUNDING'
        else:
            self.cx.params['Price Factors'][
                'InterestRate.USD-LIBOR-3M.FUNDING'] = makeflatcurve(
                    'USD', 65)
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Collateral_Rate'] = 'USD-OIS'
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Funding_Rate'] = 'USD-LIBOR-3M.FUNDING'
示例#9
0
class COLLVA(JOB):
    def __init__(self, cx, rundate, input_path, outputdir, netting_set, stats,
                 log):
        self.rundate = rundate
        self.input_path = input_path
        self.outputdir = outputdir
        self.netting_set = os.path.splitext(netting_set)[0] + '.json'
        self.stats = stats
        self.logger = log
        self.params = {
            'calc_name': ('cmc', 'calc1'),
            'Time_grid': '0d 2d 1w(1w) 1m(1m) 3m(3m) 1y(1y)',
            'Run_Date': rundate,
            'Currency': 'ZAR',
            'Random_Seed': 5126,
            'Calc_Scenarios': 'No',
            'Dynamic_Scenario_Dates': 'Yes',
            'Debug': 'No',
            'NoModel': 'Constant',
            'Partition': 'None',
            'Generate_Slideshow': 'No',
            'PFE_Recon_File': ''
        }

        from riskflow.adaptiv import AdaptivContext
        self.cx = AdaptivContext()
        old_cx = AdaptivContext()
        # load marketdata
        old_cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketData.json'))
        # load up the CVA marketdata file
        self.cx.parse_json(
            os.path.join(self.input_path, rundate, 'MarketDataCVA.json'))
        # update the cva data with the arena data
        self.cx.params['Price Factors'].update(old_cx.params['Price Factors'])
        # load trade
        self.cx.parse_json(
            os.path.join(self.input_path, self.rundate, self.netting_set))
        # get the netting set
        self.ns = self.cx.deals['Deals']['Children'][0]['instrument'].field
        # get the agreement currency
        self.agreement_currency = self.ns.get('Agreement_Currency', 'ZAR')
        # get the balance currency
        self.balance_currency = self.ns.get('Balance_Currency',
                                            self.agreement_currency)
        # set the OIS cashflow flag to speed up prime linked swaps
        self.cx.params['Valuation Configuration'][
            'CFFloatingInterestListDeal']['OIS_Cashflow_Group_Size'] = 1
        from riskflow.utils import Curve
        # change the currency
        self.params['Currency'] = self.agreement_currency

        def makeflatcurve(curr, bps, tenor=30):
            return {
                'Currency':
                curr,
                'Curve':
                Curve([],
                      [[0, bps * 0.01 * 0.01], [tenor, bps * 0.01 * 0.01]]),
                'Day_Count':
                'ACT_365',
                'Property_Aliases':
                None,
                'Sub_Type':
                'None'
            }

        if self.agreement_currency == 'ZAR':
            self.cx.params['Price Factors'][
                'InterestRate.ZAR-SWAP.OIS'] = makeflatcurve('ZAR', -15)
            self.cx.params['Price Factors'][
                'InterestRate.ZAR-SWAP.FUNDING'] = makeflatcurve('ZAR', 10)
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Collateral_Rate'] = 'ZAR-SWAP.OIS'
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Funding_Rate'] = 'ZAR-SWAP.FUNDING'
        else:
            self.cx.params['Price Factors'][
                'InterestRate.USD-LIBOR-3M.FUNDING'] = makeflatcurve(
                    'USD', 65)
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Collateral_Rate'] = 'USD-OIS'
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Collateral_Assets']['Cash_Collateral'][0][
                    'Funding_Rate'] = 'USD-LIBOR-3M.FUNDING'

    def valid(self):
        if not self.cx.deals['Deals']['Children'][0][
                'Children'] or self.cx.deals['Deals'][
                    'Children'][0]['instrument'].field.get(
                        'Collateralized', 'False') == 'False':
            return False
        else:
            return True

    def run_calc(self, calc):
        filename = 'COLLVA_' + self.params[
            'Run_Date'] + '_' + self.crb_default + '.csv'

        if os.path.isfile(os.path.join(self.outputdir, 'Greeks', filename)):
            self.logger(
                self.netting_set,
                'Warning: skipping COLLVA calc as file already exists')
        else:
            self.params['CollVA'] = {'Gradient': 'Yes'}

            # make sure the margin period of risk is 10 business days (approx 12 calendar days)
            self.cx.deals['Deals']['Children'][0]['instrument'].field[
                'Liquidation_Period'] = 12.0
            self.params['Simulation_Batches'] = 20
            self.params['Batch_Size'] = 256

            try:
                out = calc.execute(self.params)
            except Exception as e:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                traceback.print_exception(exc_type,
                                          exc_value,
                                          exc_traceback,
                                          limit=2,
                                          file=sys.stdout)

                self.logger(self.netting_set, 'Exception: ' + str(e.args))
            else:
                stats = out['Stats']
                grad_collva = calc.gradients_as_df(
                    out['Results']['grad_collva']).rename(columns={
                        'Gradient':
                        self.cx.deals['Attributes']['Reference']
                    })
                # store the CollVA as part of the stats
                out['Stats'].update({
                    'CollVA': out['Results']['collva'],
                    'Currency': self.params['Currency']
                })
                grad_collva.to_csv(
                    os.path.join(self.outputdir, 'Greeks', filename))
                self.stats.setdefault('Stats',
                                      {})[self.netting_set] = out['Stats']
                # log the netting set
                self.logger(self.netting_set, 'CollVA calc complete')
示例#10
0
def work(id, lock, queue, results, job, rundate, input_path, calendar,
         outputdir):
    def log(netting_set, msg):
        lock.acquire()
        print('JOB %s: ' % id)
        print('Netting set {0}: {1}'.format(netting_set, msg))
        lock.release()

    # set the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = str(id)
    # set the log level
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

    # now load the cuda context
    from riskflow.adaptiv import AdaptivContext

    # create the crstal context
    cx = AdaptivContext()
    # load calendars
    cx.parse_calendar_file(calendar)
    # load marketdata
    cx.parse_json(os.path.join(input_path, rundate, 'MarketData.json'))

    if os.path.isfile(
            os.path.join(input_path, rundate,
                         'CVAMarketData_Calibrated_New.json')):
        cx_new = AdaptivContext()
        cx_new.parse_json(
            os.path.join(input_path, rundate,
                         'CVAMarketData_Calibrated_New.json'))
        log("Parent", "Overriding Calibration")
        for factor in [
                x for x in cx_new.params['Price Factors'].keys()
                if x.startswith('HullWhite2FactorModelParameters')
        ]:
            # override it
            cx.params['Price Factors'][factor] = cx_new.params[
                'Price Factors'][factor]

    # log results
    logs = {}

    while True:
        # get the task
        task = queue.get()
        if task is None:
            break

        obj = globals().get(job)(cx, rundate, input_path, outputdir, task,
                                 logs, log)
        obj.perform_calc()

    # empty the queue
    queue.put(None)
    # get ready to send the results
    result = []

    # write out the logs
    if 'Stats' in logs:
        stats_file = os.path.join(
            outputdir, 'Stats',
            '{0}_Stats_{1}_JOB_{2}.csv'.format(job, rundate, id))
        pd.DataFrame(data=logs['Stats']).T.to_csv(stats_file)
        result.append(('Stats', stats_file))
    if 'CSA' in logs:
        csa_file = os.path.join(
            outputdir, 'CSA',
            '{0}_{1}_CSA_JOB_{2}.csv'.format(job, rundate, id))
        pd.DataFrame(logs['CSA']).T.to_csv(csa_file)
        result.append(('CSA', csa_file))
    results.put(result)