示例#1
0
def main(script_arguments, execute):
    exchange_name = script_arguments['exchange'].upper()
    start_str = script_arguments['start']
    end_str = script_arguments['end']

    start_time = parse(start_str).datetime
    end_time = parse(end_str).datetime

    export_ledger_for_exchange(exchange_name, start_time, end_time)
示例#2
0
    def test_creation_with_times(self):
        l = Liability(
                Money('100', 'ETH'),
                Liability.FIXED_INTEREST,
                'John',
                time_started=parse('2016-10-1').datetime,
                time_repayed=parse('2016-11-1').datetime,
        )

        l.time_started.should.equal(parse('2016-10-1').datetime)
        l.time_repayed.should.equal(parse('2016-11-1').datetime)
        l.amount.should.equal(Money('100', 'ETH'))
        l.entity_name.should.equal('John')
示例#3
0
    def _get_recent_trades_resp(self, req, return_pagination=False):
        response, headers = self.resp(req)
        trades = []

        for trade in response:
            if not trade['settled']:
                continue

            price = Money(trade['price'], self.currency)
            size = Money(trade['size'], 'BTC')
            fiat = price * size.amount
            our_type = self._order_mode_to_const(trade['side'])

            # Strange bug here, delorean isn't parsing the trailing Z on the created_at
            # date correctly.
            trade_dict = {
                'time': int(parse(trade['created_at'][:-1]).epoch),
                'trade_id': str(trade['trade_id']),
                'order_id': str(trade['order_id']),
                'btc': size,
                'fiat': fiat,
                'fee': Money(trade['fee'], self.currency),
                'type': our_type,
            }

            trades.append(trade_dict)

        if return_pagination:
            return trades, self.pagination_cursors(headers)
        else:
            return trades
示例#4
0
文件: bmo.py 项目: zlex7/gryphon
    def get_transactions_from_page(self, account):
        """
        Parses out records from a transactions page.

        Assumes the driver has already navigated to a transactions page.
        """
        logger.debug('get_transactions_from_page')

        account_num = account['account_number']
        account_currency = account['balance'].currency

        self.wait_for_text_on_page('Transaction History')
        self.wait_for_text_on_page('Balance Forward')

        # We need to look for the specific account number because the wait_for_text checks above
        # can match on the transactions page we were previously on
        logger.debug('waiting for account number to match %s' % account_num)
        WebDriverWait(self.driver, 10).until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.bodyCopy .cardNumber'), account_num))

        transaction_selector = '#ccChequingTransactionTable tbody tr'
        transaction_els = self.driver.find_elements_by_css_selector(transaction_selector)
        transaction_els.pop(0) # drop the Balance Forward row

        transactions = []

        for el in transaction_els:
            date = el.find_element_by_css_selector('td:nth-child(1)').text
            code = el.find_element_by_css_selector('td:nth-child(2)').text
            description = el.find_element_by_css_selector('td:nth-child(3)').text
            raw_debit = el.find_element_by_css_selector('td:nth-child(4)').text
            raw_credit = el.find_element_by_css_selector('td:nth-child(5)').text
            raw_balance = el.find_element_by_css_selector('td:nth-child(6)').text

            if raw_debit and raw_credit:
                raise Exception('Only one of debit and credit fields should be present')
            elif not raw_debit and not raw_credit:
                raise Exception('One of debit and credit fields should be present')
            elif raw_debit:
                debit = self.string_to_money(raw_debit + ' ' + account_currency)
                amount = debit
                transaction_type = Transaction.WITHDRAWL
            elif raw_credit:
                credit = self.string_to_money(raw_credit + ' ' + account_currency)
                amount = credit
                transaction_type = Transaction.DEPOSIT

            balance = self.string_to_money(raw_balance + ' ' + account_currency)

            timestamp = int(parse(date).epoch)

            transactions.append({
                'timestamp': timestamp,
                'description': description,
                'amount': amount,
                'type': transaction_type,
                # 'code': code,
                # 'balance': balance,
            })

        return transactions
