Example #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')
Example #2
0
def compute_account_details(portfolio, operation, spots, accounts_history, current_account_key,
                            previous_date, key_date, is_source, target_used):
    if not accounts_history.has_key(current_account_key):
        accounts_history[current_account_key] = {}
    if previous_date.has_key(current_account_key):
        accounts_history[current_account_key][key_date] = copy.deepcopy(accounts_history[current_account_key][previous_date[current_account_key]])
        if key_date!=previous_date[current_account_key]:
            accounts_history[current_account_key][key_date]['fx_pnl'] = 0.0
            accounts_history[current_account_key][key_date]['mvt_pnl'] = 0.0
            accounts_history[current_account_key][key_date]['mvt_no_pnl'] = 0.0
            accounts_history[current_account_key][key_date]['mvt_pnl_pf'] = 0.0
            accounts_history[current_account_key][key_date]['mvt_no_pnl_pf'] = 0.0
    else:
        accounts_history[current_account_key][key_date] = {'assets': 0.0, 'assets_pf': 0.0,'mvt_pnl': 0.0, 'mvt_no_pnl': 0.0, 'mvt_pnl_pf': 0.0, 'mvt_no_pnl_pf': 0.0}
    spot_pf = 1.0
    if is_source:
        wrk_currency = operation.source.currency.short_name
    else:
        wrk_currency = operation.target.currency.short_name
    if wrk_currency!=portfolio.currency.short_name and not spots.has_key(wrk_currency):
        spot_track = get_exchange_rate(wrk_currency, portfolio.currency.short_name)
        if not spots.has_key(wrk_currency):
            spots[wrk_currency] = {}
        spots[wrk_currency][portfolio.currency.short_name] = spot_track
    if wrk_currency!=portfolio.currency.short_name and spots.has_key(wrk_currency) and spots[wrk_currency].has_key(portfolio.currency.short_name):
        value = get_closest_value(spots[wrk_currency][portfolio.currency.short_name], operation.value_date)
        if value!=None:
            spot_pf = value['value']
    if is_source:
        multiplier = -1.0 if target_used or operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else 1.0
    else:
        multiplier = operation.spot if operation.spot!=None else 1.0
    computed_amount = operation.amount * multiplier
    accounts_history[current_account_key][key_date]['assets'] += computed_amount
    accounts_history[current_account_key][key_date]['assets_pf'] = accounts_history[current_account_key][key_date]['assets'] * spot_pf
    accounts_history[current_account_key][key_date]['spot_pf'] = spot_pf
    if operation.operation_type.identifier not in ['OPE_TYPE_BUY', 'OPE_TYPE_SELL', 'OPE_TYPE_BUY_FOP', 'OPE_TYPE_SELL_FOP']:
        operation.source = get_effective_instance(operation.source)
        operation.target = get_effective_instance(operation.target)
        if (operation.source==None or (operation.source.type.identifier=='CONT_ACCOUNT' and not operation.source.account_type.identifier=='ACC_FORWARD')) and (operation.target==None or (operation.target.type.identifier=='CONT_ACCOUNT' and not operation.target.account_type.identifier=='ACC_FORWARD')):
            accounts_history[current_account_key][key_date]['mvt_pnl' if operation.operation_type.identifier in ['OPE_TYPE_FEES','OPE_TYPE_ACCRUED_PAYMENT','OPE_TYPE_COUPON', 'OPE_TYPE_DIVIDEND'] else 'mvt_no_pnl'] += computed_amount
            accounts_history[current_account_key][key_date]['mvt_pnl_pf' if operation.operation_type.identifier in ['OPE_TYPE_FEES','OPE_TYPE_ACCRUED_PAYMENT','OPE_TYPE_COUPON', 'OPE_TYPE_DIVIDEND'] else 'mvt_no_pnl_pf'] += computed_amount * spot_pf
    previous_date[current_account_key] = key_date
    previous_date[current_account_key] = key_date
