예제 #1
0
 def update_from_transactions(self, transactions):
     for txn in transactions:
         company = self.get(txn["ticker"])
         should_update = False
         if "currency" not in company or (
                 not isinstance(company["currency"], str)
                 and math.isnan(company["currency"])):
             country = company["country"] if company[
                 "country"] != "USA" else "United States"
             company["currency"] = ccy.countryccy(
                 pycountry.countries.get(name=country).alpha_2.lower())
             should_update = True
         if "cagr_3" not in company or np.isnan(company["cagr_3"]):
             div_info = Series(compute_dividends(company))
             company = {**company, **div_info}
             should_update = True
         if company["ticker"] in self.__dividend_calendar.index:
             company["stats"]["ex-dividend_date"] = datetime.strptime(
                 self.__dividend_calendar.loc[company["ticker"]]["date"],
                 "%Y-%m-%d")
             should_update = True
         if should_update:
             self.update_db_company(company)
         company["stats"] = dict(
             (k.replace(" ", "_"), v) if isinstance(k, str) else (k, v)
             for k, v in company["stats"].items())
예제 #2
0
 def nereid_currency(self):
     """Return a browse record for the currency."""
     currency_code = ccy.countryccy(self.nereid_language.code[-2:])
     for currency in self.nereid_website.currencies:
         if currency.code == currency_code:
             return currency
     raise RuntimeError("Currency %s is not valid" % currency_code)
예제 #3
0
def main():
    geolocator = Nominatim(user_agent="cityinfogather")
    tf = TimezoneFinder()
    city_name = input('What city are you traveling to: ').strip().capitalize().replace(' ', '+')
    country_name = input('What country are you traveling to: ').strip().capitalize()
    try:
        country = pycountry.countries.get(name = country_name)
        loc = geolocator.geocode(city_name+','+ country_name)
        latitude = loc.latitude
        longitude = loc.longitude
        timezone = tf.timezone_at(lng=longitude, lat=latitude)
        current_time = time(timezone)
        current_time = current_time.strftime('%Y:%m:%d %H:%M:%S')
    except:
        current_time = "Not Available :("
    try:
        country_currency = ccy.countryccy(country.alpha_2)
        exchangerate = exchangerates(country_currency)
    except:
        exchangerate = "Not Available :("
   
    temperature, feels_like = weather(city_name)

    print([exchangerate, temperature, feels_like, current_time])
    return exchangerate, temperature, feels_like, current_time
예제 #4
0
 def get_currency_by_living_place(self):
     """
     повертає курс по валюті країни з якої робиться запрос
     """
     current_country = geocoder.ip('me').country
     currency_code_of_current_country = ccy.countryccy(current_country)
     return self.get_all_rate_by_country_code(currency_code_of_current_country)
예제 #5
0
 def __init__(self, country_code='fr', cross='usd', conv=None):
     self.cross = cross
     self.ccy_code = ccy.countryccy(country_code)
     self.money = ccy.currency(self.ccy_code)
     self.engine = converter.Converter(1, self.money.code, cross)
     if conv is None:
         locale.setlocale(locale.LC_ALL, '')
         conv = locale.localeconv()
     self.conv = conv
     self.symbol = locale.nl_langinfo(locale.CRNCYSTR)[1:]
예제 #6
0
 def __init__(self, country_code='fr', cross='usd', conv=None):
     self.cross = cross
     self.ccy_code = ccy.countryccy(country_code)
     self.money = ccy.currency(self.ccy_code)
     self.engine = converter.Converter(1, self.money.code, cross)
     if conv is None:
         locale.setlocale(locale.LC_ALL, '')
         conv = locale.localeconv()
     self.conv = conv
     self.symbol = locale.nl_langinfo(locale.CRNCYSTR)[1:]
예제 #7
0
def Currency_API(location):
    # No API Key required.
    # Retrives the country code from the yelp data
    # Using the ccy module to conver the country code to a currency code.
    country_currency = ccy.countryccy(location.country_code)
    # Make a request
    reponse = requests.get('https://api.exchangeratesapi.io/latest?base=USD')
    business_data = reponse.json()
    country_exchange_rate = (business_data['rates'][country_currency])
    currency_data = Currency(location.country,country_currency, country_exchange_rate)
    return currency_data
