Пример #1
0
def compute_underlying_security(portfolios, tracks, spots, portfolio, operation, inner_security, key_date, work_date=None):
    portfolio_id = str(portfolio.id)
    inner_container = SecurityContainer.objects.get(id=inner_security)
    if not tracks.has_key(inner_security):
        track = get_main_track_content(inner_container)
        tracks[inner_security] = track
    value = get_closest_value(tracks[inner_security], operation.value_date if work_date==None else work_date)
    if value==None:
        LOGGER.error("No NAV available for " + inner_container.name + " as of " + str(from_epoch(long(key_date))))
        return None
    divisor = get_price_divisor(inner_container)
    portfolios[portfolio_id][key_date][inner_security]['price'] = value['value']
    portfolios[portfolio_id][key_date][inner_security]['price_divisor'] = divisor
    spot_pf = 1.0
    if inner_container.currency.short_name!=portfolio.currency.short_name and (not spots.has_key(inner_container.currency.short_name) or not spots[inner_container.currency.short_name].has_key(portfolio.currency.short_name)):
        spot_track = get_exchange_rate(inner_container.currency.short_name, portfolio.currency.short_name)
        if not spots.has_key(inner_container.currency.short_name):
            spots[inner_container.currency.short_name] = {}
        spots[inner_container.currency.short_name][portfolio.currency.short_name] = spot_track
    if inner_container.currency.short_name!=portfolio.currency.short_name and spots.has_key(inner_container.currency.short_name) and spots[inner_container.currency.short_name].has_key(portfolio.currency.short_name):
        value = get_closest_value(spots[inner_container.currency.short_name][portfolio.currency.short_name], operation.value_date if work_date==None else work_date)
        if value!=None:
            spot_pf = value['value']
        else:
            LOGGER.error("No SPOT available for " + inner_container.currency.short_name + '/' + portfolio.currency.short_name + " as of " + str(from_epoch(long(key_date))))
            return None
    portfolios[portfolio_id][key_date][inner_security]['price_pf'] = portfolios[portfolio_id][key_date][inner_security]['price'] * spot_pf
    portfolios[portfolio_id][key_date][inner_security]['price_pf_divisor'] = portfolios[portfolio_id][key_date][inner_security]['price'] * spot_pf / divisor
    portfolios[portfolio_id][key_date][inner_security]['spot_pf'] = spot_pf
    portfolios[portfolio_id][key_date][inner_security]['price_date'] = value['date'].strftime('%Y-%m-%d')
Пример #2
0
def create_security_credit(container, source, target, details, label, is_dividend=True):
    current_account_type = Attributes.objects.get(identifier='ACC_CURRENT', active=True)
    operation_type = Attributes.objects.get(identifier='OPE_TYPE_DIVIDEND' if is_dividend else 'OPE_TYPE_COUPON', active=True)
    
    operation = FinancialOperation()
    operation.name = ('Dividends' if operation_type.identifier=='OPE_TYPE_DIVIDEND'  else 'Coupon') + ' on security ' + target['security'].name + ' of ' + str(target['price']) + ' per share'
    operation.short_name =('Dividends' if operation_type.identifier=='OPE_TYPE_DIVIDEND'  else 'Coupon') + ' on security ' + target['security'].name
    operation.status = Attributes.objects.get(identifier='OPE_STATUS_EXECUTED', active=True) if not details.has_key('status') else details['status']
    operation.operation_type = operation_type
    operation.creation_date = details['operation_date']
    operation.operator = None
    operation.validator = None
    operation.source = get_account(container, details, current_account_type)
    operation.target = target['security']
    operation.spot = details['spot_rate']
    operation.repository = None
    
    divisor = get_price_divisor(target['security'])

    operation.quantity = target['quantity']
    operation.amount = target['quantity'] * target['price'] * details['spot_rate'] / divisor
    operation.price = target['price']
    operation.operation_date = details['trade_date']
    operation.operation_pnl = operation.amount
    operation.value_date = details['value_date']
    operation.termination_date = details['value_date']
    operation.associated_operation = None
    operation.save()
    create_expenses(operation, operation.source, details['source_expenses'])
    create_expenses(operation, operation.source, details['target_expenses'])
    return operation
