Example #1
0
def watch():
    db = session.get_a_trading_db_mysql_session()
    r = session.get_a_redis_connection()

    logger.info('Reporting for duty.')

    try:
        while True:
            logger.info('Scanning for abnormalities.')

            check_profit(db)
            check_open_pl(db)
            check_ticktimes(db)
            check_position(db)
            check_btc_net_assets(db)
            check_spreads_are_normal(db)
            check_fv_not_stagnant(db)
            check_fv_predictor_key_set(r)

            # for some reason this commit is needed to pick up changes on
            # subsequent queries.
            session.commit_mysql_session(db)

            logger.info('Going to sleep for %s seconds.' % TICK_SLEEP)
            time.sleep(TICK_SLEEP)
    finally:
        db.remove()
def test_fast_revenue_fees_profit():
    db = session.get_a_trading_db_mysql_session()

    for i in range(1, 30):
        start, end = get_random_period()

        print '%s, %s' % (start, end)

        slow_revenue, slow_fees, slow_profit = gryphon_profit.revenue_fees_profit_in_period(
            db, start, end)
        fast_revenue, fast_fees, fast_profit = gryphon_profit.fast_revenue_fees_profit_in_period(
            db, start, end)

        result = (slow_revenue.round_to_decimal_places(4)
                  == fast_revenue.round_to_decimal_places(4)
                  and slow_profit.round_to_decimal_places(4)
                  == fast_profit.round_to_decimal_places(4)
                  and slow_fees.round_to_decimal_places(4)
                  == fast_fees.round_to_decimal_places(4))

        if not result:
            print 'BAD'
        else:
            print 'GOOD'

    db.remove()
Example #3
0
def main(exchanges, execute):
    exchanges = configuration.parse_configurable_as_list(exchanges)
    db = session.get_a_trading_db_mysql_session()

    for exchange_name in exchanges:
        exchange_wrapper = exchange_factory.make_exchange_from_key(
            exchange_name)
        initialize_exchange_ledger(db, exchange_wrapper)

    if execute is True:
        db.commit()
Example #4
0
def get_target(exchange_name):
    db = session.get_a_trading_db_mysql_session()
    try:
        exchange = make_exchange_from_key(exchange_name)
        exchange_data = exchange.exchange_account_db_object(db)
        if not exchange_data:
            exchange_data = ExchangeData(exchange.name)
        target = exchange_data.target['BTC']
        logger.info("%s's target is %s", exchange.friendly_name, target)
    finally:
        db.remove()
    return target
Example #5
0
File: app.py Project: zlex7/gryphon
    def __init__(self):
        tornado.web.Application.__init__(self, url_patterns, **settings)

        self.dashboard_db = session.get_a_dashboard_db_mysql_session()
        self.trading_db = session.get_a_trading_db_mysql_session()

        try:
            self.gds_db = session.get_a_gds_db_mysql_session()
        except KeyError as e:
            logger.info(GDS_ERROR)
            self.gds_db = None

        self.configuration = configuration.read_config_from_file(
            'dashboards.conf')
Example #6
0
def withdraw(exchange_name, target_exchange_name, amount_str):
    db = session.get_a_trading_db_mysql_session()
    try:
        exchange_data = make_exchange_data_from_key(exchange_name, db)
        target_exchange_data = make_exchange_data_from_key(target_exchange_name, db)
        target_exchange = make_exchange_from_key(target_exchange_name)
        amount = Money.loads(amount_str)
        
        addr = target_exchange.current_deposit_address
        exchange_data.record_withdrawal(target_exchange_data, amount, addr)
        session.commit_mysql_session(db)
        logger.info(tc.colored("Recorded %s withdrawal from %s" % (amount, exchange_name), "green"))
    finally:
        db.remove()
Example #7
0
def get_db_balances(exchanges):
    db = session.get_a_trading_db_mysql_session()

    db_balances = {}
    db_balances['system'] = Balance()
    try:
        for exchange in exchanges:
            exchange_data = exchange.exchange_account_db_object(db)
            db_balances[exchange.name] = exchange_data.balance
            db_balances['system']['USD'] += db_balances[exchange.name].fiat().to('USD')
            db_balances['system']['BTC'] += db_balances[exchange.name]['BTC']
    finally:
        db.close()
    return db_balances
