Exemplo n.º 1
0
def exchange_fees_coin():
    """'Exchange fees by cryptocurrency' page.
    """
    # If 'calc_currency' exists in cookie, use it
    currency = request.cookies.get('calc_currency')
    if currency:
        curr = currency
    else:
        curr = Params.DEFAULT_CURRENCY
    curr = get_coin(curr)
    feedback_form = FeedbackForm()
    # Get exchanges
    coins = get_coins(pos_limit=Params.BROWSE_FEE_COINS, status="Active")
    # Get Meta tags
    title = get_meta_tags('Exchanges|Fees|Coin',
                          'Title')
    description = get_meta_tags('Exchanges|Fees|Coin',
                                'Description')
    # Actions if Feedback Form was filled
    if feedback_form.feedback_submit.data:
        if feedback_form.validate():
            manage_feedback_form(feedback_form, request.path)
    # Load page
    return render_template('exchange_fees_coin.html',
                           curr=curr,
                           title=title,
                           description=description,
                           feedback_form=feedback_form,
                           coins=coins)
 def get_best_coinZ(self, coin, baseCoin):
     """Finds a coin that trades in the exchange against both given coins.
     Returns a 'CoinZ' object.
     """
     # Get CoinZ's that trade against 'coin' & 'baseCoin'
     coinZ_coin = self.get_all_coinZs(coin)
     coinZ_baseCoin = self.get_all_coinZs(baseCoin)
     # Find CoinZ that trades agains both coins with highest liquidity
     winning_coinZ = CoinZ(None, -1, -1)
     for coinZ in coinZ_coin:
         for coinZ_2 in coinZ_baseCoin:
             if coinZ[0] == coinZ_2[0]:
                 if min(coinZ[1], coinZ_2[1]) < winning_coinZ.min_liq():
                     continue
                 # If same liquidity (or no available), BTC prevails
                 elif min(coinZ[1], coinZ_2[1]) == winning_coinZ.min_liq():
                     if (winning_coinZ.coin
                             and winning_coinZ.coin.id == 'BTC'):
                         continue
                 winning_coinZ = CoinZ(get_coin(coinZ[0]), coinZ[1],
                                       coinZ_2[1])
     if not winning_coinZ.coin:
         return None
     self.logger.debug("[{}] Chosen CoinZ: {}".format(
         self.exchange.id, winning_coinZ))
     return winning_coinZ
Exemplo n.º 3
0
def exchange_fees_exch():
    """'Exchange fees by exchange' page.
    """
    # If 'calc_currency' exists in cookie, use it
    currency = request.cookies.get('calc_currency')
    if currency:
        curr = currency
    else:
        curr = Params.DEFAULT_CURRENCY
    curr = get_coin(curr)
    feedback_form = FeedbackForm()
    # Get exchanges
    exchanges = get_exchanges(['Exchange'], status='Active')
    # Get promos
    promos = get_promos()
    # Get Meta tags
    title = get_meta_tags('Exchanges|Fees|Exch',
                          'Title')
    description = get_meta_tags('Exchanges|Fees|Exch',
                                'Description')
    # Actions if Feedback Form was filled
    if feedback_form.feedback_submit.data:
        if feedback_form.validate():
            manage_feedback_form(feedback_form, request.path)
    return render_template('exchange_fees_exch.html',
                           curr=curr,
                           title=title,
                           description=description,
                           feedback_form=feedback_form,
                           exchanges=exchanges,
                           promos=promos)
Exemplo n.º 4
0
def exchange_fees_by_exch(exch_id):
    """Displays the fees of the exchange given as argument.
    """
    exchange = get_exchange(exch_id)
    # If exchange not recognnized, redirect
    if not exchange:
        return redirect(url_for('exchange_fees_exch'))
    # Get Exchange fees
    trading_fees = get_trading_fees_by_exch(exch_id)
    dep_with_fees = get_dep_with_fees_by_exch(exch_id)
    # Get Exchange data
    exch_data = get_exchange_data(exchange.id,
                                  exchange.site_url,
                                  exchange_info_file,
                                  logger)
    # Get promos
    promos = get_promos()
    # If 'calc_currency' exists in cookie, use it
    currency = request.cookies.get('calc_currency')
    if currency:
        curr = currency
    else:
        curr = Params.DEFAULT_CURRENCY
    curr = get_coin(curr)
    # Get forms
    feedback_form = FeedbackForm()
    promo_form = PromoForm()
    # Get Meta tags
    title = get_meta_tags('Exchanges|Fees|Exch|Exch',
                          'Title',
                          [exchange.name])
    description = get_meta_tags('Exchanges|Fees|Exch|Exch',
                                'Description',
                                [exchange.name])
    # Get Texts
    trading_text = Markup(get_exch_text(exch_id, 'Trade'))
    withdrawal_text = Markup(get_exch_text(exch_id, 'Withdrawal'))
    # Actions if Feedback Form was filled
    if feedback_form.feedback_submit.data:
        if feedback_form.validate():
            manage_feedback_form(feedback_form, request.path)
    # Load page
    return render_template('exchange_fees_by_exch.html',
                           exchange=exchange,
                           curr=curr,
                           title=title,
                           description=description,
                           feedback_form=feedback_form,
                           promo_form=promo_form,
                           trading_text=trading_text,
                           withdrawal_text=withdrawal_text,
                           trading_fees=trading_fees,
                           dep_with_fees=dep_with_fees,
                           exch_data=exch_data,
                           promos=promos)