Example #3
0
def compute_positions(container=None):
    LOGGER.info("Start computing securities positions")
    if container==None:
        all_operations = FinancialOperation.objects.filter(operation_type__identifier__in=['OPE_TYPE_BUY','OPE_TYPE_SELL','OPE_TYPE_BUY_FOP','OPE_TYPE_SELL_FOP']).order_by('value_date')
    else:
        accounts = container.accounts.all()
        accounts_ids = [account.id for account in accounts]
        all_operations = FinancialOperation.objects.filter(Q(repository__id__in=accounts_ids) | Q(source__id__in=accounts_ids) | Q(target__id__in=accounts_ids), operation_type__identifier__in=['OPE_TYPE_BUY','OPE_TYPE_SELL','OPE_TYPE_BUY_FOP','OPE_TYPE_SELL_FOP']).order_by('value_date')
        
    tracks = {}
    spots = {}
    
    portfolios = {}
    securities = {}
    previous_date = {}
    for operation in all_operations:
        LOGGER.info(operation.name)
        portfolio = PortfolioContainer.objects.filter(accounts__id=operation.repository.id)
        if portfolio.exists():
            portfolio = portfolio[0]
        else:
            LOGGER.error("No portfolio associated to account")
            continue
        key_date = str(epoch_time(operation.value_date))
        security_id = str(operation.target.id)
        
        portfolio_id = str(portfolio.id)
        if not securities.has_key(security_id):
            securities[security_id] = {}
        if not portfolios.has_key(portfolio_id):
            portfolios[portfolio_id] = {}
        if previous_date.has_key(security_id):
            securities[security_id][key_date] = copy.deepcopy(securities[security_id][previous_date[security_id]])
        if not securities[security_id].has_key(key_date):
            securities[security_id][key_date] = {'total': 0.0, 'name': operation.target.short_name, 'id': operation.target.id, 'type': operation.target.type.identifier}
        if not portfolios[portfolio_id].has_key(key_date):
            portfolios[portfolio_id][key_date] = {}
        if not securities[security_id][key_date].has_key(portfolio_id):
            securities[security_id][key_date][portfolio_id] = 0.0
        securities[security_id][key_date][portfolio_id] = securities[security_id][key_date][portfolio_id] + (operation.quantity * (1.0 if operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else -1.0))
        securities[security_id][key_date]['total'] = securities[security_id][key_date]['total'] + (operation.quantity * (1.0 if operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else -1.0))
        if previous_date.has_key(portfolio_id):
            portfolios[portfolio_id][key_date] = copy.deepcopy(portfolios[portfolio_id][previous_date[portfolio_id]])
            if previous_date[portfolio_id]!=key_date:
                if portfolios[portfolio_id][key_date].has_key('increase'):
                    del portfolios[portfolio_id][key_date]['increase']
                if portfolios[portfolio_id][key_date].has_key('decrease'):
                    del portfolios[portfolio_id][key_date]['decrease']
                if portfolios[portfolio_id][key_date].has_key('increase_fop'):
                    del portfolios[portfolio_id][key_date]['increase_fop']
                if portfolios[portfolio_id][key_date].has_key('decrease_fop'):
                    del portfolios[portfolio_id][key_date]['decrease_fop']
        if not portfolios[portfolio_id][key_date].has_key(security_id):
            portfolios[portfolio_id][key_date][security_id] = {'total': 0.0, 'name': operation.target.short_name, 'id': operation.target.id, 'type': operation.target.type.identifier, 'price': 0.0, 'price_pf': 0.0, 'price_date': None, 'buy_price': 0.0, 'buy_spot': 1.0}
        if not portfolios[portfolio_id][key_date].has_key('increase'):
            portfolios[portfolio_id][key_date]['increase'] = {'portfolio': 0.0}
        if not portfolios[portfolio_id][key_date].has_key('decrease'):
            portfolios[portfolio_id][key_date]['decrease'] = {'portfolio': 0.0}
        if not portfolios[portfolio_id][key_date].has_key('increase_fop'):
            portfolios[portfolio_id][key_date]['increase_fop'] = {'portfolio': 0.0}
        if not portfolios[portfolio_id][key_date].has_key('decrease_fop'):
            portfolios[portfolio_id][key_date]['decrease_fop'] = {'portfolio': 0.0}
        computed_amount = operation.quantity * (1.0 if operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else -1.0)
        if (portfolios[portfolio_id][key_date][security_id]['total'] + computed_amount)!=0.0:
            portfolios[portfolio_id][key_date][security_id]['buy_price'] = computed_amount * (operation.price if operation.price!=None else 0.0) + portfolios[portfolio_id][key_date][security_id]['buy_price'] * portfolios[portfolio_id][key_date][security_id]['total']
            portfolios[portfolio_id][key_date][security_id]['buy_price'] = portfolios[portfolio_id][key_date][security_id]['buy_price']/(portfolios[portfolio_id][key_date][security_id]['total'] + computed_amount)
            portfolios[portfolio_id][key_date][security_id]['buy_spot'] = operation.spot if operation.spot!=None else 1.0
            
        portfolios[portfolio_id][key_date][security_id]['total'] += computed_amount
        
        portfolio_movement = portfolios[portfolio_id][key_date]['increase' if operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else 'decrease']
        portfolio_movement_fop = portfolios[portfolio_id][key_date]['increase_fop' if operation.operation_type.identifier in ['OPE_TYPE_BUY', 'OPE_TYPE_BUY_FOP'] else 'decrease_fop']
        if not portfolio_movement.has_key(operation.target.currency.short_name):
            portfolio_movement[operation.target.currency.short_name] = 0.0
        if not portfolio_movement_fop.has_key(operation.target.currency.short_name):
            portfolio_movement_fop[operation.target.currency.short_name] = 0.0
        spot_pf = 1.0
        if operation.target.currency.short_name!=portfolio.currency.short_name and (not spots.has_key(operation.target.currency.short_name) or not spots[operation.target.currency.short_name].has_key(portfolio.currency.short_name)):
            spot_track = get_exchange_rate(operation.target.currency.short_name, portfolio.currency.short_name)
            if not spots.has_key(operation.target.currency.short_name):
                spots[operation.target.currency.short_name] = {}
            spots[operation.target.currency.short_name][portfolio.currency.short_name] = spot_track
        if operation.target.currency.short_name!=portfolio.currency.short_name and spots.has_key(operation.target.currency.short_name) and spots[operation.target.currency.short_name].has_key(portfolio.currency.short_name):
            value = get_closest_value(spots[operation.target.currency.short_name][portfolio.currency.short_name], operation.value_date)
            if value!=None:
                spot_pf = value['value']
        portfolios[portfolio_id][key_date][security_id]['buy_spot'] = spot_pf
        portfolio_movement[operation.target.currency.short_name] += operation.amount
        portfolio_movement['portfolio'] += operation.amount * spot_pf
        portfolio_movement_fop[operation.target.currency.short_name] += operation.amount if operation.operation_type.identifier in ['OPE_TYPE_SELL_FOP', 'OPE_TYPE_BUY_FOP'] else 0.0
        portfolio_movement_fop['portfolio'] += (operation.amount if operation.operation_type.identifier in ['OPE_TYPE_SELL_FOP', 'OPE_TYPE_BUY_FOP'] else 0.0) * spot_pf
        for inner_security in portfolios[portfolio_id][key_date].keys():
            if inner_security not in ['increase', 'decrease', 'increase_fop', 'decrease_fop']:
                compute_underlying_security(portfolios, tracks, spots, portfolio, operation, inner_security, key_date)
        previous_date[portfolio_id] = key_date
        previous_date[security_id] = key_date
    LOGGER.info("Completing securities positions")
    # Complete
    for portfolio_id in portfolios:
        movements = sorted(portfolios[portfolio_id].keys(), reverse=True)
        portfolio = PortfolioContainer.objects.get(id=portfolio_id)
        start_date = portfolio.inception_date
        if start_date==None:
            start_date = datetime.date(2014,1,1)
        today = datetime.date.today()
        while start_date<today:
            work_date = dt.combine(start_date, dt.min.time())
            key_date = str(epoch_time(work_date))
            for position_date in movements:
                if key_date>=position_date:
                    break
                position_date = None
            if position_date!=None and key_date!=position_date:
                portfolios[portfolio_id][key_date] = copy.deepcopy(portfolios[portfolio_id][position_date])
                if portfolios[portfolio_id][key_date].has_key('increase'):
                    del portfolios[portfolio_id][key_date]['increase']
                if portfolios[portfolio_id][key_date].has_key('decrease'):
                    del portfolios[portfolio_id][key_date]['decrease']
                if portfolios[portfolio_id][key_date].has_key('increase_fop'):
                    del portfolios[portfolio_id][key_date]['increase_fop']
                if portfolios[portfolio_id][key_date].has_key('decrease_fop'):
                    del portfolios[portfolio_id][key_date]['decrease_fop']
                for inner_security in portfolios[portfolio_id][key_date].keys():
                    if portfolios[portfolio_id][key_date][inner_security]['total']!=0.0:
                        compute_underlying_security(portfolios, tracks, spots, portfolio, operation, inner_security, key_date, work_date)
                    else:
                        del portfolios[portfolio_id][key_date][inner_security]
            start_date = dates.AddDay(start_date, 1)
            
    LOGGER.info("Securities positions computed")
    set_positions_portfolios(portfolios)
    LOGGER.info("Securities positions (portfolio view) stored")
    set_positions_securities(securities)
    LOGGER.info("Securities positions (securities view) stored")