Пример #3
0
def get_exchange_rate(source_currency, destination_currency):
    currency = SecurityContainer.objects.filter(name__startswith=source_currency + destination_currency)
    if currency.exists():
        currency = currency[0]
    else:
        threaded.bloomberg_data_query('NO_NEED', [source_currency + destination_currency + ' Curncy'], True)
        currency = SecurityContainer.objects.get(name__startswith=source_currency + destination_currency)
    divisor = get_price_divisor(currency)
    return get_main_track_content(currency, True, False, divisor)
Пример #4
0
def create_security_movement(container, source, target, details, label):
    current_account_type = Attributes.objects.get(identifier='ACC_CURRENT', active=True)
    security_account_type = Attributes.objects.get(identifier='ACC_SECURITY', active=True)
    
    operation = FinancialOperation()
    operation.name = label if label!=None else generate_security_movement_label(target, details)
    operation.short_name = generate_security_movement_short_label(target, details)
    operation.status = Attributes.objects.get(identifier='OPE_STATUS_EXECUTED', active=True) if not details.has_key('status') else details['status']
    operation.operation_type = generate_security_movement_operation_type(details)
    operation.creation_date = details['operation_date']
    operation.operator = None
    operation.validator = None
    operation.source = get_account(container, details, current_account_type) if details['impact_pnl'] else None
    operation.target = target['security']
    if operation.target.status.identifer!='STATUS_ACTIVE':
        # Status cannot be executed on a pending security
        operation.status = Attributes.objects.get(identifier='OPE_STATUS_PENDING', active=True) if not details.has_key('status') else details['status']
    operation.spot = details['spot_rate']
    operation.repository = get_account(container, details, security_account_type)
    operation.quantity = target['quantity']
    used_price = target['price']
    if not details['impact_pnl'] and (used_price==None or used_price==0.0):
        track = get_main_track_content(target['security'])
        value = get_closest_value(track, dt.strptime(details['trade_date'], '%Y-%m-%d'))
        if value==None:
            LOGGER.warn(target['security'].name + " - Transaction does not have a correct price but no valid price could be found.")
            used_price = 0.0
        else:
            LOGGER.warn(target['security'].name + " - Transaction does not have a correct price but a valid price could be found.")
            used_price = value['value']
    divisor = get_price_divisor(target['security'])
    operation.amount = (target['quantity'] * used_price * details['spot_rate']) / divisor
    operation.price = target['price']
    operation.operation_date = details['trade_date']
    operation.operation_pnl = 0.0
    operation.value_date = details['value_date']
    operation.termination_date = details['value_date']
    operation.associated_operation = None
    operation.save()
    if details['impact_pnl']:
        create_expenses(operation, operation.source, details['source_expenses'])
        create_expenses(operation, operation.source, details['target_expenses'])
    if details.has_key('accrued_interest'):
        if details['accrued_interest'].has_key('source') and details['accrued_interest']['source']!=None and details['accrued_interest']['source']!=0.0:
            create_accrued(operation, operation.source, details['accrued_interest']['source'])
        if details['accrued_interest'].has_key('target') and details['accrued_interest']['target']!=None and details['accrued_interest']['target']!=0.0:
            create_accrued(operation, operation.source, details['accrued_interest']['target'])
    return operation