Exemplo n.º 5
0
def home():
    url_orig_coin = 'empty'
    url_dest_coin = 'empty'
    input_form = SearchForm()
    # If 'calc_currency' exists in cookie, use it
    currency = request.cookies.get('calc_currency')
    if currency:
        curr = currency
        input_form.currency.data = currency
    else:
        curr = Params.DEFAULT_CURRENCY
    curr = get_coin(curr)
    exchanges = get_exchanges(['Exchange'], status='Active')
    user_exchanges = [exch.id for exch in exchanges]
    # Get Blog information
    posts = get_latest_posts(None, 6)
    # Get Meta tags
    title = get_meta_tags('Home', 'Title')
    description = get_meta_tags('Home', 'Description')
    # Get forms
    feedback_form = FeedbackForm()
    promo_form = PromoForm()
    # Get promos
    promos = get_promos()
    # Actions if Feedback Form was filled
    if promo_form.promo_submit.data:
        if promo_form.validate():
            manage_promo_form(promo_form, 'Promos')
    # Actions if Feedback Form was filled
    if feedback_form.feedback_submit.data:
        if feedback_form.validate():
            manage_feedback_form(feedback_form, request.path)
    resp = make_response(render_template('home.html', form=input_form,
                                         curr=curr, exchanges=exchanges,
                                         user_exchanges=user_exchanges,
                                         title=title,
                                         description=description,
                                         feedback_form=feedback_form,
                                         promo_form=promo_form,
                                         promos=promos,
                                         url_orig_coin=url_orig_coin,
                                         url_dest_coin=url_dest_coin,
                                         add_flaticon_link=True,
                                         posts=posts))
    # Store session ID in cookie if it is not already stored
    session_id = request.cookies.get('session')
    if not session_id:
        resp.set_cookie('session', token_hex(8))
        session_id = request.cookies.get('session')
    return resp
 def perform_trade(self, sell_amt, sell_coin, buy_coin):
     """Performs the trade from 'sell_coin' to 'buy_coin'.
     Returns a 'Trade' object
     """
     # Find the trading fee for the given pairget_trade_fee(
     fee_amt_perc, fee_coin, fee_literal = self.get_trade_fee(
         sell_amt, sell_coin, buy_coin)
     if fee_amt_perc is None:
         self.logger.warning("perform_trade: No trade fee for '{}[{}/{}]'."
                             "Skipping trade calculation.".format(
                                 self.exchange.id, sell_coin.id,
                                 buy_coin.id))
         return None
     # Perform trade:
     buy_amt = fx_exchange(sell_coin.id, buy_coin.id,
                           sell_amt * (1 - fee_amt_perc / 100), self.logger)
     if buy_amt is None:
         self.logger.warning("perform_trade [2]: Trade could not be "
                             "performed '{}[{}/{}]'. "
                             "Skipping trade calculation.".format(
                                 self.exchange.id, sell_coin.id,
                                 buy_coin.id))
         return None
     elif buy_amt <= 0:
         self.logger.warning(
             "perform_trade [3]: Trade performed with negative outcome '{}[{} {} --> {} {}]'. "
             "Skipping trade calculation.".format(self.exchange.id,
                                                  sell_amt, sell_coin.id,
                                                  buy_amt, buy_coin.id))
         return None
     # Fees calculated by default in 'sell_coin'
     fee_amt = fee_amt_perc / 100 * sell_amt
     # If 'FeeCoin' has a value, calculate fees in 'FeeCoin'
     if fee_coin and fee_coin is not '-':
         fee_amt = fx_exchange(sell_coin.id, fee_coin, fee_amt, self.logger)
         fee_coin = get_coin(fee_coin)
     else:
         fee_coin = sell_coin
     # Return calculated trade
     self.logger.debug("perform_trade [3]: Trade for '{}[{}/{}]:"
                       " Sell={} {} / Buy={} {} / Fee={} {}'"
                       "".format(self.exchange.id, sell_coin.id,
                                 buy_coin.id, sell_amt, sell_coin.id,
                                 buy_amt, buy_coin.id, fee_amt,
                                 fee_coin.id))
     return Trade(sell_amt, sell_coin, buy_amt, buy_coin, fee_amt, fee_coin,
                  fee_literal)
Exemplo n.º 7
0
def promotions():
    try:
        # If 'calc_currency' exists in cookie, use it
        currency = request.cookies.get('calc_currency')
        if currency:
            curr = currency
        else:
            curr = Params.DEFAULT_CURRENCY
        curr = get_coin(curr)
        # Get forms
        feedback_form = FeedbackForm()
        promo_form = PromoForm()
        # Get Meta tags
        title = get_meta_tags('Promotions', 'Title')
        description = get_meta_tags('Promotions', 'Description')
        # Get promos
        promos = get_promos()
        # Actions if Feedback Form was filled
        if promo_form.promo_submit.data:
            if promo_form.validate():
                manage_promo_form(promo_form, 'Promos')
        # Actions if Feedback Form was filled
        if feedback_form.feedback_submit.data:
            if feedback_form.validate():
                manage_feedback_form(feedback_form, request.path)
    # Catch generic exception just in case anything went wront
    except Exception as e:
        logger.error("routes: Error procesing 'crypto-promotions'")
        error_notifier(type(e).__name__,
                       traceback.format_exc(),
                       mail,
                       logger)
        return redirect(url_for('home'))
    # Load page
    return render_template('promotions.html',
                           curr=curr,
                           title=title,
                           description=description,
                           feedback_form=feedback_form,
                           promo_form=promo_form,
                           promos=promos)
