Exemplo n.º 1
0
def update_balance_ndf(ccy, amount_ccy, amount_pv, amount_brl, revenue_brl, side, dc):
    def incr_by(key, value):
        db_key = f'Balance/NDF/{ccy}/{key}'
        databus.increase_by_float(db_key, value)

    incr_by('TotalAmount', amount_ccy)
    incr_by('NetPV', amount_pv)
    incr_by('NetPV_BRL', amount_brl)
    incr_by('NetAmount', amount_ccy if side.lower() == 'buy' else -amount_ccy)
    incr_by('Revenue_BRL', revenue_brl)
    incr_by(f'{side}/TotalPV', amount_pv)
    incr_by(f'{side}/TotalAmount', abs(amount_ccy))

    partial_pv_key = f'Balance/NDF/{ccy}/{side}/PartialPV'
    partial_pv_list = databus.get(partial_pv_key)
    tuple_partial_pvs_max_dcs = (1, 31, 61, 91, 181, 361, 721)
    idx = bisect.bisect_right(tuple_partial_pvs_max_dcs, dc) - 1
    partial_pv_list[idx] += amount_pv
    databus.set(partial_pv_key, partial_pv_list)

    partial_amount_key = f'Balance/NDF/{ccy}/{side}/PartialAmount'
    partial_amount_list = databus.get(partial_amount_key)
    idx = bisect.bisect_right(tuple_partial_pvs_max_dcs, dc) - 1
    partial_amount_list[idx] += abs(amount_ccy)
    databus.set(partial_amount_key, partial_amount_list)
Exemplo n.º 2
0
def blotter_transactions():
    blotter_msgs = databus.get('Blotter')
    l_messages = []
    if blotter_msgs:
        for t in blotter_msgs:
            msg = databus.get('Blotter/{}'.format(t))
            l_messages.append(json.loads(msg))
        l_messages = sorted(l_messages, key=lambda x: x['quote_req_id'])
    return l_messages
Exemplo n.º 3
0
def config():
    with open(get_data_path('RobotFX_SpotConfig.json')) as json_file:
        spot_config = json.load(json_file)
        cutoff_times = spot_config['CutOffTimes']

        with open(get_data_path('RobotFX_Currencies.json')) as currencies_json_file:
            cur_data = json.load(currencies_json_file)
            for cur in cutoff_times['Primary']:
                cutoff_times['Primary'][cur]['ViewPriority'] = cur_data[cur]['ViewPriority']

    with open(get_data_path('RobotFX_NDFTimeBuckets.json')) as json_file:
        time_buckets_data = json.load(json_file)
        time_buckets = time_buckets_data['TimeBuckets']

    counterparties = []
    with open(get_data_path('RobotFX_LegalEntities.json')) as json_file:
        legal_entities_data = json.load(json_file)
        for (key, obj) in legal_entities_data.items():
            counterparties.append(
                {
                    'Id': len(counterparties) + 1,
                    'Alias': obj['Alias'],
                    'Counterparty': obj['CounterpartyName'],
                    'Cnpj': key,
                    'MarketType': obj['FXMarketType'],
                    'DefaultTransaction': obj['DefaultFXTransaction'],
                    'Products': obj['Products'],
                }
            )

    counterparties = sorted(counterparties, key=lambda cparty: cparty['Alias'])

    # groups = []
    with open(get_data_path('RobotFX_LegalEntitiesRelationships.json')) as json_file:
        groups_data = json.load(json_file)
        groups_data = groups_data.get('Groups_Spreads', {})
        spot_groups = groups_data.get('FXSPOT', {})
        ndf_groups = groups_data.get('FXNDF', {})

    spot_timeout = databus.get('TradingParameters/Engine_Global_Parameters/FXSPOT/RFQ_Timeout')
    ndf_timeout = databus.get('TradingParameters/Engine_Global_Parameters/FXNDF/RFQ_Timeout')

    json_sorted_currencies = get_currencies_sorted()
    return render_template(
        'config-main.html',
        cutoff_times=json.dumps(cutoff_times),
        time_buckets=json.dumps(time_buckets),
        counterparties=json.dumps(counterparties),
        spot_groups=json.dumps(spot_groups),
        ndf_groups=json.dumps(ndf_groups),
        currencies=json.dumps(cur_data),
        spot_timeout=json.dumps(spot_timeout),
        ndf_timeout=json.dumps(ndf_timeout),
        sorted_currencies=json_sorted_currencies,
    )