Пример #5
0
 def compute_valuation(self, container, frequency):
     #TODO Correct the bug with frequency different of daily
     LOGGER.info("Computing valuation of " + container.name + " with frequency " + frequency.name)
     start_date = datetime.date(2014,1,1) if container.inception_date==None else container.inception_date
     today = datetime.date.today()
     valuation = {}
     all_positions = get_positions_portfolio(container)
     all_positions = all_positions['data'] if all_positions!=None else {}
     previous_key = None
     previous_date = None
     while start_date<today:
         work_date = get_work_date(start_date, frequency)
         key_date = str(epoch_time(work_date))
         period_duration = float(get_current_period_duration(work_date, frequency))
         period_position = float(get_current_date_position(start_date, frequency))
         if not valuation.has_key(key_date):
             valuation[key_date] = {'total': {'portfolio': 0.0}, 'forward': {}, 'forward_pf': 0.0,'cash': {}, 'cash_pf': 0.0, 'spot_pf': {}, 'invested': {}, 'invested_fop':{}, 'pnl': {'portfolio': 0.0}, 'fx_pnl': {}, 'movement':{'portfolio': 0.0, 'portfolio_tw': 0.0}, 'performances': {'mdietz': {'day': 0.0, 'wtd': 0.0, 'mtd': 0.0, 'qtd': 0.0, 'std': 0.0, 'ytd': 0.0, 'si': 0.0}}}
         else:
             valuation[key_date]['cash'] = {}
             valuation[key_date]['forward'] = {}
             valuation[key_date]['cash_pf'] = 0.0
             valuation[key_date]['forward_pf'] = 0.0
             valuation[key_date]['spot_pf'] = {}
             valuation[key_date]['invested'] = {}
             valuation[key_date]['total'] = {}
         for account in container.accounts.filter(~Q(account_type__identifier='ACC_SECURITY')):
             history = get_account_history(account)
             if history!=None:
                 history = history['data']
                 if not valuation[key_date]['pnl'].has_key(account.currency.short_name):
                     valuation[key_date]['pnl'][account.currency.short_name] = 0.0
                 if not valuation[key_date]['movement'].has_key(account.currency.short_name):
                     valuation[key_date]['movement'][account.currency.short_name] = 0.0
                 if history!=None:
                     value = valuation_content.get_closest_value(history, dt.combine(start_date, dt.min.time()), True)
                     if account.account_type.identifier=='ACC_CURRENT':
                         account_key = 'cash'
                     elif account.account_type.identifier=='ACC_FORWARD':
                         account_key = 'forward'
                     if not valuation[key_date][account_key].has_key(account.currency.short_name):
                         valuation[key_date][account_key][account.currency.short_name] = {'portfolio': 0.0, 'account': 0.0}
                     if not valuation[key_date]['movement'].has_key(account.currency.short_name):
                         valuation[key_date]['movement'][account.currency.short_name] = 0.0
                     if value!=None:
                         valuation[key_date][account_key][account.currency.short_name]['account'] += value['assets']
                         if not valuation[key_date]['total'].has_key(account.currency.short_name):
                             valuation[key_date]['total'][account.currency.short_name] = 0.0
                         valuation[key_date]['total'][account.currency.short_name] += value['assets']
                         valuation[key_date][account_key][account.currency.short_name]['portfolio'] += value['assets_pf']
                         valuation[key_date][account_key + '_pf'] += value['assets_pf']
                         valuation[key_date]['spot_pf'][account.currency.short_name] = value['spot_pf']
                         valuation[key_date]['movement'][account.currency.short_name] += value['mvt_no_pnl']
                         valuation[key_date]['movement']['portfolio'] += value['mvt_no_pnl_pf']
                         valuation[key_date]['movement']['portfolio_tw'] += value['mvt_no_pnl_pf'] * ((period_duration - period_position + 1.0)/period_duration)
                         valuation[key_date]['pnl'][account.currency.short_name] += value['mvt_pnl']
                         valuation[key_date]['pnl']['portfolio'] += value['mvt_pnl_pf']
         if not valuation[key_date]['invested'].has_key('portfolio'):
             valuation[key_date]['invested']['portfolio'] = 0.0
         if not valuation[key_date]['invested_fop'].has_key('portfolio'):
             valuation[key_date]['invested_fop']['portfolio'] = 0.0
         current_positions = valuation_content.get_closest_value(all_positions, work_date, True)
         if current_positions!=None:
             for position in current_positions:
                 if position not in ['increase', 'decrease', 'increase_fop', 'decrease_fop']:
                     LOGGER.info("Operation on security with id [" + str(position) + "]")
                     security = SecurityContainer.objects.get(id=position)
                     divisor = get_price_divisor(security)
                     amount = current_positions[position]['total'] * current_positions[position]['price'] / divisor
                     amount_portfolio = current_positions[position]['total'] * current_positions[position]['price_pf'] / divisor
                     if not valuation[key_date]['invested'].has_key(security.currency.short_name):
                         valuation[key_date]['invested'][security.currency.short_name] = 0.0
                     valuation[key_date]['invested'][security.currency.short_name] += amount
                     valuation[key_date]['invested']['portfolio'] += amount_portfolio
                 elif position in ['increase_fop', 'decrease_fop']:
                     valuation[key_date]['invested_fop']['portfolio'] += (current_positions[position]['portfolio'] * (1.0 if position=='increase_fop' else -1.0))
         valuation[key_date]['total']['portfolio'] = valuation[key_date]['cash_pf'] + valuation[key_date]['invested']['portfolio']
         new_work_date = get_work_date(dates.AddDay(start_date, 1), frequency)
         new_key_date = str(epoch_time(new_work_date))
         # Modified dietz
         if key_date!=new_key_date or dates.AddDay(start_date, 1)>=today:
             if previous_key!=None:
                 movement_previous_spot = 0.0
                 for key_currency in valuation[key_date]['movement'].keys():
                     if key_currency!='portfolio' and key_currency!='portfolio_tw' and valuation[key_date]['movement'][key_currency]!=0.0:
                         movement_previous_spot += valuation[key_date]['movement'][key_currency] * (valuation[previous_key]['spot_pf'][key_currency] if valuation[previous_key]['spot_pf'].has_key(key_currency) else valuation[key_date]['spot_pf'][key_currency])
             else:
                 movement_previous_spot = valuation[key_date]['movement']['portfolio']
             mdietz_up = valuation[key_date]['total']['portfolio'] - valuation[key_date]['invested_fop']['portfolio'] - (valuation[previous_key]['total']['portfolio'] if previous_key!=None else 0.0) - movement_previous_spot
             mdietz_down = (valuation[previous_key]['total']['portfolio'] if previous_key!=None else 0.0) + valuation[key_date]['movement']['portfolio_tw']
             if mdietz_down!=0.0:
                 mdietz = mdietz_up / mdietz_down
             else:
                 mdietz = 0.0
             # First is used to determine if this is the reference frequency that is computed
             first = True
             for key_perf in PERF_MAPPING[frequency.identifier]:
                 if first:
                     valuation[key_date]['performances']['mdietz'][key_perf] = mdietz * 100.0
                 else:
                     if previous_date!=None:
                         if key_perf=='si' or (previous_key!=key_date and get_work_date(previous_date, DATE_MAPPING[key_perf])==get_work_date(start_date, DATE_MAPPING[key_perf])):
                             valuation[key_date]['performances']['mdietz'][key_perf] = (((valuation[previous_key]['performances']['mdietz'][key_perf]/100.0 + 1.0) * (mdietz + 1.0)) - 1.0) * 100.0
                         elif get_work_date(previous_date, DATE_MAPPING[key_perf])!=get_work_date(start_date, DATE_MAPPING[key_perf]):
                             valuation[key_date]['performances']['mdietz'][key_perf] = mdietz * 100.0
                     else:
                         valuation[key_date]['performances']['mdietz'][key_perf] = mdietz * 100.0
                 first = False
         if key_date!=new_key_date:
             previous_key = key_date
             previous_date = start_date
         start_date = dates.AddDay(start_date, 1)
     set_portfolios_valuation({str(container.id): valuation})
     for wrk_frequency in DATE_MAPPING.values():
         self.generate_tracks(container, wrk_frequency, valuation)