Exemplo n.º 8
0
def exchange_fees_by_coin(coin_url_name):
    """Displays the fees for the coin given as as argument.
    """
    try:
        coin = get_coin_by_urlname(coin_url_name)
        # If coin not recognized, redirect
        if not coin:
            return redirect(url_for('exchange_fees_coin'))
        # Get coin fees
        coin_fees = get_coin_fees(coin.id)
        # Get coin data
        coin_data = get_coin_data(coin.paprika_id,
                                  coin_info_file,
                                  people_info_file,
                                  tag_info_file,
                                  logger)
        # If 'calc_currency' exists in cookie, use it
        currency = request.cookies.get('calc_currency')
        if currency:
            curr = currency
        else:
            curr = Params.DEFAULT_CURRENCY
        feedback_form = FeedbackForm()
        # Get Meta tags
        title = get_meta_tags('Exchanges|Fees|Coin|Coin',
                              'Title',
                              [coin.long_name, coin.symbol])
        description = get_meta_tags('Exchanges|Fees|Coin|Coin',
                                    'Description',
                                    [coin.long_name, coin.symbol])
        # Get search coins
        if (coin.type == 'Crypto'):
            quick_search_coins = Params.QUICK_SEARCH_COINS['Crypto']
        else:
            quick_search_coins = Params.QUICK_SEARCH_COINS['Fiat']
        search_coins = []
        search_count = 0
        for item in quick_search_coins:
            if item != coin.id:
                coinA = get_coin(item)
                search_coins.append({"coinA": coinA, "coinB": coin})
                search_count += 1
            # If for items have been gathered, exit loop
            if search_count == 4:
                break
    # Catch generic exception just in case anything went wront
    except Exception as e:
        logger.error("routes: Error procesing '{}'".format(coin_url_name))
        error_notifier(type(e).__name__,
                       traceback.format_exc(),
                       mail,
                       logger)
        return redirect(url_for('exchange_fees_coin'))
    # Load page
    return render_template('exchange_fees_by_coin.html',
                           coin=coin,
                           coin_data=coin_data,
                           curr=curr,
                           title=title,
                           description=description,
                           feedback_form=feedback_form,
                           coin_fees=coin_fees,
                           search_coins=search_coins)
Exemplo n.º 9
0
def exch_results(url_orig_coin=None, url_dest_coin=None):
    """There are two ways of landing in this page:
         - Search form was filled: performs search and returns results
         - Direct external link (no form was filled!): in this case,
         a page with no results is shown, and then from the page a proper
         calculation is triggered. It is done like this to let the user
         load the page as soon as possible.
    """
    session_id = request.cookies.get('session')
    if not session_id:
        new_session_id = token_hex(8)
    sorted_paths = []
    input_form = SearchForm()
    # Choose currency: 1) Form 2) Cookie 3) Default
    currency = request.cookies.get('calc_currency')
    if input_form.currency.data != 'Empty':
        curr = input_form.currency.data
    elif currency:
        curr = currency
        input_form.currency.data = curr
    else:
        curr = Params.DEFAULT_CURRENCY
        input_form.currency.data = curr
    auto_search = False
    feedback_form = FeedbackForm()
    exchanges = get_exchanges(['Exchange'])
    user_exchanges = [exch.id for exch in exchanges]
    path_results = None
    open_fbck_modal = False
    # Get Meta tags (in case form was not filled)
    title = get_meta_tags('Exchanges|Results',
                          'Title',
                          [url_orig_coin.upper(), url_dest_coin.upper()])
    description = get_meta_tags('Exchanges|Results',
                                'Description',
                                [url_orig_coin.upper(), url_dest_coin.upper()])
    # 1) ACTIONS IF *SEARCH* FORM WAS FILLED
    if input_form.search_submit.data:
        if input_form.validate():
            curr = input_form.currency.data
            orig_loc = get_exch_by_name(input_form.orig_loc.data)
            orig_coin = get_coin_by_longname(input_form.orig_coin.data)
            # Save 'orig_amt' as Float or integer depending on value
            num = float(input_form.orig_amt.data)
            if num % 1 == 0:
                num = int(num)
            orig_amt = num
            dest_loc = get_exch_by_name(input_form.dest_loc.data)
            dest_coin = get_coin_by_longname(input_form.dest_coin.data)
            user_exchanges = input_form.exchanges.data
            # Get Meta tags (again, if form was filled)
            title = get_meta_tags('Exchanges|Results',
                                  'Title',
                                  [orig_coin.symbol, dest_coin.symbol])
            description = get_meta_tags('Exchanges|Results',
                                        'Description',
                                        [orig_coin.long_name,
                                         dest_coin.long_name])
            # If user selected all Exchanges or none of them, don't filter
            if len(user_exchanges) == len(exchanges):
                user_exchanges = []
            fee_settings = {"CEP": input_form.cep_promos.data,
                            "Default": input_form.default_fee.data,
                            "Binance": input_form.binance_fee.data}
            # start_time = datetime.datetime.now()
            try:
                paths = calc_paths(orig_loc, orig_coin, orig_amt,
                                   dest_loc, dest_coin,
                                   curr, fee_settings, logger)
                path_results = len(paths)
            # Catch generic exception just in case anything went wront in logic
            except Exception as e:
                db.session.rollback()
                error_notifier(type(e).__name__,
                               traceback.format_exc(),
                               mail,
                               logger)
                paths = []
                path_results = -1
            # If no results were found, send worning email
            if path_results == 0:
                args_dic = {"orig_amt": orig_amt,
                            "orig_coin": orig_coin.id,
                            "orig_loc": orig_loc.id,
                            "dest_coin": dest_coin.id,
                            "dest_loc": dest_loc.id,
                            "currency": curr}
                warning_notifier("Search with no results",
                                 args_dic,
                                 mail,
                                 logger)
            # Register query
            # finish_time = datetime.datetime.now()
            # results = len(paths)
            # exchs = ""
            # for exch in user_exchanges:
            #     exchs += exch + '|'
            # exchs = exchs[:-1]
            # try:
            #     query = QueryRegister(session_id=session_id,
            #                           orig_amt=orig_amt,
            #                           orig_coin=orig_coin.id,
            #                           orig_loc=orig_loc.id,
            #                           dest_coin=dest_coin.id,
            #                           dest_loc=dest_loc.id,
            #                           currency=curr,
            #                           connection_type=connection_type,
            #                           exchanges=exchs,
            #                           results=results,
            #                           start_time=start_time,
            #                           finish_time=finish_time)
            #     db.session.add(query)
            #     db.session.commit()
            # except Exception as e:
            #     db.session.rollback()
            #     error_notifier(type(e).__name__,
            #                    traceback.format_exc(),
            #                    mail,
            #                    logger)
            # Select all Exchanges if no partial selection was made
            if not user_exchanges:
                user_exchanges = [exch.id for exch in exchanges]
            # Return capped list of results
            sorted_paths = sorted(paths, key=lambda x: x.total_fees)
            sorted_paths = sorted_paths[0:Params.MAX_PATHS]
    # 2) ACTIONS IF *NO* FORM WAS FILLED (DIRECT LINK!)
    else:
        orig_coin = get_coin(url_orig_coin.upper())
        dest_coin = get_coin(url_dest_coin.upper())
        if orig_coin:
            input_form.orig_coin.data = orig_coin.long_name
            amt = fx_exchange("USD", orig_coin.id, 3000, logger)
            input_form.orig_amt.data = str(math.ceil(amt)) + " "
        if dest_coin:
            input_form.dest_coin.data = dest_coin.long_name
        auto_search = True
    resp = make_response(render_template('exch_results.html',
                                         form=input_form,
                                         curr=curr,
                                         exchanges=exchanges,
                                         user_exchanges=user_exchanges,
                                         paths=sorted_paths,
                                         path_results=path_results,
                                         auto_search=auto_search,
                                         feedback_form=feedback_form,
                                         title=title,
                                         description=description,
                                         open_feedback_modal=open_fbck_modal,
                                         url_orig_coin=url_orig_coin,
                                         url_dest_coin=url_dest_coin))
    # Store session ID & Currency in cookie if there are not already stored
    if not session_id:
        resp.set_cookie('session', new_session_id)
    if currency != curr:
        resp.set_cookie('calc_currency', curr)
    return resp