示例#5
0
    def get_multi_order_details_resp(self, req, order_ids):
        order_ids = [unicode(o) for o in order_ids]

        multi_trades = self.trades_for_orders_resp(req, order_ids)
        data = {}

        for order_id in order_ids:
            total_price_currency = Money('0', self.currency)
            total_volume_currency = Money('0', self.volume_currency)
            our_trades = []
            our_type = None

            price_currency_key = self.currency.lower()
            vol_currency_key = self.volume_currency.lower()

            if order_id in multi_trades:
                trades = multi_trades[order_id]

                for t in trades:
                    volume_currency_amount = abs(
                        Money(t[vol_currency_key], self.volume_currency),
                    )

                    fee = abs(Money(t['fee'], self.currency))

                    price_currency_amount = abs(
                        Money(t[price_currency_key], self.currency),
                    )

                    total_price_currency += price_currency_amount
                    total_volume_currency += volume_currency_amount

                    if Decimal(t[vol_currency_key]) > 0:
                        our_type = Consts.BID
                    else:
                        our_type = Consts.ASK

                    our_trades.append({
                        'time': int(parse(t['datetime']).epoch),
                        'trade_id': unicode(t['id']),
                        'fee': fee,
                        vol_currency_key: volume_currency_amount,
                        'fiat': price_currency_amount,
                    })

            try:
                time_created = min([t['time'] for t in our_trades])
            except ValueError:  # This is raised if there are no trades.
                time_created = None

            data[order_id] = {
                'time_created': time_created,
                'type': our_type,
                '%s_total' % vol_currency_key: total_volume_currency,
                'fiat_total': total_price_currency,
                'trades': our_trades,
            }

        return data
示例#6
0
    def get_multi_order_details_resp(self, req, order_ids):
        # This is modeled after Bitstamp, where we get the order details from the
        # trades endpoint directly. The caveat is that order_details will only work
        # for the most recent 50 trades. Since we are always accounting trades right
        # after they happen, this should be ok (and also affects Bitstamp).
        order_ids = [str(o) for o in order_ids]

        multi_trades = self.trades_for_orders_resp(req, order_ids)
        data = {}

        for order_id in order_ids:
            total_usd = Money('0', 'USD')
            total_btc = Money('0', 'BTC')

            our_trades = []
            our_type = None

            if order_id in multi_trades:
                trades = multi_trades[order_id]

                for t in trades:
                    assert (t['currency1'] == 'XBT')
                    btc_amount = Money(t['currency1Amount'], 'BTC')

                    assert (t['currency2'] == 'USD')
                    usd_amount = Money(t['currency2Amount'], 'USD')

                    # This might also come back as XBT, but since ItBit has 0-fee
                    # trading right now, I can't tell.
                    assert (t['commissionCurrency'] == 'USD')
                    fee = Money(t['commissionPaid'], 'USD')

                    total_usd += usd_amount
                    total_btc += btc_amount

                    our_type = self._order_mode_to_const(t['direction'])

                    our_trades.append({
                        'time': parse(t['timestamp']).epoch,
                        'trade_id': None,
                        'fee': fee,
                        'btc': btc_amount,
                        'fiat': usd_amount,
                    })

            time_created = None

            if our_trades:
                time_created = min([t['time'] for t in our_trades])

            data[order_id] = {
                'time_created': time_created,
                'type': our_type,
                'btc_total': total_btc,
                'fiat_total': total_usd,
                'trades': our_trades
            }

        return data
示例#7
0
    def generate_data(self):
        gds_active = self.is_gds_connection_active()

        if gds_active is False:
            return self.generate_null_data()

        # Get query string parameters.
        query_string_high = self.get_argument('high', None)
        query_string_low = self.get_argument('low', None)
        show_orders = self.get_argument('show_orders', False) != False
        at_time = self.get_argument('at_time', None)
        no_lookback_limit = self.get_argument('no_lookback_limit', None)

        selected_exchanges = self.get_active_exchanges(self.trading_pair_names)

        # Some simple formatting of our query string parameters.
        self.no_lookback_limit = True if no_lookback_limit else False

        if at_time:
            at_time = parse(at_time).datetime

        # Get the data.
        open_orders_for_exchange = {}

        open_orders_for_exchange = self.get_open_orders_by_exchange(at_time)

        levels_for_exchange, low_bid, high_ask = self.get_orderbook_levels(
            self.gds_db,
            self.trading_pairs,
            at_time,
            selected_exchanges,
        )

        levels_for_exchange = self.format_levels_for_graphing(
            levels_for_exchange)

        high, low = self.determine_graph_default_range(
            query_string_high,
            query_string_low,
            low_bid,
            high_ask,
            open_orders_for_exchange,
        )

        args = {
            'gds_active': gds_active,
            'levels_for_exchange': levels_for_exchange,
            'selected_exchanges': selected_exchanges,
            'open_orders_for_exchange': open_orders_for_exchange,
            'high': high,
            'low': low,
            'pair_name': self.pair_name,
            'show_orders': show_orders,
            'at_time': None if not at_time else at_time.isoformat(),
        }

        return args