def Currency_API(country):
    # No API Key required.
    # Retrives the country code from the yelp data
    country = country[0][2]
    # Using the ccy module to conver the country code to a currency code.
    country_currency = ccy.countryccy(country)
    # Make a request
    reponse = requests.get('https://api.exchangeratesapi.io/latest?base=USD')
    business_data = reponse.json()
    country_exchange_rate = (business_data['rates'][country_currency])
    return (f' {country_exchange_rate} {country_currency}'.format(
        country_exchange_rate, country_currency))
예제 #9
0
def import_portfolio():
    start_time = time.time()
    user = DegiroUser.create_from_db(mongo.db.users, session["USER"], encryptor)
    degiro = Degiro(user=None, data=None, session_id=user.session_id, account_id=user.account_id)
    try:
        degiro.get_client_config()
        degiro.get_degiro_config()
        degiro.get_data()
    except ConnectionError as err:
        session.clear()
        return redirect(url_for('login', error_login="******"))
    product_ids = [position["id"] for position in degiro.data["portfolio"]["value"] if position["id"].isdigit()]
    products = degiro.get_products_by_ids(product_ids)
    movements = degiro.get_account_overview("01/01/1970", datetime.now().strftime("%d/%m/%Y"))

    print("Degiro total request time --- %s seconds ---" % (time.time() - start_time))
    names = tickers["Name"].tolist()
    names = [str(name).lower() for name in names]
    modified_tickers = tickers["Ticker"].tolist()
    modified_tickers = [ticker.split('.')[0] for ticker in modified_tickers]
    for movement in movements:
        ticker = products[str(movement["productId"])]["symbol"]
        currency = products[str(movement["productId"])]["currency"]
        name = products[str(movement["productId"])]["name"].lower()
        indexes = [index for index in range(len(modified_tickers)) if modified_tickers[index] == ticker]
        if len(indexes) > 0:
            for index in indexes:
                country = tickers["Country"][index]
                country = pycountry.countries.get(
                    name=country if country != "USA" else "United States")
                company_currency = ccy.countryccy(country.alpha_2)
                company_name = names[index]
                similarity_index = SequenceMatcher(None, name, company_name).ratio()
                if similarity_index > 0.5 and currency == company_currency:
                    movement["ticker"] = tickers["Ticker"].tolist()[index]
                    movement["name"] = tickers["Name"].tolist()[index]
        movement["date"] = movement["date"].strftime("%Y-%m-%d")
    portfolio = {"email": session["USER"], "name": "Degiro", "transactions": [], "total": 0, "dividend_history": {},
                 "currency": "EUR", "id_txn": 0, "history": {}, "current": 0,
                 "summary": {}, "stats": {}, "last_update": datetime.now()}
    mongo.db.portfolio.insert_one(portfolio)
    portfolio = Portfolio.retrieve_from_database(mongo.db.portfolio, session["USER"], "Degiro")
    companies_cache.update_from_transactions(movements)

    history_cache.update_from_transactions(movements, companies_cache, portfolio.currency)
    for movement in movements:
        portfolio.add_transaction(movement, history_cache, companies_cache)
    update_portfolio(portfolio)
    return redirect(url_for("show_portfolio_manager"))
예제 #10
0
    def get_fees(country_iso):
        try:
            if country_iso is None:
                query = {}
            else:
                query = {"country": country_iso}
            data = FeesService.connect_to_fees_database().find(query, {"_id": 0, })
            fees = dumps(data, sort_keys=True, indent=4, separators=(',', ': '))
            fees = json.loads(fees)

            for x in fees:
                x['currency'] = ccy.countryccy(x['country'])

            fees = dumps(fees, sort_keys=True, indent=4, separators=(',', ': '))
            return Response(response=fees, status=201, mimetype='application/json')
        except Exception as e:
            return FeesService.log_and_return_error_response(e)