Example #8
0
def withdraw_fiat(exchange_name, target_exchange_name, amount_str, deposit_amount_str, transaction_details):
    db = session.get_a_trading_db_mysql_session()
    try:
        exchange_data = make_exchange_data_from_key(exchange_name, db)
        target_exchange_data = make_exchange_data_from_key(target_exchange_name, db)
        amount = Money.loads(amount_str)
        if deposit_amount_str:
            deposit_amount = Money.loads(deposit_amount_str)
            exchange_data.record_fiat_withdrawal(target_exchange_data, amount, deposit_amount=deposit_amount, transaction_details=transaction_details)
        else:
            exchange_data.record_fiat_withdrawal(target_exchange_data, amount, transaction_details=transaction_details)
            
        session.commit_mysql_session(db)
        logger.info(tc.colored("Recorded %s withdrawal from %s" % (amount, exchange_name), "green"))
    finally:
        db.remove()
Example #9
0
def transaction_complete(exchange_name, currency):
    db = session.get_a_trading_db_mysql_session()
    try:
        exchange_data = make_exchange_data_from_key(exchange_name, db)
        tr = db.query(Transaction).filter_by(exchange=exchange_data).filter_by(_amount_currency=currency).filter_by(transaction_status=Transaction.IN_TRANSIT).order_by(Transaction.time_created).first()
        if tr:
            tr.complete()
            session.commit_mysql_session(db)
            if tr.transaction_type == Transaction.DEPOSIT:
                action = "deposit to"
            elif tr.transaction_type == Transaction.WITHDRAWL:
                action = "withdrawal from"
            logger.info(tc.colored("Recorded %s %s %s" % (tr.amount, action, exchange_name), "green"))
        else:
            logger.info(tc.colored("No Transaction of that currency found", "red"))
    finally:
        db.remove()
Example #10
0
def run():
    db = session.get_a_trading_db_mysql_session()

    try:
        logger.info('Reporting for duty.')

        while True:
            audit_bmo_accounts(db)
            audit_boa_accounts(db)

            session.commit_mysql_session(db)
            logger.info('Going to sleep for %s.' %
                        humanize_seconds(TICK_SLEEP))
            time.sleep(TICK_SLEEP)

    finally:
        db.remove()
Example #11
0
def run():
    db = session.get_a_trading_db_mysql_session()

    DatumRecorder().create(db=db)

    logger.info('Reporting for duty.')

    try:
        while True:
            current_time = Delorean().datetime

            try:
                update_tx_hashes(db)
            except Exception as e:
                logger.exception('Error while updating transaction hashes')

            # Checking the exact minute amounts works because the shoebox is ticking every 1m
            # This may not work 100% if the shoebox tick takes any noticable amount of time
            # to run. In that case we might tick at the end of xx:59 and the beginning of xx:01,
            # and these tasks wouldn't run. We'll keep an eye on it and may have to add some
            # persistance later.

            # every 5 minutes
            if current_time.minute % 5 == 0:
                try:
                    get_breaking_bitcoin_news()
                except Exception:
                    logger.exception('Error while getting breaking news')

            # every hour
            if current_time.minute == 0:
                money_moving()
                manual_btc_withdrawals(db)

            # end of day UTC
            if current_time.hour == 0 and current_time.minute == 0:
                notify_revenue(db)

            heartbeat(SHOEBOX_HEARTBEAT_KEY)

            session.commit_mysql_session(db)
            logger.info('Going to sleep for %s.' %
                        humanize_seconds(TICK_SLEEP))
            time.sleep(TICK_SLEEP)
    finally:
        db.remove()
Example #12
0
def wind_down(exchange_name, strategy_params, execute=False):
    db = session.get_a_trading_db_mysql_session()

    try:
        strategy = Strategy(
            make_exchange_from_key(exchange_name),
            db,
            debug=False,
            backtest=False,
            execute=execute,
            params=strategy_params,
        )

        harness = Harness(strategy, db)
        harness.wind_down()
    finally:
        session.commit_mysql_session(db)
        db.remove()