示例#8
0
    def test_creation_with_details(self):
        l = Liability(
                Money('100', 'ETH'),
                Liability.FIXED_INTEREST,
                'John',
                time_started=parse('2016-10-1').datetime,
                details={'interest_rate': 0.05},
        )

        l.details['interest_rate'].should.equal(0.05)
def compare_ours_to_history(our_exchange_id, exchange, price_currency, volume_currency='BTC'):
    hist_trades = get_historical_trades(
        exchange.lower(),
        price_currency, volume_currency,
    )
    our_trades = get_our_recorded_trades(our_exchange_id.upper())

    start = parse('2015-11-27 0:0:0').datetime.replace(tzinfo=None)
    end = parse('2015-11-27 11:59:59').datetime.replace(tzinfo=None)

    print our_exchange_id.upper()
    hist_in_range = [t for t in hist_trades if t[0] >= start and t[0] <= end]
    ours_in_range = [t for t in our_trades if t[0] >= start and t[0] <= end]

    for t in hist_in_range:
        if t not in ours_in_range:
            print 'Hist Trade not in ours: %s' % t

    for t in ours_in_range:
        if t not in hist_in_range:
            print'Our trade not in history: %s' % t
    print'\n\n\n\n\n'
示例#10
0
    def parse_trades(self, resp_obj):
        trades = []

        for trade in resp_obj:
            trade = {
                'exchange': self.exchange_name,
                'price': Money(trade['price'], 'CAD'),
                'volume': Money(trade['size'], 'BTC'),
                'timestamp': parse(trade['time']).epoch,
                'trade_id': trade['trade_id'],
            }

            trades.append(trade)

        return trades
示例#11
0
文件: shoebox.py 项目: zlex7/gryphon
def money_moving():
    current_time = Delorean().datetime

    morning_timeslot = parse('9am -0800').datetime  # when we get up in PST
    afternoon_timeslot = parse(
        '3:30pm -0500').datetime  # 4pm EST is BMO's wire cutoff

    in_morning_timeslot = (current_time.hour == morning_timeslot.hour
                           and current_time.minute == morning_timeslot.minute)

    in_afternoon_timeslot = (current_time.hour == afternoon_timeslot.hour and
                             current_time.minute == afternoon_timeslot.minute)

    if in_morning_timeslot or in_afternoon_timeslot:
        on_call_dev = get_on_call_dev()
        channel = '@%s' % on_call_dev

        if in_morning_timeslot:
            message = 'Time for early morning money moving!'
        elif in_afternoon_timeslot:
            message = 'Time for afternoon money moving! (Wire cutoff is 4pm EST)'

        slacker = Slacker(channel, 'mover', icon_emoji=':moneybag:')
        slacker.notify(message)
示例#12
0
    def get_start_time_and_end_time(self,
                                    default_start=None,
                                    default_end=None):
        start = self.get_argument('start', None)
        end = self.get_argument('end', None)

        start_time = None
        end_time = None

        if start:
            start_time = parse(start).datetime
        elif default_start:
            start_time = default_start
        else:
            start_time = Delorean().truncate('day').datetime

        if end:
            end_time = parse(end).datetime
        elif default_end:
            end_time = default_end
        else:
            end_time = Delorean(start_time, 'UTC').next_day(1).datetime

        return start_time, end_time
示例#13
0
    def parse_trades(self, resp_obj):
        raw_trades = resp_obj['recentTrades']
        trades = []

        for raw_trade in raw_trades:
            trade = {
                'exchange': self.exchange_name,
                'price': Money(raw_trade['price'], 'USD'),
                'volume': Money(raw_trade['amount'], 'BTC'),
                'timestamp': parse(raw_trade['timestamp']).epoch,
                'trade_id': raw_trade['matchNumber'],
            }

            trades.append(trade)

        return trades
示例#14
0
    def get_order_details_resp(self, reqs):
        try:
            raw_order, headers = self.resp(reqs['order'])
        except exceptions.NoEffectOrderCancelledError:
            # Coinbase returns an API Error with the text "NotFound" in it when
            # querying orders that were cancelled with no trades, so we return an empty
            # order here if that is the response.
            result = {
                'time_created': None,
                'type': None,
                'btc_total': Money('0', self.volume_currency),
                'fiat_total': Money('0', self.currency),
                'trades': [],
            }

            return result

        # This already has the results (see above) so we don't need to .resp() it
        our_trades = reqs['trades']

        mode = self._order_mode_to_const(raw_order['side'])
        total_btc = Money(raw_order['filled_size'], 'BTC')
        time_created = int(parse(raw_order['created_at']).epoch)
        total_fiat = Money('0', self.currency)

        for t in our_trades:
            total_fiat += t['fiat']

        result = {
            'time_created': time_created,
            'type': mode,
            'btc_total': total_btc,
            'fiat_total': total_fiat,
            'trades': our_trades
        }

        return result