예제 #11
0
    def add_transaction(self, data, cache, companies_cache):
        self.index_transaction += 1
        transaction = dict()
        transaction["id"] = self.index_transaction
        transaction["shares"] = int(data["shares"])
        transaction["price_COS"] = float(data["price_COS"])
        transaction["price"] = float(data["price"])
        transaction["fees"] = float(data["fees"])
        transaction["total"] = data["price"] * data["shares"]
        transaction["date"] = data["date"]
        transaction["ticker"] = data["ticker"]
        transaction["name"] = data["name"]

        self.transactions.append(transaction)
        self.total += transaction["total"]
        company = companies_cache.get(transaction["ticker"])
        country = pycountry.countries.get(
            name=company["country"]
            if company["country"] != "USA" else "United States")
        company["currency"] = ccy.countryccy(country.alpha_2)
        txn_history = compute_history(cache, self.currency, transaction,
                                      Currency(company["currency"]),
                                      company["country"])
        ref_hist = DataFrame() if self.history.empty else self.history[[
            "S&P500", "Amount", "Net_Dividends", "Dividends"
        ]]
        if not ref_hist.empty:
            ref_hist = ref_hist.rename(columns={"S&P500": "Close"})
        hist = DataFrame() if self.history.empty else self.history.drop(
            "S&P500", axis=1)
        hist = add_txn_hist(hist, txn_history)
        temp_txn = transaction.copy()
        ref_txn_hist = get_reference_history(self.currency, cache, temp_txn)
        ref_hist = add_txn_hist(ref_hist, ref_txn_hist)
        conversion_rate = get_current_conversion_rate(
            Currency(company["currency"]), self.currency, cache)
        c_div = self.get_current_dividend(company, conversion_rate,
                                          temp_txn["shares"])
        self.add_txn_to_positions(c_div, company, transaction, txn_history,
                                  cache)
        if self.transactions:
            hist["S&P500"] = ref_hist["Close"]
        self.compute_stats(hist, companies_cache, cache)
예제 #12
0
def main(city, country):
    geolocator = Nominatim(user_agent="cityinfogather")
    tf = TimezoneFinder()
    city_name = city.strip().capitalize().replace(' ', '+')
    country_name = country.strip().capitalize()
    try:
        country = pycountry.countries.get(name=country_name)
        loc = geolocator.geocode(city_name+',' + country_name)
        latitude = loc.latitude
        longitude = loc.longitude
        timezone = tf.timezone_at(lng=longitude, lat=latitude)
        current_time = time(timezone)
        current_time = current_time.strftime('%Y:%m:%d %H:%M:%S')
    except:
        current_time = "Sorry, the Current Time is Not Available :("
    try:
        country_currency = ccy.countryccy(country.alpha_2)
        exchangerate = exchangerates(country_currency)
    except:
        exchangerate = "Sorry, the Exchange Rate is Currently Not Available :("

    temperature, feels_like = weather(city_name)

    return exchangerate, temperature, feels_like, current_time
예제 #13
0
def uplaodCheckout():

    global currency
    countrycode = 'NL'

    if ('country' in request.args.keys()):
        countrycode = pycountry.countries.search_fuzzy(
            request.args.get('country'))[0].alpha_2
        currency = ccy.countryccy(countrycode)

    body = {
        "merchantAccount": config.MERCHANT_ACCOUNT,
        "countryCode": countrycode,
        "amount": {
            "currency": currency,
            "value": 1000
        },
        "channel": "Web"
    }
    resp = makeCall('paymentMethods', json.dumps(body))
    print(resp.json())
    return render_template("app.html",
                           payments=resp.text,
                           clientKey=config.CLIENT_KEY)
예제 #14
0
파일: ccytests.py 프로젝트: Zibbo/ccy
 def test_eurozone(self):
     self.assertEqual(len(eurozone), 18)
     for c in eurozone:
         self.assertEqual(countryccy(c), 'EUR')
예제 #15
0
from tkinter import *
import ccy
from tools import *
from exchange import Exchange

root = root_in_center(450, 350)
exchange = Exchange()

search_string = [
    f'{country}({country_code}): {ccy.countryccy(country_code)}'  # список країн, кодів країн,
    for country_code, country in
    ccy.countries().items()  # та їхніх кодів валют
    if ccy.countryccy(country_code)
]  # по яким буде здійснюватись
# пошук

se = SearchEntry(root, search_string, width=30, font=('Times', 14, 'normal'))
se.focus_set()

rate_board = Frame(root)

scroll_bar = Scrollbar(rate_board)

currency_lst = Listbox(rate_board,
                       width=30,
                       height=14,
                       yscrollcommand=scroll_bar.set)

scroll_bar.configure(command=currency_lst.yview)

currency_lst.insert(END, 'Currency' + ' ' * 33 + 'Cost')
def format_currency_filter(amount):
    currency_code = ccy.countryccy(request.accept_languages.best[-2:]) or 'USD'
    return '{0} {1}'.format(currency_code, amount)
예제 #17
0
파일: test_ccy.py 프로젝트: alexanu/ccy
def test_eurozone():
    assert len(eurozone) == 19
    for c in eurozone:
        assert countryccy(c) == 'EUR'