Exemplo n.º 10
0
def exch_results(url_orig_coin=None, url_dest_coin=None):
    """There are two ways of landing in this page:
         - Search form was filled: performs search and returns results
         - Direct external link (no form was filled!): in this case,
         a page with no results is shown, and then from the page a proper
         calculation is triggered. It is done like this to let the user
         load the page as soon as possible.
    """
    try:
        session_id = request.cookies.get('session')
        if not session_id:
            new_session_id = token_hex(8)
        sorted_paths = []
        input_form = SearchForm()
        # Choose currency: 1) Form 2) Cookie 3) Default
        currency = request.cookies.get('calc_currency')
        if input_form.currency.data != 'Empty':
            curr = input_form.currency.data
        elif currency:
            curr = currency
            input_form.currency.data = curr
        else:
            curr = Params.DEFAULT_CURRENCY
            input_form.currency.data = curr
        curr = get_coin(curr)
        if not curr:
            curr = get_coin('usd-us-dollars')
        auto_search = False
        feedback_form = FeedbackForm()
        exchanges = get_exchanges(['Exchange'], status='Active')
        user_exchanges = [exch.id for exch in exchanges]
        path_results = None
        amt_warning = None
        # Get Meta tags (in case form was not filled)
        title = get_meta_tags('Exchanges|Results',
                              'Title',
                              [url_orig_coin.upper(), url_dest_coin.upper()])
        description = get_meta_tags('Exchanges|Results',
                                    'Description',
                                    [url_orig_coin.upper(),
                                     url_dest_coin.upper()])
        # 1) ACTIONS IF *SEARCH* FORM WAS FILLED
        if input_form.search_submit.data:
            if input_form.validate():
                curr = input_form.currency.data
                curr = get_coin(curr)
                orig_loc = get_exch_by_name(input_form.orig_loc.data)
                orig_coin = get_coin_by_longname(input_form.orig_coin.data)
                # Save 'orig_amt' as Float or integer depending on value
                num = float(input_form.orig_amt.data)
                if num % 1 == 0:
                    num = int(num)
                orig_amt = num
                dest_loc = get_exch_by_name(input_form.dest_loc.data)
                dest_coin = get_coin_by_longname(input_form.dest_coin.data)
                user_exchanges = input_form.exchanges.data
                # Get Meta tags (again, if form was filled)
                title = get_meta_tags('Exchanges|Results',
                                      'Title',
                                      [orig_coin.symbol, dest_coin.symbol])
                description = get_meta_tags('Exchanges|Results',
                                            'Description',
                                            [orig_coin.long_name,
                                             dest_coin.long_name])
                # If user selected all Exchanges or none of them, don't filter
                if len(user_exchanges) == len(exchanges):
                    user_exchanges = []
                fee_settings = {"CEP": input_form.cep_promos.data,
                                "Default": input_form.default_fee.data,
                                "Binance": input_form.binance_fee.data}
                # start_time = datetime.datetime.now()
                try:
                    paths = calc_paths(orig_loc, orig_coin, orig_amt,
                                       dest_loc, dest_coin,
                                       curr, fee_settings, logger)
                    path_results = len(paths)
                # Catch generic exception if anything went wrong in logic
                except Exception as e:
                    db.session.rollback()
                    error_notifier(type(e).__name__,
                                   traceback.format_exc(),
                                   mail,
                                   logger)
                    paths = []
                    path_results = -1
                # If no results were found, check "orign_amt" to try again
                if path_results == 0:
                    amount_usd = fx_exchange(orig_coin.id,
                                             'usd-us-dollars',
                                             orig_amt,
                                             logger)
                    if amount_usd and amount_usd < Params.RECALC_AMOUNT:
                        orig_amt = round_number(orig_amt * Params.RECALC_AMOUNT
                                                / amount_usd)
                        orig_amt = round_big_number(orig_amt)
                        input_form.orig_amt.data = orig_amt
                        try:
                            paths = calc_paths(orig_loc, orig_coin, orig_amt,
                                               dest_loc, dest_coin,
                                               curr, fee_settings, logger)
                            path_results = len(paths)
                            amt_warning = True
                        # Catch generic exception if anything went wrong
                        except Exception as e:
                            db.session.rollback()
                            error_notifier(type(e).__name__,
                                           traceback.format_exc(),
                                           mail,
                                           logger)
                            paths = []
                            path_results = -1
                # If no results were found, send worning email
                if path_results == 0:
                    args_dic = {"orig_amt": orig_amt,
                                "orig_coin": orig_coin.id,
                                "orig_loc": orig_loc.id,
                                "dest_coin": dest_coin.id,
                                "dest_loc": dest_loc.id,
                                "currency": curr.id}
                    warning_notifier("Search with no results",
                                     args_dic,
                                     mail,
                                     logger)
                # Select all Exchanges if no partial selection was made
                if not user_exchanges:
                    user_exchanges = [exch.id for exch in exchanges]
                # Return capped list of results
                sorted_paths = sorted(paths, key=lambda x: x.total_fees)
                sorted_paths = sorted_paths[0:Params.MAX_PATHS]
        # 2) ACTIONS IF *NO* FORM WAS FILLED (DIRECT LINK!)
        else:
            orig_coin = get_coin_by_symbol(url_orig_coin.upper())
            dest_coin = get_coin_by_symbol(url_dest_coin.upper())
            # If 'orig_coin' or 'dest_coin' not found, try in mappings table
            if not orig_coin:
                new_symbol = get_mapping('Coin',
                                         'symbol',
                                         url_orig_coin.upper())
                if new_symbol:
                    orig_coin = get_coin_by_symbol(new_symbol)
            if not dest_coin:
                new_symbol = get_mapping('Coin',
                                         'symbol',
                                         url_dest_coin.upper())
                if new_symbol:
                    dest_coin = get_coin_by_symbol(new_symbol)
            # Procced with function
            if orig_coin:
                input_form.orig_coin.data = orig_coin.long_name
                amt = fx_exchange('usd-us-dollars', orig_coin.id, 3000, logger)
                if amt:
                    amt = round_big_number(amt)
                    input_form.orig_amt.data = str(math.ceil(amt)) + " "
            if dest_coin:
                input_form.dest_coin.data = dest_coin.long_name
            auto_search = True
        # Actions if Feedback Form was filled
        if feedback_form.feedback_submit.data:
            if feedback_form.validate():
                manage_feedback_form(feedback_form, request.path)
    # Catch generic exception just in case anything went wront in logic
    except Exception as e:
        db.session.rollback()
        logger.error("Routes: Non-handled exception at '{}'"
                     .format(request.url))
        error_notifier(type(e).__name__,
                       traceback.format_exc(),
                       mail,
                       logger)
        return redirect(url_for('exchanges'))
    resp = make_response(render_template('exch_results.html',
                                         form=input_form,
                                         curr=curr,
                                         exchanges=exchanges,
                                         user_exchanges=user_exchanges,
                                         paths=sorted_paths,
                                         amt_warning=amt_warning,
                                         path_results=path_results,
                                         auto_search=auto_search,
                                         feedback_form=feedback_form,
                                         title=title,
                                         description=description,
                                         url_orig_coin=url_orig_coin,
                                         url_dest_coin=url_dest_coin))
    # Store session ID & Currency in cookie if there are not already stored
    if not session_id:
        resp.set_cookie('session', new_session_id)
    if currency != curr.id:
        resp.set_cookie('calc_currency', curr.id)
    return resp