Exemplo n.º 4
0
def blotter_generic_quote(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'QUOTE'
    model['buy'] = '-' if msg.BidPx is None else msg.BidPx
    model['sell'] = '-' if msg.OfferPx is None else msg.OfferPx
    return model
Exemplo n.º 5
0
def blotter_generic_reject_response(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'REJECTED'
    model['color'] = 'red'
    model['rejected_text'] = msg.Text
    return model
Exemplo n.º 6
0
def supplier_control_limits_put():
    currencies_config = request.json['data']

    def is_brl_ok(config):
        return is_positive_number(config.get('SettlementRate', None))

    def is_ccy_ok(ccy, config):
        return (is_positive_number(config.get('SettlementRate', None))
                and is_positive_number(config.get('MaxQuantity', None))
                and is_positive_number(config.get('MarkupBUY', None), ge=True)
                and is_positive_number(config.get('MarkupSELL', None),
                                       ge=True))

    ccy_valid = False
    system_currencies = databus.get('Currencies')
    if set(system_currencies) != set(currencies_config.keys()):
        return jsonify({'status': 'error - invalid_uploaded_data'
                        })  # TODO: melhorar mensagem

    for ccy, config in currencies_config.items():
        if ccy.lower() == 'brl':
            ccy_valid = is_brl_ok(config)
        else:
            ccy_valid = is_ccy_ok(ccy, config)

        if not ccy_valid:
            return jsonify({'status': 'error - invalid_uploaded_data'})

    with open(get_data_path('RobotFX_FXSupplierControl.json'),
              'w') as json_file_out:
        json_file_out.write(json.dumps(currencies_config, indent=2))

    databus.update_from_file(get_data_path('RobotFX_FXSupplierControl.json'),
                             'FXSupplierControl')
    return jsonify({'status': 'ok'})
Exemplo n.º 7
0
def get_transaction(msg_type, msg_id):
    result = databus.get(f'Transactions/Messages/{msg_type}/{msg_id}')
    if result:
        j = json.loads(result)
        msg = messages.parse_from_json(j.get('msg'))
        return msg, j.get('details')

    return None, None
Exemplo n.º 8
0
def blotter_generic_deal(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    if msg.Type == messages.ExecReportType.ACCEPT:
        model['mtype'] = 'EXECUTING'
    else:
        model['mtype'] = 'EXP.QUOTE'
    return model
Exemplo n.º 9
0
def increase_cash_limits_spot(ccy, amount, n):
    db_key = f'CashLimits/SPOT/{ccy}/d{n}'
    if databus.get(db_key) is None:
        return False, f"Limite de caixa não definido para {ccy} D+{n}"

    databus.increase_by_float(db_key, amount)
    databus.publish('cash-limits-spot', 1)
    return True, ''
Exemplo n.º 10
0
def set_timestamp(msg_id, msg_code, value):
    if msg_code != 'Quote':
        result = databus.get(f'Transactions/Metrics/{msg_id}')
        if result is not None:
            j = json.loads(result)
        else:
            j = {'timestamps': {}}
        j['timestamps'][msg_code] = value
        pack = json.dumps(j)
        databus.update_from_dict({msg_id: pack}, 'Transactions/Metrics')
    else:  # for Quote is a list of timestamps
        result = databus.get(f'Transactions/Metrics/{msg_id}')
        j = json.loads(result)
        if 'Quote' not in j['timestamps'].keys():
            j['timestamps'][msg_code] = []
        j['timestamps'][msg_code].append(get_local_timestamp())
        pack = json.dumps(j)
        databus.update_from_dict({msg_id: pack}, 'Transactions/Metrics')

    r.publish('history', json.dumps({"info": "metrics", "publish_data": {'pack': pack, 'msg_id': msg_id}}))
Exemplo n.º 11
0
def pre_trading_balance_update():
    """
@login_required(roles=['e-sales spot'])
    atualiza o CashLimits adicionando ou removendo + dinheiro.
    """
    balance_update = json.loads(request.data)
    balance_update = balance_update.get('balance_update', None)

    if balance_update is not None:
        for ccy, limits in balance_update.items():
            for maturity, value in limits.items():
                if value is None:
                    continue

                value = float(value)
                n = int(maturity[1])

                if n not in [0, 1]:
                    continue

                if databus.get(f'CashLimits/SPOT/{ccy}/{maturity}') is None:
                    databus.set(f'CashLimits/SPOT/{ccy}/{maturity}', 0.0)

                if value > 0:
                    success, error_msg = increase_cash_limits_spot(
                        ccy, value, n)
                else:
                    success, error_msg = decrease_cash_limits_spot(ccy,
                                                                   value,
                                                                   n,
                                                                   reset=True)

                ccy_logs = databus.get(f'CashLimits/Logs/{ccy}/{maturity}')
                if isinstance(ccy_logs, list):
                    ccy_logs.append(value)
                    databus.set(f'CashLimits/Logs/{ccy}/{maturity}', ccy_logs)

                if not success:
                    return jsonify({'status': 'fail', 'reason': error_msg})

    return jsonify({'status': 'ok'})
Exemplo n.º 12
0
def decrease_cash_limits_spot(ccy, amount, n, reset=False):
    db_key = f'CashLimits/SPOT/{ccy}/d{n}'
    if databus.get(db_key) is None:
        return False, f"Limite de caixa não definido para {ccy} D+{n}"

    try:
        if not databus.decrease_if_greater_than(db_key, amount, reset):
            return False, f"Fundos insuficientes para {ccy} D+{n}"
    except RuntimeError:
        return False, "Operação inválida"

    databus.publish('cash-limits-spot', 1)
    return True, ''
Exemplo n.º 13
0
def spread_transaction_getter(is_ndf, is_group):
    basic_key = 'SpreadRegistry/' + ('NDF' if is_ndf else 'SPOT') + '/' + (
        'group' if is_group else 'counterparty')

    if databus.exists(basic_key):
        transactions = databus.get(basic_key)
        transactions = sorted(transactions,
                              key=lambda x: x['ts'],
                              reverse=True)
    else:
        transactions = []

    return json.dumps(transactions)
Exemplo n.º 14
0
def getBlotterSpotPopup():
    deal_id = request.args.get('dealid', '')
    if not deal_id:
        abort(404, description="Resource not found")

    try:
        info = json.loads(
            databus.get('Blotter/{deal_id}'.format(deal_id=deal_id)))
    except TypeError:
        abort(404, description="Resource not found")

    return render_template('blotter-spot-dealid-popup.html',
                           deal_id=json.dumps(deal_id),
                           info=info)
Exemplo n.º 15
0
def engine_control_spot():
    with open(get_data_path('RobotFX_TradingParameters.json')) as json_file:
        trading_parameters = json.load(json_file)
        engine_parameters = trading_parameters["Engine_Global_Parameters"][
            "FXSPOT"]

    with open(get_data_path('RobotFX_SpotConfig.json')) as json_file:
        spot_config = json.load(json_file)
        cutoff_times = spot_config['CutOffTimes']

    spot_timeout = databus.get(
        'TradingParameters/Engine_Global_Parameters/FXSPOT/RFQ_Timeout')

    return render_template(
        'engine-control-spot.html',
        engine_parameters=json.dumps(engine_parameters),
        cutoff_times=json.dumps(cutoff_times),
        spot_timeout=json.dumps(spot_timeout),
    )
Exemplo n.º 16
0
def update_blotter(msg):
    model = None

    if isinstance(msg, messages.QuoteRequest):
        quoterequest = msg
    else:
        quoterequest, _ = get_quoterequest_msg(msg.QuoteReqID)

    if quoterequest.SecurityType == messages.EnumSecurityType.SPOT:
        model = update_blotter_spot(msg)
        if model:
            cur = model["currency"]
            root_key = f'Balance/SPOT/{cur}/TotalAmount/'
            if model['mtype'] == "DEAL":
                buy_total = sum(float(databus.get(root_key + 'BuyD' + str(i))) for i in range(3))
                sell_total = sum(float(databus.get(root_key + 'SellD' + str(i))) for i in range(3))
                accounting_supplier_model = {
                    model['currency']: {
                        'net': buy_total - sell_total,
                        'buy_total': buy_total,
                        'buy_d0': float(databus.get(root_key + 'BuyD0')),
                        'buy_d1': float(databus.get(root_key + 'BuyD1')),
                        'buy_d2': float(databus.get(root_key + 'BuyD2')),
                        'sell_total': sell_total,
                        'sell_d0': float(databus.get(root_key + 'SellD0')),
                        'sell_d1': float(databus.get(root_key + 'SellD1')),
                        'sell_d2': float(databus.get(root_key + 'SellD2')),
                    }
                }
                accounting_supplier_model_json = json.dumps(json.dumps(accounting_supplier_model))
                r.publish('accounting_fxsupplier', accounting_supplier_model_json)
    elif quoterequest.SecurityType == messages.EnumSecurityType.NDF:
        model = update_blotter_ndf(msg)

    if model:
        model_json = json.dumps(model)
        entry = {model['quote_req_id']: model_json}
        databus.update_from_dict(entry, 'Blotter')
        r.publish('blotter', json.dumps(model_json))
        r.publish('blotter_fxsupplier', json.dumps(model_json))
Exemplo n.º 17
0
def blotter_generic_quote_request(quoterequest):
    if quoterequest.SecurityType == messages.EnumSecurityType.SPOT:
        security_type = 'FXSPOT'
    elif quoterequest.SecurityType == messages.EnumSecurityType.NDF:
        security_type = 'FXNDF'

    model = {
        'quote_req_id': quoterequest.QuoteReqID,
        'color': 'orange',
        'mtype': 'RFQ',
        'cnpj': None,
        'counterparty': quoterequest.CustomerStr,
        'client_side': quoterequest.Side,
        'security_type': security_type,
        'dealcode': quoterequest.CustomerDealCode,
        'amount': quoterequest.OrderQty,
        'symbol': quoterequest.Symbol,
        'currency': quoterequest.Currency,
        'notes': quoterequest.Text,
    }

    model['cnpj'] = quoterequest.CustomerID
    model['counterparty'] = databus.get(f'LegalEntities/{quoterequest.CustomerID}/CounterpartyName')
    return model
Exemplo n.º 18
0
def blotter_generic_quote_cancel(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'TIMEOUT'
    return model
Exemplo n.º 19
0
def check_spot_limits_initialized():
    status = databus.get('System/Status/Trading/SPOT/Initialized')
    return json.dumps(status)
Exemplo n.º 20
0
def casado_data():
    data_json = {}
    data_json['CasadoBuy'] = databus.get('FXSupplierCasado/Price')

    return jsonify(data_json)
Exemplo n.º 21
0
def supplier_data(security_type):

    data = {}
    if security_type not in ('SPOT', 'NDF'):
        raise Exception('error: security type not found!')

    user_id = session.get("user_id", None)
    role = get_user_role(user_id)
    if role == 'fx-supplier':
        quoting_not_halted = True
    elif security_type == 'SPOT':
        quoting_not_halted = databus.get('System/Status/Quoting/Spot/All')
    elif security_type == 'NDF':
        quoting_not_halted = databus.get('System/Status/Quoting/NDF/All')

    if quoting_not_halted:
        casado = databus.get('FXSupplierCasado/Price')
    else:
        casado = '-'
    data['Casado'] = {'Price': casado}
    data['CurrencyPairs'] = {}
    currency_pairs = databus.get(
        'FXSupplierData/{security}'.format(security=security_type))
    if currency_pairs is None:
        currency_pairs = {}
    for ccy_pair in currency_pairs:
        ccy = ccy_pair[0:3]
        precision = databus.get('Currencies/{ccy}/Precision'.format(ccy=ccy))
        if quoting_not_halted:
            bid = databus.get(
                'FXSupplierData/{security}/{ccy_pair}/Bid'.format(
                    security=security_type, ccy_pair=ccy_pair))
            ask = databus.get(
                'FXSupplierData/{security}/{ccy_pair}/Ask'.format(
                    security=security_type, ccy_pair=ccy_pair))

            if bid is None or ask is None:
                bid = "Fail"
                ask = "Fail"
            else:
                bid = round(bid, precision)
                ask = round(ask, precision)
        else:
            bid = '-'
            ask = '-'

        view_priority = databus.get(
            'Currencies/{ccy}/ViewPriority'.format(ccy=ccy))
        data['CurrencyPairs'][ccy_pair] = {
            'Bid': bid,
            'Ask': ask,
            'ViewPriority': view_priority
        }

    if quoting_not_halted:
        fut_usdbrl_bid = databus.get('MarketData/Futures/USDBRL/Active/Bid')
        fut_usdbrl_ask = databus.get('MarketData/Futures/USDBRL/Active/Ask')

        if fut_usdbrl_bid is None or fut_usdbrl_ask is None:
            fut_usdbrl_bid = "Fail"
            fut_usdbrl_ask = "Fail"
    else:
        fut_usdbrl_bid = "-"
        fut_usdbrl_ask = "-"

    data['Futures'] = {
        "USDBRL": {
            'Active': {
                'Bid': fut_usdbrl_bid,
                'Ask': fut_usdbrl_ask
            }
        }
    }

    return jsonify(data)
Exemplo n.º 22
0
def supplier_control_data():
    data_json = {}

    currencies = databus.get('Currencies')
    for currency in currencies:
        ccy_info = {}
        base = 'FXSupplierControl/{ccy}/'.format(ccy=currency)
        ccy_info['SettlementRate'] = databus.get(base + 'SettlementRate')

        if currency.upper() != 'BRL':
            ccy_info['SettlementRateCurveConvention'] = databus.get(
                base + 'SettlementRateCurveConvention')
            ccy_info['MaxQuantity'] = databus.get(base + 'MaxQuantity')
            ccy_info['MarkupSELL'] = databus.get(base + 'MarkupSELL')
            ccy_info['MarkupBUY'] = databus.get(base + 'MarkupBUY')

            precision = databus.get(
                'Currencies/{ccy}/Precision'.format(ccy=currency))
            value_buy = databus.get(
                'FXSupplierData/SPOT/{ccy}BRL/Bid'.format(ccy=currency))
            value_sell = databus.get(
                'FXSupplierData/SPOT/{ccy}BRL/Ask'.format(ccy=currency))

            if value_buy is None or value_sell is None:
                ccy_info['Buy'] = "Fail"
                ccy_info['Sell'] = "Fail"
            else:
                ccy_info['Buy'] = round(value_buy, precision)
                ccy_info['Sell'] = round(value_sell, precision)

            ccy_info['CashLimitsD0'] = databus.get(
                'CashLimits/SPOT/{ccy}/d0'.format(ccy=currency))
            ccy_info['CashLimitsD1'] = databus.get(
                'CashLimits/SPOT/{ccy}/d1'.format(ccy=currency))
        else:
            ccy_info['Buy'] = '-'
            ccy_info['Sell'] = '-'

        data_json[currency] = ccy_info

    return jsonify(data_json)
Exemplo n.º 23
0
def blotter_generic_neworder(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'NEW.ORDER'
    return model
Exemplo n.º 24
0
def get_transaction_status(quoterequest_id):
    return databus.get(f'Transactions/Status/{quoterequest_id}')
Exemplo n.º 25
0
def blotter_generic_reject_request(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'NOTH.DONE'
    model['rejected_text'] = msg.Text
    return model
Exemplo n.º 26
0
def get_user_role(user_id):
    user_role_databus_key = f"ActiveUsers/{user_id}/Role"
    user_role = databus.get(user_role_databus_key)
    return user_role if user_role else None
Exemplo n.º 27
0
def blotter_generic_exec_ack(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['color'] = '#49ed6d'
    model['mtype'] = 'DEAL'
    return model
Exemplo n.º 28
0
def spreads_spot_put():
    now = get_local_time()
    type_update = request.args.get('type', '').lower()
    update_group = type_update == 'group'
    key = request.args.get('key', '').upper()
    status = request.json['status']
    currency = status['currency']
    spotDay = status['spotday']
    side = status['side']
    spread = status['spread']
    if spread != '-':
        spread = int(
            Decimal(spread) *
            10_000)  # Solucao de caso de spread igual a: 12, 24 ou 48.

    basic_key = 'SpreadRegistry/SPOT/' + type_update

    if databus.exists(basic_key):
        data_list = databus.get(basic_key)
    else:
        data_list = []
    user_id = session.get("user_id", None)
    username = get_username(user_id)
    element = {
        'target': key,
        'ts': now.strftime('%Y-%m-%d %H:%M:%S'),
        'user': str(username),
        'ccy': str(currency),
        'spotday': str(spotDay),
        'side': str(side),
        'spread': str(spread),
    }

    if not update_group:
        element['counterparty'] = databus.get(
            'LegalEntities/{cnpj}/CounterpartyName'.format(cnpj=key))
        basic_group_key = 'LegalEntitiesRelationships/Groups_Spreads_'
        if databus.exists((basic_group_key +
                           'FX{type}_Memberships/{cnpj}').format(cnpj=key,
                                                                 type='SPOT')):
            element['group'] = databus.get(
                (basic_group_key + 'FX{type}_Memberships/{cnpj}').format(
                    cnpj=key, type="SPOT"))
        else:
            element['group'] = '-'

    data_list.append(element)

    databus.set(basic_key, data_list)

    manage_spreads_tables(1, is_ndf=False)

    with open(get_data_path('RobotFX_Client_Spreads.json')) as json_file:
        all_spreads = json.load(json_file)
        entity_type = 'GroupSpreads' if update_group else 'CounterpartySpreads'
        if key not in all_spreads[entity_type]:
            all_spreads[entity_type][key] = {}

        all_spreads[entity_type][key]['FXSPOT'] = request.json['spreads']

    with open(get_data_path('RobotFX_Client_Spreads.json'),
              'w') as json_file_out:
        json_file_out.write(json.dumps(all_spreads, indent=2))

    databus.update_from_file(get_data_path('RobotFX_Client_Spreads.json'),
                             'ClientSpreads')

    return jsonify({'status': 'ok'})
Exemplo n.º 29
0
def get_username(user_id):
    username_databus_key = f"ActiveUsers/{user_id}/Username"
    username = databus.get(username_databus_key)
    return username if username else None
Exemplo n.º 30
0
def blotter_generic_exec_ack_unknown(msg):
    strmodel = databus.get(f'Blotter/{msg.QuoteReqID}')
    model = json.loads(strmodel)
    model['mtype'] = 'ACK.UNKNOWN'
    return model