예제 #18
0
    def process_portfolio(self, cache, cache_companies, refresh=False):
        hist = DataFrame()
        ref_hist = DataFrame()

        self.positions = dict()
        self.stats = {
            "div_rate": 0,
            "net_div_rate": 0,
            "cagr1": 0,
            "cagr3": 0,
            "cagr5": 0,
            "payout_ratio": 0,
            "years_of_growth": 0
        }
        self.dividend_transactions = DataFrame()
        for txn in self.transactions:
            company = cache_companies.get(txn["ticker"])
            temp_txn = txn.copy()
            if refresh:
                date = datetime.strptime(temp_txn["date"], "%Y-%m-%d")
                new_date = datetime.today() - timedelta(days=1)
                temp_txn["date"] = datetime.strftime(
                    new_date if date < new_date else date, "%Y-%m-%d")
            current_time = datetime.now()
            if current_time.weekday() > 4:
                temp_txn["date"] = datetime.strftime(
                    current_time.date() -
                    timedelta(days=current_time.weekday()), "%Y-%m-%d")
            country = pycountry.countries.get(
                name=company["country"]
                if company["country"] != "USA" else "United States")
            company["currency"] = ccy.countryccy(country.alpha_2)

            txn_hist = compute_history(cache, self.currency, temp_txn,
                                       Currency(company["currency"]),
                                       company["country"])
            dividends = txn_hist.loc[txn_hist["Dividends"] > 0, "Dividends"]
            name = [txn["ticker"]] * len(dividends)
            df = {
                "Date": dividends.index,
                "Dividends": dividends.values,
                "Tickers": name
            }
            dividends = DataFrame(df)
            dividends.set_index("Date", inplace=True)
            if self.dividend_transactions.empty:
                self.dividend_transactions = dividends
            else:
                self.dividend_transactions = self.dividend_transactions.append(
                    dividends)
            hist = add_txn_hist(hist, txn_hist)
            ref_txn_hist = get_reference_history(self.currency, cache,
                                                 temp_txn)
            ref_hist = add_txn_hist(ref_hist, ref_txn_hist)
            conversion_rate = get_current_conversion_rate(
                Currency(company["currency"]), self.currency, cache)
            c_div = self.get_current_dividend(company, conversion_rate,
                                              temp_txn["shares"])
            self.add_txn_to_stats(c_div, company, temp_txn)
            self.add_txn_to_positions(c_div, company, temp_txn, txn_hist,
                                      cache)
        if self.transactions:
            hist["S&P500"] = ref_hist["Close"]
        self.compute_stats(hist, cache_companies, cache)
예제 #19
0
파일: __init__.py 프로젝트: plutoese/mars
def format_currency_filter(amount):
    currency_code = ccy.countryccy(request.accept_languages.best[-2:])
    return '{0} {1}'.format(currency_code, amount)
예제 #20
0
파일: test_ccy.py 프로젝트: alexanu/ccy
def test_countryccy():
    assert 'AUD' == countryccy('au')
    assert 'EUR' == countryccy('eu')
예제 #21
0
파일: ccytests.py 프로젝트: glencoates/ccy
 def testCountryCcy(self):
     self.assertEqual("AUD", countryccy("au"))
     self.assertEqual("EUR", countryccy("eu"))