示例#15
0
from gryphon.lib.models.emeraldhavoc.trade import Trade as EHTrade
from gryphon.lib.money import Money
from gryphon.lib.time_parsing import parse

# this is a hack for now because we don't have consistent data
# sources for the other exchanges, and I don't want to dirty
# gryphon.lib's commit history with something like this.
exchanges_with_volume_sources = [
    'cavirtex',
    'kraken',
    'bitstamp',
    'bitfinex',
    'vaultofsatoshi',
]

EARLIEST_TICKER_ENTRY = parse('2015-11-13 19:30').datetime
EARLIEST_TRADE_ENTRY = parse('2015-11-25 23:59').datetime

# Functions for getting a single exchange's volume


def get_single_exchange_volume_in_period(tc_db, exchange_name, start_time,
                                         end_time):
    if is_past_single_day(start_time,
                          end_time) and start_time > EARLIEST_TICKER_ENTRY:
        return get_single_exchange_volume_on_day_from_db_tickers(
            tc_db,
            exchange_name,
            start_time,
        )
    elif start_time > EARLIEST_TRADE_ENTRY:
示例#16
0
def audit_all_bw_volume(exchange_list):
    start_date = parse('2015-12-01').datetime
    end_date = parse('2015-12-15').datetime
    for exchange in exchange_list:
        audit_bw_volume(exchange, start_date, end_date)
示例#17
0
    'KRAKEN',
    'COINBASE',
    'COINBASE_CAD',
    'ITBIT',
    'CAVIRTEX',
    'QUADRIGA',
    #'COINSETTER',
]

bw_exchanges = [
    'BITSTAMP',
    'BITFINEX',
    'KRAKEN',
]

test_start_date = parse('2015-12-1').datetime
test_end_date = parse('2015-12-15').datetime

def backfill_trades(exchanges):
    for e in exchanges:
        trades = get_trades_to_backfill(e[0], e[1], e[2], e[3])
        write_trades_to_db(e[0], trades)


def get_trades_to_backfill(our_exchange_id, exchange, price_currency, volume_currency):
    our_trades = get_our_recorded_trades(our_exchange_id.upper())
    oldest_trade_timestamp = our_trades[0][0]
    historical_trades = get_historical_trades(exchange.lower(), price_currency, volume_currency)
    trades_to_add = [t for t in historical_trades if t[0] < oldest_trade_timestamp]

    # sort the trades to add in adding the most recent one first.
示例#18
0
from gryphon.lib.gryphonfury import positions
from gryphon.lib.logger import get_logger
from gryphon.lib.models.exchange import Exchange as ExchangeData
from gryphon.lib.models.exchange import Position
from gryphon.lib.models.liability import Liability
from gryphon.lib.models.order import Order
from gryphon.lib.models.trade import Trade
from gryphon.lib.models.transaction import Transaction
from gryphon.lib.money import Money
from gryphon.lib.time_parsing import parse

logger = get_logger(__name__)

# If your ledger is only accurate after a certain time, put it here, and ledger_balance
# requests earlier than this will throw an exception.
EARLIEST_CORRECT_LEDGER_DATE = parse('2015-01-01').datetime

# This number is used by the overwatch bot to determine if there is a bitcoin amount
# missing from our system.
# TODO:
#   - This should be configurable by the user. Since this is only used in overwatch,
#     maybe it should be part of an overwatch config.
#   - We should also be able to represent targets in all our supported cryptocurrencies
#     in this manner.
BTC_NET_ASSETS_TARGET = Money('0', 'BTC')

NO_BURN_ACCOUNT_WARNING = """\
There is no entry with the name 'BURN' in your exchange account table, so we won't\
be able to show non-trading expenses in the dashboard service. You can learn how to\
set this feature up in the framework documentation.\
"""
示例#19
0
 def _datetime_to_timestamp(self, dt_string):
     # As of 2015-12-01 13:00 UTC, quadriga timestamps are now in UTC
     # (with no warning or backwards compatability, of course)
     return int(parse(dt_string).epoch)