Exemplo n.º 11
0
def calc_paths(orig_loc, orig_coin, orig_amt, dest_loc, dest_coin, currency,
               fee_settings, logger):

    # Paths container
    path_list = []
    """ ***********************************************************************
    ***************************************************************************
    1. DIRECT EXCHANGE(NO HOPS)
    ***************************************************************************
    *********************************************************************** """

    logger.info("\n\nSTARTING CALCULATION FOR: \norig_amt = {}\n"
                "orig_coin = {}\norig_loc = {}\ndest_coin = {}\ndest_loc = {}"
                "\ncurrency = {}\nfee_settings = {}".format(
                    orig_amt, orig_coin, orig_loc, dest_coin, dest_loc,
                    currency, fee_settings))

    logger.info("Main: CALCULATING '1. DIRECT EXCHANGE(NO HOPS)'")
    # Get exchanges with direct pair exchange
    direct_pair_exch = get_exch_by_pair(orig_coin.id, dest_coin.id, logger)
    # Get exchanges that allow deposits of 'orig_coin'
    exchs_allow_deposits = get_exch_by_coin(orig_coin.id)
    # Common parts of 'Path'
    path_type = 0
    origin = Location("Origin", orig_loc, orig_amt, orig_coin, logger)
    # Loop for each exchange to calculate Path fees
    for exch in direct_pair_exch:
        # First, check if the exchange allows deposits
        if exch not in exchs_allow_deposits:
            continue
        # If allows deposits, perform trade
        trade_1_sell_amt = orig_amt
        if origin.withdraw_fee:
            trade_1_sell_amt -= origin.withdraw_fee
        # Calc deposit fee 1 and substract it from sell amount
        deposit_fee_1 = [None, None]
        if exch != origin.exchange.id:
            deposit_fee_1 = calc_fee('Deposit', exch, orig_coin.id,
                                     trade_1_sell_amt, logger)
            if deposit_fee_1 and deposit_fee_1[0] is not None:
                trade_1_sell_amt -= deposit_fee_1[0]
        # Perform Trade 1
        exchange_1 = ExchangeManager(get_exchange(exch), fee_settings, logger)
        trade_1 = exchange_1.perform_trade(trade_1_sell_amt, orig_coin,
                                           dest_coin)
        # If 'perform_trade()' did not get results, skip path. Else continue
        if not trade_1:
            logger.warning("Main: Trade could not be performed for {}/{}[{}]. "
                           "Path skipped.".format(orig_coin.id, dest_coin.id,
                                                  exch))
            continue
        # Calc destination amount
        dest_amt = trade_1.buy_amt
        # Calc Withdraw fee and modify destination amount
        withdraw_fee_1 = []
        if exch != dest_loc.id:
            withdraw_fee_1 = calc_fee('Withdrawal', exch, trade_1.buy_coin.id,
                                      trade_1.buy_amt, logger)
            if withdraw_fee_1 and withdraw_fee_1[0] is not None:
                dest_amt -= withdraw_fee_1[0]
                if dest_amt < 0:
                    logger.warning("Main: Destination amount "
                                   "lower than 0 for {} [{}]. "
                                   " Path skipped.".format(
                                       exch, trade_1.buy_coin.id))
                    continue
            else:
                logger.warning("Main: Withdraw Fee not found for {} [{}]. "
                               "Path skipped.".format(exch,
                                                      trade_1.buy_coin.id))
                continue
        # Generate Hop & destination location to finish 'Path'
        hop_1 = Hop(get_exchange(exch), trade_1, deposit_fee_1, withdraw_fee_1)
        destination = Location("Destination", dest_loc, dest_amt, dest_coin,
                               logger)
        if destination.exchange.id == exch:
            destination.remove_deposit_fees()
        # Generate 'Path' and add to 'path_list'
        path = Path(path_type, origin, hop_1, None, destination, currency,
                    logger)
        path_list.append(path)
        logger.debug(
            ('Path Found: {}->{}({})').format(trade_1.sell_coin.id,
                                              trade_1.buy_coin.id, exch))
    logger.info("End of '1. DIRECT EXCHANGE(NO HOPS)'")
    """ ***********************************************************************
    ***************************************************************************
    2. INDIRECT EXCHANGE(ONE HOP)
    ***************************************************************************
    *********************************************************************** """
    logger.info("Main: CALCULATING '2. INDIRECT EXCHANGE(ONE HOP)'")
    # Get exchanges with indirect pair exchange
    orig_coin_exchanges = get_exch_by_coin(orig_coin.id)
    dest_coin_exchanges = get_exch_by_coin(dest_coin.id)
    # Filter exchanges already used - Filter 'orig_coin_exchanges'
    filtered_exch = set()
    for exch in orig_coin_exchanges:
        if exch not in direct_pair_exch:
            filtered_exch.add(exch)
    orig_coin_exchanges = filtered_exch
    logger.debug(
        "Main: 'orig_coin_exchanges' filtered: {}".format(orig_coin_exchanges))
    # Filter exchanges already used - Filter 'dest_coin_exchanges'
    filtered_exch = set()
    for exch in dest_coin_exchanges:
        if exch not in direct_pair_exch:
            filtered_exch.add(exch)
    dest_coin_exchanges = filtered_exch
    logger.debug(
        "Main: 'dest_coin_exchanges' filtered: {}".format(dest_coin_exchanges))
    # Select exchanges that trade both coins, but not with a direct trade
    indirect_pair_exch = [
        exch for exch in orig_coin_exchanges if exch in dest_coin_exchanges
    ]
    logger.debug("Exchanges with both pairs (but not direct trade) [{}]: {}"
                 "".format(len(indirect_pair_exch), indirect_pair_exch))
    # Common parts of 'Path'
    path_type = 1
    origin = Location("Origin", orig_loc, orig_amt, orig_coin, logger)
    # Loop for each exchange with both pairs
    for exch in indirect_pair_exch:
        # Get CoinZ that trades against both pairs
        exchange = ExchangeManager(get_exchange(exch), fee_settings, logger)
        coinZ = exchange.get_best_coinZ(orig_coin.id, dest_coin.id)
        if not coinZ:
            logger.warning("Main: No coinZ found in exchange '{}' to convert"
                           "'{}' to '{}' Path skipped.".format(
                               exch, orig_coin.id, dest_coin.id))
            continue
        # CALCULATE OUTPUTS FOR 'Hop 1'
        trade_1_sell_amt = orig_amt
        if origin.withdraw_fee:
            trade_1_sell_amt -= origin.withdraw_fee
        # Calc deposit fee 1 and substract it from sell amount
        deposit_fee_1 = [None, None]
        if exch != origin.exchange.id:
            deposit_fee_1 = calc_fee('Deposit', exch, orig_coin.id,
                                     trade_1_sell_amt, logger)
            if deposit_fee_1 and deposit_fee_1[0] is not None:
                trade_1_sell_amt -= deposit_fee_1[0]
        # Perform Trade 1
        trade_1 = exchange.perform_trade(trade_1_sell_amt, orig_coin,
                                         coinZ.coin)
        # If 'perform_trade()' did not get results, skip path. Else continue
        if not trade_1:
            logger.warning("Main: Trade could not be performed for {}/{}[{}]. "
                           "Path skipped.".format(orig_coin.id, coinZ.coin.id,
                                                  exch))
            continue
        # Generate output object for 'Hop 1'
        hop_1 = Hop(exchange.exchange, trade_1, deposit_fee_1, None)
        # CALCULATE OUTPUTS FOR 'Hop 2'
        trade_2 = exchange.perform_trade(trade_1.buy_amt, trade_1.buy_coin,
                                         dest_coin)
        # If 'perform_trade()' did not get results, skip path. Else continue
        if not trade_2:
            logger.warning("Main: Trade could not be performed for {}/{}[{}]. "
                           "Path skipped.".format(trade_1.buy_coin.id,
                                                  dest_coin.id, exch))
            continue
        # Calc destination amount
        dest_amt = trade_2.buy_amt
        # Calc Withdraw fee and modify destination amount
        withdraw_fee_2 = []
        if exch != dest_loc.id:
            withdraw_fee_2 = calc_fee('Withdrawal', exch, trade_2.buy_coin.id,
                                      trade_2.buy_amt, logger)
            if withdraw_fee_2 and withdraw_fee_2[0] is not None:
                dest_amt -= withdraw_fee_2[0]
            else:
                logger.warning("Main: Withdraw Fee not found for {} [{}]. "
                               "Path skipped.".format(exch,
                                                      trade_2.buy_coin.id))
                continue
        # Generate Hop & destination location to finish 'Path'
        deposit_fee_2 = [None, None]
        hop_2 = Hop(exchange.exchange, trade_2, deposit_fee_2, withdraw_fee_2)
        destination = Location("Destination", dest_loc, dest_amt, dest_coin,
                               logger)
        if destination.exchange.id == exch:
            destination.remove_deposit_fees()
        # Generate 'Path' and add to 'path_list'
        path = Path(path_type, origin, hop_1, hop_2, destination, currency,
                    logger)
        path_list.append(path)
        logger.debug('Path Found: {}->{}({})'
                     ' --> {}->{}({})'.format(trade_1.sell_coin.id,
                                              trade_1.buy_coin.id, exch,
                                              trade_2.sell_coin.id,
                                              trade_2.buy_coin.id, exch))
    logger.info("End of '2. INDIRECT EXCHANGE(ONE HOP)'")
    """ ***********************************************************************
    ***************************************************************************
    3. INDIRECT EXCHANGE(TWO HOPS)
    ***************************************************************************
    *********************************************************************** """
    logger.info("Main: CALCULATING '3. INDIRECT EXCHANGE(TWO HOPS)'")
    # Get all the coins that trade against 'orig_coin' for each exchange
    orig_coin_exchanges_coinZs = []
    for exch in orig_coin_exchanges:
        exchange = ExchangeManager(get_exchange(exch), fee_settings, logger)
        coinZs_A = exchange.get_all_cryptoZs(orig_coin.id)
        exchange.coinZs = coinZs_A
        orig_coin_exchanges_coinZs.append(exchange)
        logger.debug("Pairs against [] {}: {}".format(exchange.exchange.id,
                                                      orig_coin.id,
                                                      exchange.coinZs))
    # Get all the coins that trade against 'dest_coin' for each exchange
    dest_coin_exchanges_coinZs = []
    for exch in dest_coin_exchanges:
        exchange = ExchangeManager(get_exchange(exch), fee_settings, logger)
        coinZs_B = exchange.get_all_cryptoZs(dest_coin.id)
        exchange.coinZs = coinZs_B
        dest_coin_exchanges_coinZs.append(exchange)
        logger.debug("Pairs against [] {}: {}".format(exchange.exchange.id,
                                                      orig_coin.id,
                                                      exchange.coinZs))
    # Common parts of 'Path'
    path_type = 2
    origin = Location("Origin", orig_loc, orig_amt, orig_coin, logger)
    # Loop through all the exchanges and coins
    for exch_A in orig_coin_exchanges_coinZs:
        for coinZ_A in exch_A.coinZs:
            for exch_B in dest_coin_exchanges_coinZs:
                if exch_A.exchange.id == exch_B.exchange.id:
                    continue
                for coinZ_B in exch_B.coinZs:
                    # If coinZ_A==coinZ_B, calculate Exchange Path
                    if coinZ_A[0] == coinZ_B[0]:
                        # CALCULATE OUTPUTS FOR 'Hop 1'
                        trade_1_sell_amt = orig_amt
                        if origin.withdraw_fee:
                            trade_1_sell_amt -= origin.withdraw_fee
                        # Calc deposit fee 1 and substract it from sell amount
                        deposit_fee_1 = [None, None]
                        if exch_A.exchange.id != origin.exchange.id:
                            deposit_fee_1 = calc_fee('Deposit',
                                                     exch_A.exchange.id,
                                                     orig_coin.id,
                                                     trade_1_sell_amt, logger)
                            if deposit_fee_1 and deposit_fee_1[0] is not None:
                                trade_1_sell_amt -= deposit_fee_1[0]
                        # Perform Trade 1
                        trade_1 = exch_A.perform_trade(trade_1_sell_amt,
                                                       orig_coin,
                                                       get_coin(coinZ_A[0]))
                        # If 'perform_trade()' did not get results, skip path
                        if not trade_1:
                            logger.warning(
                                "Main: Trade could not be performed"
                                " for {}/{}[{}]. Path skipped.".format(
                                    orig_coin.id, coinZ_A[0],
                                    exch_A.exchange.id))
                            continue
                        # Calc destination amount
                        in_amt_2 = trade_1.buy_amt
                        # Calc Withdraw fee and modify destination amount
                        withdraw_fee_1 = calc_fee('Withdrawal',
                                                  exch_A.exchange.id,
                                                  trade_1.buy_coin.id,
                                                  trade_1.buy_amt, logger)
                        if withdraw_fee_1 and withdraw_fee_1[0] is not None:
                            in_amt_2 -= withdraw_fee_1[0]
                        else:
                            logger.warning("Main: Withdraw Fee not found for"
                                           " {} [{}]. Path skipped.".format(
                                               exch_A.exchange.id,
                                               trade_1.buy_coin.id))
                            continue
                        # Generate output object for 'Hop 1'
                        hop_1 = Hop(exch_A.exchange, trade_1, deposit_fee_1,
                                    withdraw_fee_1)
                        # CALCULATE OUTPUTS FOR 'Hop 2'
                        # Calc deposit fee 2 and substract it from sell amount
                        deposit_fee_2 = calc_fee('Deposit', exch_B.exchange.id,
                                                 trade_1.buy_coin.id, in_amt_2,
                                                 logger)
                        if deposit_fee_2 and deposit_fee_2[0] is not None:
                            in_amt_2 -= deposit_fee_2[0]
                        # Perform Trade 2
                        trade_2 = exch_B.perform_trade(in_amt_2,
                                                       trade_1.buy_coin,
                                                       dest_coin)
                        # If 'perform_trade()' did not get results, skip path
                        if not trade_2:
                            logger.warning(
                                "Main: Trade could not be performed"
                                " for {}/{}[{}]. Path skipped.".format(
                                    trade_1.buy_coin.id, dest_coin.id,
                                    exch_B.exchange.id))
                            continue
                        # Calc destination amount
                        dest_amt = trade_2.buy_amt
                        # Calc Withdraw fee and modify destination amount
                        withdraw_fee_2 = []
                        if exch_B.exchange.id != dest_loc.id:
                            withdraw_fee_2 = calc_fee('Withdrawal',
                                                      exch_B.exchange.id,
                                                      trade_2.buy_coin.id,
                                                      trade_2.buy_amt, logger)
                            if (withdraw_fee_2
                                    and withdraw_fee_2[0] is not None):
                                dest_amt -= withdraw_fee_2[0]
                                if dest_amt < 0:
                                    logger.warning("Main: Destination amount "
                                                   "lower than 0 for {} [{}]."
                                                   " Path skipped.".format(
                                                       exch_B.exchange.id,
                                                       trade_2.buy_coin.id))
                                    continue
                            else:
                                logger.warning(
                                    "Main: Withdraw Fee not found "
                                    "for {} [{}]. Path skipped.".format(
                                        exch_B.exchange.id,
                                        trade_2.buy_coin.id))
                                continue
                        # Generate Hop & destination location to finish 'Path'
                        hop_2 = Hop(exch_B.exchange, trade_2, deposit_fee_2,
                                    withdraw_fee_2)
                        destination = Location("Destination", dest_loc,
                                               dest_amt, dest_coin, logger)
                        if destination.exchange.id == exch_B.exchange.id:
                            destination.remove_deposit_fees()
                        # Generate 'Path' and add to 'path_list'
                        path = Path(path_type, origin, hop_1, hop_2,
                                    destination, currency, logger)
                        path_list.append(path)
                        logger.debug(
                            'Path Found: {}->{}({}) --> {}->{}({})'.format(
                                trade_1.sell_coin.id, trade_1.buy_coin.id,
                                exch_A.exchange.id, trade_2.sell_coin.id,
                                trade_2.buy_coin.id, exch_B.exchange.id))
    logger.info("End of '3. INDIRECT EXCHANGE(TWO HOPS)'")

    # generate_paths_file(path_list, currency, logger)
    logger.info("Path calculation finished. '{}' results".format(
        len(path_list)))
    return path_list