예제 #22
0
            )
        else:
            try:
                import geoip
            except ImportError:
                logging.warning(
                    "Python-package 'pygeoip' is not installed. Currency lookup-by-country will not be available."
                )
            else:
                try:
                    # TODO: Reasonably cache this
                    c = geoip.lookup_country_code(ext_ip)
                    if c:
                        logging.info("Country by IP: %s", c)
                        logging.info("Lookup currency by country...")
                        curr = ccy.countryccy(c)
                        logging.info("Local currency: %s", curr)
                        return curr
                except Exception, e:
                    logging.error(e)

    # If all above failed, try to query geobytes directly for curency code
    # TODO: Reasonably cache this
    if ext_ip and inetcache.isonline:
        try:
            with closing(
                    urllib2.urlopen(
                        "http://getcitydetails.geobytes.com/GetCityDetails?fqcn=%s"
                        % ext_ip, None, 5)) as resp:
                meta = resp.read()
            r = re.search(r"\"geobytescurrencycode\"\s*:\s*\"([A-Z]{3})\"",
예제 #23
0
 def test_eurozone(self):
     self.assertEqual(len(eurozone), 18)
     for c in eurozone:
         self.assertEqual(countryccy(c), 'EUR')
예제 #24
0
 def testCountryCcy(self):
     self.assertEqual('AUD', countryccy('au'))
     self.assertEqual('EUR', countryccy('eu'))
예제 #25
0
def format_currency_filter(amount):
    lang = request.accept_languages.best[-2:]
    if lang == 'en':
        lang = 'us'
    currency_code = ccy.countryccy(lang)
    return '{0} {1}'.format(currency_code, amount)
    def FindCurrencyCodes(self, df, c):

        currencyList = []
        for countryCode in df["country_code"]:
            countryCode = str(countryCode)
            c = ccy.countryccy(countryCode)
            c = str(c)

            if c != "None":
                currencyList.append(c)
            elif c == "None":
                if countryCode == "VE":  #Venezuela
                    currencyList.append("VEF")

                if countryCode == "CR":  #Costa Rica
                    currencyList.append("CRC")

                if countryCode == "PA":  #Panama
                    currencyList.append("PAB")

                if countryCode == "BH":  #Baharin //Ccheck
                    currencyList.append("BHD")

                if countryCode == "KW":  #Kuwait	//check
                    currencyList.append("KWD")

                if countryCode == "KE":  #Kenya	//check
                    currencyList.append("KES")

                if countryCode == "RS":  #Serbia	//check
                    currencyList.append("RSD")

                if countryCode == "ME":  #Montenegro	//check
                    currencyList.append("EUR")

                if countryCode == "MK":  #Macedonia	//check
                    currencyList.append("MKD")

                if countryCode == "BA":  #Bosnia and Herzegovina
                    currencyList.append("BAM")

                if countryCode == "MU":  #Mauritius	//check
                    currencyList.append("MUR")

                if countryCode == "MA":  #Moroccan	//check
                    currencyList.append("MAD")

                if countryCode == "PS":  #Palestine	//check
                    currencyList.append("ILS")

                if countryCode == "TN":  #Tunisia	//check
                    currencyList.append("TND")

                if countryCode == "BW":  #Botswana //check
                    currencyList.append("BWP")

                if countryCode == "JO":  #Jordan		//check
                    currencyList.append("JOD")

                if countryCode == "IS":  #Iceland	//check
                    currencyList.append("ISK")

                if countryCode == "NA":  #Namibia //check
                    currencyList.append("NAD")

                if countryCode == "LB":  #Lebanon //check
                    currencyList.append("LBP")

                if countryCode == "OM":  #Oman	//check
                    currencyList.append("OMR")

                if countryCode == "TZ":  #Tanzania	//check
                    currencyList.append("TZS")

                if countryCode == "GH":  #Ghana	//check
                    currencyList.append("GHS")

                if countryCode == "UA":  #Ukraine	//check
                    currencyList.append("UAH")

                if countryCode == "PK":  #Pakistan
                    currencyList.append("PKR")

                if countryCode == "BD":  #Bangladesh
                    currencyList.append("BDT")

                if countryCode == "MN":  #Mongolia
                    currencyList.append("MNT")

                if countryCode == "LA":  #Laos
                    val = str("LAK")
                    currencyList.append(val)

                if countryCode == "LK":  #Sri Lanka
                    val = str("LKR")
                    currencyList.append(val)

        df['countryCurrency'] = currencyList
        #pd.set_option('display.max_rows', None)
        #pd.set_option('display.max_column', None)
        return (df)
예제 #27
0
def convert(ctx, amount: float = 1, from_currency=None, to_currency=None):
    """
    Convert.

    Convert between currencies. Defaults to geolocated currencies.
    """
    _update_currencies(ctx.config.app_id, ctx.storage)

    if amount is None:
        amount = 1

    if from_currency is None and to_currency is None:
        ctx.respond(ctx._("You haven't specified a currency pair."))
        return

    if from_currency is None or to_currency is None:
        try:
            geocode = ctx.provider_for("geocode")
        except KeyError:
            ctx.respond(
                ctx.
                _("Sorry, I don't have a geocode provider loaded, and you haven't specified both currencies."
                  ))
            return

        user_data = yield ctx.bot.defer_from_thread(UserData.lookup_default,
                                                    ctx.client, ctx.origin)

        if "location" not in user_data:
            ctx.respond(
                ctx.
                _("You don't have location data set, so I can't guess what currency you want."
                  ))
            return

        result = (yield geocode(ctx.origin))[0]

        currency = ccy.countryccy([
            component["short_name"]
            for component in result["address_components"]
            if "country" in component["types"]
        ][0])

        if currency is None:
            ctx.respond(ctx._("I don't know the currency for your location."))
            return

        if from_currency is None:
            from_currency = currency

        if to_currency is None:
            to_currency = currency

    from_currency = from_currency.upper()
    to_currency = to_currency.upper()

    for currency in [from_currency, to_currency]:
        if currency not in ctx.storage.rates:
            ctx.respond(
                ctx._("I don't know the exchange rate for {currency}.").format(
                    currency=currency))
            return

    den = ctx.storage.rates[from_currency]
    num = ctx.storage.rates[to_currency]

    converted = amount * num / den

    ctx.respond(
        ctx.
        _("{amount:.4f} {from_currency} ({from_currency_name}) = {converted:.4f} {to_currency} ({to_currency_name})"
          ).format(amount=amount,
                   from_currency=from_currency,
                   from_currency_name=ctx.storage.names[from_currency],
                   converted=converted,
                   to_currency=to_currency,
                   to_currency_name=ctx.storage.names[to_currency]))
예제 #28
0
파일: ccytests.py 프로젝트: Zibbo/ccy
 def testCountryCcy(self):
     self.assertEqual('AUD', countryccy('au'))
     self.assertEqual('EUR', countryccy('eu'))
예제 #29
0
current_rates._get_rate('USD', date=date(2017, 5, 4))

# We can also Load the history rates as well from the website

history_rates = CurrencyConverter(
    'http://www.ecb.int/stats/eurofxref/eurofxref-hist.zip')

# check the information in detail about the currencies for e.g INR (INDIA)

ccy = ccy.currency('INR')
ccy.printinfo()

#check the currency of the country

ccy.countryccy('us')

# Lets check the rates from current_currency

current_rates.convert(100, 'EUR', 'INR')

#convert the current rate from Euro to INR for today's date

current_rates.convert(100, 'EUR', 'INR', date=date(2017, 5, 4))

# We can also make the default currency, lets make it Euro

current_rates.convert(100, 'EUR')

# Check the rates, how much is 100 Rs in Euro
current_rates.convert(100, 'INR')
예제 #30
0
def formato_moeda_filtro(valor):
    codigo_moeda = ccy.countryccy('BR')
    return '{0} {1}'.format(codigo_moeda, valor)
예제 #31
0
def convert(ctx, amount: float, from_currency=None, to_currency=None):
    """
    Convert.

    Convert between currencies. Defaults to geolocated currencies.
    """
    _update_currencies(ctx.config.app_id, ctx.storage)

    if from_currency is None and to_currency is None:
        ctx.respond(ctx._("You haven't specified a currency pair."))
        return

    if from_currency is None or to_currency is None:
        try:
            geocode = ctx.provider_for("geocode")
        except KeyError:
            ctx.respond(ctx._("Sorry, I don't have a geocode provider loaded, and you haven't specified both currencies."))
            return

        user_data = yield ctx.bot.defer_from_thread(UserData.lookup_default, ctx.client, ctx.origin)

        if "location" not in user_data:
            ctx.respond(ctx._("You don't have location data set, so I can't guess what currency you want."))
            return

        result = (yield geocode(ctx.origin))[0]

        currency = ccy.countryccy(
            [component["short_name"] for component in result["address_components"]
             if "country" in component["types"]][0]
        )

        if currency is None:
            ctx.respond(ctx._("I don't know the currency for your location."))
            return

        if from_currency is None:
            from_currency = currency

        if to_currency is None:
            to_currency = currency

    from_currency = from_currency.upper()
    to_currency = to_currency.upper()

    for currency in [from_currency, to_currency]:
        if currency not in ctx.storage.rates:
            ctx.respond(ctx._("I don't know the exchange rate for {currency}.").format(
                currency=currency
            ))
            return

    den = ctx.storage.rates[from_currency]
    num = ctx.storage.rates[to_currency]

    converted = amount * num / den

    ctx.respond(ctx._("{amount:.4f} {from_currency} ({from_currency_name}) = {converted:.4f} {to_currency} ({to_currency_name})").format(
        amount=amount,
        from_currency=from_currency,
        from_currency_name=ctx.storage.names[from_currency],
        converted=converted,
        to_currency=to_currency,
        to_currency_name=ctx.storage.names[to_currency]
    ))