def test_fast_profit():
    db = session.get_a_trading_db_mysql_session()

    for i in range(1, 30):
        start, end = get_random_period()

        print '%s, %s' % (start, end)

        slow_profit = gryphon_profit.profit_in_period(db, start, end)
        fast_profit = gryphon_profit.fast_profit_in_period(db, start, end)

        result = (slow_profit.round_to_decimal_places(4) ==
                  fast_profit.round_to_decimal_places(4))

        if not result:
            print 'BAD: %s, != %s' % (slow_profit, fast_profit)
        else:
            print 'GOOD: %s, == %s' % (slow_profit, fast_profit)

    db.remove()
def test_fast_revenue():
    db = session.get_a_trading_db_mysql_session()

    for i in range(1, 30):
        start, end = get_random_period()

        print '%s, %s' % (start, end)

        slow_revenue = gryphon_profit.revenue_in_period(db, start, end)
        fast_revenue = gryphon_profit.fast_revenue_in_period(db, start, end)

        # These numbers will be off by tiny fractions due to rounding differences
        # between python and sql. Four decimal places of precision here (1/100th of
        # a cent, is good enough.
        result = (slow_revenue.round_to_decimal_places(4) ==
                  fast_revenue.round_to_decimal_places(4))

        if not result:
            print 'BAD: %s, != %s' % (slow_revenue, fast_revenue)
        else:
            print 'GOOD: %s, == %s' % (slow_revenue, fast_revenue)

    db.remove()
Example #15
0
def fix_balance_issues_for_exchange(exchange_name, execute=False):
    db = session.get_a_trading_db_mysql_session()
    exchange = exchange_factory.make_exchange_from_key(exchange_name)

    if not exchange:
        raise Exception('No exchange %s' % exchange_name)

    exchange_balance = exchange.get_balance()

    reset_balance_for_exchange_in_currency(
        db,
        exchange,
        exchange_balance,
        exchange.currency,
        execute,
    )

    reset_balance_for_exchange_in_currency(
        db,
        exchange,
        exchange_balance,
        exchange.volume_currency,
        execute,
    )
Example #16
0
# There's a bizarre bug I haven't had time to investigate whereby if we import
# Delorean in order with the rest of the 3rd party libaries, our time_parsing lib
# doesn't work. This only happens in the console. Bizarre.
from delorean import Delorean

logger = get_logger(__name__)

NO_GDS_ERROR = """\
Couldn't get a gds session. Probably missing credentials or GDS isn't set up.\
"""

# Load the contents of the .env.
environment.load_environment_variables()

# Create oft-used database objects.
trading_db = session.get_a_trading_db_mysql_session()

try:
    gds_db = session.get_a_gds_db_mysql_session()
except Exception as e:
    logger.info(NO_GDS_ERROR)