Example #4
0
def compute_accounts(container=None):
    LOGGER.info("Start computing accounts positions")
    spots = {}
    if container==None:
        all_operations = FinancialOperation.objects.filter(~Q(operation_type__identifier__in=['OPE_TYPE_BUY_FOP', 'OPE_TYPE_SELL_FOP']), Q(status__identifier__in=['OPE_STATUS_EXECUTED','OPE_STATUS_CONFIRMED'])).order_by('value_date')
    else:
        accounts = container.accounts.all()
        accounts_ids = [account.id for account in accounts]
        all_operations = FinancialOperation.objects.filter(~Q(operation_type__identifier__in=['OPE_TYPE_BUY_FOP', 'OPE_TYPE_SELL_FOP']), Q(repository__id__in=accounts_ids) | Q(source__id__in=accounts_ids) | Q(target__id__in=accounts_ids), Q(status__identifier__in=['OPE_STATUS_EXECUTED','OPE_STATUS_CONFIRMED'])).order_by('value_date')
    accounts_history = {}
    previous_date = {}
    for operation in all_operations:
        target_account_used = False
        source_account_used = True
        try:
            portfolio = PortfolioContainer.objects.filter(accounts__id=operation.source.id)
            source_key = str(operation.source.id)
        except:
            source_account_used = False
            portfolio = PortfolioContainer.objects.filter(accounts__id=operation.target.id)
        if portfolio.exists():
            portfolio = portfolio[0]
           
            key_date = str(epoch_time(operation.value_date))
            if operation.target!=None and operation.operation_type.identifier not in ['OPE_TYPE_BUY', 'OPE_TYPE_SELL', 'OPE_TYPE_BUY_FOP', 'OPE_TYPE_SELL_FOP', 'OPE_TYPE_DIVIDEND', 'OPE_TYPE_COUPON']:
                target_key = str(operation.target.id)
                if not accounts_history.has_key(target_key):
                    accounts_history[target_key] = {}
                target_account_used = True
                
            if source_account_used:
                compute_account_details(portfolio, operation, spots, accounts_history, source_key, previous_date, key_date, True, target_account_used)
                
            if target_account_used:
                compute_account_details(portfolio, operation, spots, accounts_history, target_key, previous_date, key_date, False, target_account_used)
        else:
            LOGGER.error("No portfolio associated to account")
            continue
    LOGGER.info("Completing accounts positions")
    # Complete
    for account_id in accounts_history.keys():
        portfolio = PortfolioContainer.objects.filter(accounts__id=account_id)
        account = AccountContainer.objects.get(id=account_id)
        portfolio = portfolio[0]
        
        start_date = portfolio.inception_date
        if start_date==None:
            start_date = datetime.date(2014,1,1)
        today = datetime.date.today()
        
        movements = sorted(accounts_history[account_id].keys(), reverse=True)
        while start_date<today:
            work_date = dt.combine(start_date, dt.min.time())
            key_date = str(epoch_time(work_date))
            for account_date in movements:
                if key_date>=account_date:
                    break
                account_date = None
            if account_date!=None and key_date!=account_date:
                spot_pf = 1.0
                wrk_currency = account.currency.short_name
                if wrk_currency!=portfolio.currency.short_name and not spots.has_key(wrk_currency):
                    spot_track = get_exchange_rate(wrk_currency, portfolio.currency.short_name)
                    if not spots.has_key(wrk_currency):
                        spots[wrk_currency] = {}
                    spots[wrk_currency][portfolio.currency.short_name] = spot_track
                if wrk_currency!=portfolio.currency.short_name and spots.has_key(wrk_currency) and spots[wrk_currency].has_key(portfolio.currency.short_name):
                    value = get_closest_value(spots[wrk_currency][portfolio.currency.short_name], work_date)
                    if value!=None:
                        spot_pf = value['value']
                accounts_history[account_id][key_date] = copy.deepcopy(accounts_history[account_id][account_date])
                accounts_history[account_id][key_date]['assets_pf'] = accounts_history[account_id][key_date]['assets'] * spot_pf
                accounts_history[account_id][key_date]['mvt_no_pnl_pf'] = 0.0
                accounts_history[account_id][key_date]['mvt_pnl_pf'] = 0.0
                accounts_history[account_id][key_date]['mvt_no_pnl'] = 0.0
                accounts_history[account_id][key_date]['mvt_pnl'] = 0.0
                accounts_history[account_id][key_date]['spot_pf'] = spot_pf
            start_date = dates.AddDay(start_date, 1)
    LOGGER.info("Accounts positions computed")
    set_accounts_history(accounts_history)
    LOGGER.info("Accounts positions stored")