# Create the oft-used exchange connection shortcuts.
console_shortcuts = {
    'COINBASE_BTC_USD': 'cb',
    'BITSTAMP_BTC_USD': 'b',
    'BITSTAMP_BTC_EUR': 'be',
    'BITSTAMP_BCH_USD': 'bbch',
    'BITSTAMP_BCH_EUR': 'bbche',
    'BITSTAMP_BCH_BTC': 'bbchb',
    'BITSTAMP_ETH_EUR': 'bee',
Example #17
0
def manual_accounting(exchange_name, order_id, actor, execute=False):
    if actor not in EXPECTED_ACTORS:
        logger.warning(tc.colored(ACTOR_WARNING, color='yellow'))

    db = session.get_a_trading_db_mysql_session()

    try:
        exchange = make_exchange_from_key(exchange_name)
        exchange_data = make_exchange_data_from_key(exchange_name, db)

        vol_currency_key = '%s_total' % exchange.volume_currency.lower()

        try:
            exchange.cancel_order(order_id)
        except CancelOrderNotFoundError:
            pass

        details = exchange.get_order_details(order_id)

        unit_price = details['fiat_total'] / details[vol_currency_key].amount

        try:
            order = db.query(Order)\
                .filter(Order.exchange_order_id == order_id)\
                .filter(Order._exchange_name == exchange.name)\
                .one()

            order.time_created = epoch(details['time_created']).naive
            action = 'Updated'
        except sqlalchemy.orm.exc.NoResultFound:
            order = Order(
                actor,
                details['type'],
                details[vol_currency_key],
                unit_price,
                exchange,
                order_id,
            )

            order.time_created = epoch(details['time_created']).naive
            order.exchange_rate = Money('1',
                                        exchange.currency).to('USD').amount
            action = 'Added'

        position_change, position_change_no_fees = order.was_eaten(details)

        old_balance = exchange_data.balance[exchange.volume_currency]

        for currency_code, position in position_change.iteritems():
            exchange_data.position[currency_code] += position
            exchange_data.balance[currency_code] += position

        logger.info(
            'Order: %s for %.4f @ %.2f',
            order.order_type,
            order.volume,
            order.price,
        )

        for trade in order.trades:
            logger.info(
                'Trade: %s for %.4f @ %.2f',
                trade.trade_type,
                trade.volume,
                trade.price,
            )

        if execute:
            db.add(order)
            db.add(exchange_data)
            session.commit_mysql_session(db)

            logger.info(
                tc.colored(
                    '%s order #%s and its %s trade(s)' %
                    (action, order_id, len(details['trades'])),
                    'green',
                ))

            logger.info(
                tc.colored(
                    'Updated balance from %s to %s' %
                    (old_balance,
                     exchange_data.balance[exchange.volume_currency]),
                    'green',
                ))

        else:
            logger.info(
                tc.colored(
                    'pass --execute to save this order to the db',
                    'red',
                ))

    finally:
        db.remove()
Example #18
0
def live_run(configuration):
    strategy_name = configuration['platform']['strategy']
    is_builtin_strategy = configuration['platform']['builtin']
    execute = configuration['platform']['execute']

    logger.info('live_run(%s, %s)' % (strategy_name, execute))

    db = session.get_a_trading_db_mysql_session()

    harness = Harness(db, configuration)

    strategy_class = get_strategy_class(strategy_name, is_builtin_strategy)
    strategy = strategy_class(db, harness, configuration['strategy'])
    strategy.set_up()

    harness.strategy = strategy

    if execute:
        EventRecorder().create(db=db)
        DatumRecorder().create(db=db)
    else:
        EventRecorder().create()
        DatumRecorder().create()

    sentry = Sentry(configuration['platform']['sentry'])
    heartbeat = Heartbeat(configuration['platform']['heartbeat'])

    try:
        tick_count = 0

        while True:
            try:
                tick_start = Delorean().epoch
                print '\n\n%s' % strategy.name

                if warm_shutdown_flag:
                    return  # This takes us into the finally block.

                # Initial audit. This is done inside the main loop so that our robust
                # exception catching kicks in on initial audit failures.
                if harness.audit is True and tick_count == 0:
                    # We try a fast audit (no wind down) since the bots usually start
                    # from a clean slate.
                    try:
                        harness.full_audit(wind_down=False)
                    except AuditException:
                        logger.info(
                            'Bot was not cleanly shut down, winding down and auditing',
                        )

                        harness.full_audit(wind_down=True)

                # Regular audits.
                if (harness.audit is True and tick_count > 0
                        and tick_count % harness.audit_tick == 0):
                    harness.full_audit()
                else:
                    harness.tick()

                    harness.post_tick(tick_count)

                tick_profiling.record_tick_data(tick_start, strategy.name)
                tick_profiling.record_tick_block_data(
                    strategy,
                    tick_count,
                    strategy.name,
                )

                heartbeat.heartbeat(strategy.name)

            except Exception as e:
                sentry.captureException()

                logger.exception(
                    tc.colored(
                        '[%s] %s' % (e.__class__.__name__, e.message),
                        'red',
                    ))

                exception_retry_loop(harness, sentry, db)
            finally:
                session.commit_mysql_session(db)
                tick_count += 1

            if harness.strategy_complete() is True:
                break
            else:
                gentle_sleep(harness.sleep_time_to_next_tick())
    finally:
        warm_shutdown(harness, db, sentry, execute)
        session.commit_mysql_session(db)
        db.remove()

        if restart_flag:
            restart()