Exemple #1
0
    def __init__(self, key, sec):
        Thread.__init__(self)

        self._core = MtGoxCore(key, sec)
        # start with a clean order book
        logger.info('Initialising; Swiping order book...')
        while True:
            data = self._core.orders()
            oids = map(lambda o: o['oid'],
                       data['orders']
                       )
            logger.debug(oids)
            if oids == []:
                break
            map(self._core.cancel, oids)
        logger.info('Order book is clean')

        self._orders = {}
        self._balance = convert.balance(data)
        self._lock = Lock()
        self._running = False
        logger.info('Initialisation done!')
Exemple #2
0
import time

from mtgoxcore import MtGoxCore
from tradehillcore import TradehillCore
from decimal import Decimal

GOXFEE = Decimal("0.0053")
HILFEE = Decimal("0.0054")  # Referral code

gox = MtGoxCore()
hil = TradehillCore()

while True:
    goxtick = gox.ticker()["ticker"]
    hiltick = hil.ticker()["ticker"]
    goxsell = Decimal(goxtick["buy"]) * (1 - GOXFEE)
    goxbuy = Decimal(goxtick["sell"]) / (1 - GOXFEE)
    hilsell = Decimal(hiltick["buy"]) * (1 - HILFEE)
    hilbuy = Decimal(hiltick["sell"]) / (1 - HILFEE)
    if hilbuy < goxsell:
        print time.ctime(time.time())
        print "  Buy on Tradehill for %.3f, sell on MtGox for %.3f --\
 make %.2f%% profit!" % (
            hilbuy,
            goxsell,
            100 * (goxsell - hilbuy) / hilbuy,
        )
    if goxbuy < hilsell:
        print time.ctime(time.time())
        print "  Buy on MtGox for %.3f, sell on Tradehill for %.3f --\
 make %.2f%% profit!" % (
Exemple #3
0
# logging.basicConfig(
#     format = '%(name)-12s: %(message)s',
#     )
# logging.getLogger('MtGoxCore').setLevel(logging.DEBUG)
# logging.getLogger('MtGox').setLevel(logging.DEBUG)


import time, convert, pynotify, logging

from mtgoxcore import MtGoxCore
from config import KEY, SEC
from decimal import Decimal

FEE = Decimal('0.0043')

gox = MtGoxCore(KEY, SEC)
bal = convert.balance(gox.balance())
#bal = {'btcs': Decimal(40), 'usds': Decimal(0)}
while True:
    try:
        tic = convert.ticker(gox.ticker())
        newbal = convert.balance(gox.balance())

        last = tic['last']
        buy = tic['sell']
        sell = tic['buy']
        usds = bal['usds']
        btcs = bal['btcs']
        newusds = newbal['usds']
        newbtcs = newbal['btcs']
        valusds = (1 - FEE) * newbtcs * last + newusds
Exemple #4
0
class MtGox(Thread):
    def __init__(self, key, sec):
        Thread.__init__(self)

        self._core = MtGoxCore(key, sec)
        # start with a clean order book
        logger.info('Initialising; Swiping order book...')
        while True:
            data = self._core.orders()
            oids = map(lambda o: o['oid'],
                       data['orders']
                       )
            logger.debug(oids)
            if oids == []:
                break
            map(self._core.cancel, oids)
        logger.info('Order book is clean')

        self._orders = {}
        self._balance = convert.balance(data)
        self._lock = Lock()
        self._running = False
        logger.info('Initialisation done!')

    def run(self):
        self._running = True
        logger.info('Syncronisation thread started (hi mom!)')
        while self._running:
            self._sync()
            time.sleep(INTERVAL)
        logger.info('Ending syncronisation thread')

    def stop(self):
        self._running = False

    def _sync(self):
        # logger.info('Syncronising orders...')
        # logger.debug('Acquiring lock...')
        self._lock.acquire()
        # logger.debug('Lock acquired!')
        if self._orders == {}:
            # logger.info('Nothing to do; Syncronisation done!')
            # logger.debug('Releasing lock')
            self._lock.release()
            return
        logger.info('Syncronising orders...')
        def index(orders):
            bids = {}
            asks = {}
            for o in orders:
                p = o['price']
                if o['type'] == 'bid':
                    d = bids
                else:
                    d = asks
                if not p in d:
                    d[p] = []
                d[p].append(o)
            return (bids, asks)
        def sum_amounts(xs):
            return sum(map(lambda x: x['amount'], xs))
        def tot_amounts(xs):
            return sum(map(sum_amounts, xs.values()))
        def partition(orders):
            live = []
            dead = []
            now = time.time()
            for o in orders:
                if o['status'] != 'open':
                    dead.append(o)
                elif o['ttl'] is not None and \
                        o['date'] + o['ttl'] < now:
                    o['status'] = 'timed_out'
                    dead.append(o)
                else:
                    live.append(o)
            f = lambda x: x['date']
            return (sorted(live, key = f),
                    sorted(dead, key = f))
        def callback(o, f, *args):
            logger.debug('Callback for %s: %s%s' % (o['oid'], f, repr(args)))
            try:
                o['callbacks'][f](o, *args)
            except Exception, e:
                logger.debug('Callback %s for order %s failed: %s' % (f, o['oid'], e))
                pass

        cancelled = None
        data = self._core.orders()
        orders = convert.orders(data)
        balance = convert.balance(data)
        while True:
            logger.debug('Building indexes')
            logger.debug('Orderbook from MtGox: %s' % data)
            (oldbids, oldasks) = index(self._orders.values())
            (oldbtcs, oldusds) = (self._balance['btcs'], self._balance['usds'])
            (newbids, newasks) = index(orders)
            (newbtcs, newusds) = (balance['btcs'], balance['usds'])

            # check for cancelation
            if cancelled is not None:
                logger.debug('Checking if %s was cancelled' % cancelled['oid'])
                bought = tot_amounts(oldbids) - tot_amounts(newbids)
                sold = tot_amounts(oldasks) - tot_amounts(newasks)
                delta1 = bought * (1 - BUY_FEE) - sold * (1 - SELL_FEE)
                if cancelled['type'] == 'bid':
                    delta2 = (bought - cancelled['amount']) * (1 - BUY_FEE) - \
                        sold * (1 - SELL_FEE)
                    d = oldbids
                    f = self._core.buy
                else:
                    delta2 = bought * (1 - BUY_FEE) - \
                        (sold - cancelled['amount']) * (1 - SELL_FEE)
                    d = oldasks
                    f = self._core.sell
                real_delta = newbtcs - oldbtcs
                logger.debug('Sold %.2f -- Bough %.2f' % (sold, bought))
                logger.debug('Deltas: not cancelled %.2f -- cancelled %.2f -- real %.2f' % (delta1, delta2, real_delta))
                if abs(abs(delta1) - abs(real_delta)) > abs(abs(delta2) - abs(real_delta)):
                    # Was cancelled - prune local orders
                    logger.debug('Order was cancelled: %s at %.2f USD' % (cancelled['oid'], cancelled['price']))
                    (live, dead) = partition(d[cancelled['price']])
                    logger.debug('Live: %s', live)
                    logger.debug('Dead: %s', dead)
                    dead_left = False
                    for o in dead:
                        if cancelled['amount'] >= o['amount']:
                            oid = o['oid']
                            cancelled['amount'] -= o['amount']
                            o['cancelled_amount'] = o['amount']
                            o['amount'] = Decimal(0)
                            if o['status'] == 'timed_out':
                                callback(o, 'onTimeout')
                            else:
                                callback(o, 'onCancel')
                            del self._orders[oid]
                            continue
                        if not cancelled['amount'].is_zero():
                            o['cancelled_amount'] += cancelled['amount']
                            o['amount'] -= cancelled['amount']
                        dead_left = True
                        break
                    # If the cancelled amount was too large:
                    if not dead_left and not cancelled['amount'].is_zero():
                        logger.debug('Cancelled order too large; replacing...')
                        f(cancelled['amount'], cancelled['price'])
                        logger.debug('Done!')
                    cancelled = None
                    continue # rebuild indexes
                else:
                    logger.debug('Order was not cancelled: %s as %.2f USD' % (cancelled['oid'], cancelled['price']))
                    # Was not cancelled - do nothing
                    cancelled = None

            # check for progress and/or filled orders
            try:
                price = (oldusds - newusds) / (newbtcs - oldbtcs)
            except:
                price = Decimal(0)
            def process(old, new):
                logger.debug('Processing orders...')
                logger.debug('Old: %s', old)
                logger.debug('New: %s', new)
                to_cancel = []
                for (p, os) in old.items():
                    logger.debug('Processing at price %.2f USD', p)
                    oldamount = sum_amounts(os)
                    if p in new:
                        newamount = sum_amounts(new[p])
                    else:
                        newamount = Decimal(0)
                    amount = oldamount - newamount
                    (live, dead) = partition(os)
                    os = live + dead
                    logger.debug('Bought %.2f BTC', amount)
                    logger.debug('Orders to process: %s', os)
                    for o in os:
                        oid = o['oid']
                        if o['amount'] <= amount:
                            # filled
                            amount -= o['amount']
                            a = o['amount']
                            o['filled_amount'] += o['amount']
                            o['amount'] = Decimal(0)
                            callback(o, 'onProgress', a, price)
                            callback(o, 'onFilled')
                            del self._orders[oid]
                            continue
                        if not amount.is_zero():
                            # part filled
                            o['filled_amount'] += amount
                            o['amount'] -= amount
                            callback(o, 'onProgress', amount, price)
                        if o['status'] is not 'open':
                            # we're processing non-open orders -- cancel!
                            logger.debug('Need to cancel at price %.2f' % p)
                            logger.debug('Candidates for cancelation: %s', new[p])
                            to_cancel += new[p]
                        break
                logger.debug('Processing done!')
                return to_cancel
            to_cancel = \
                process(oldbids, newbids) + \
                process(oldasks, newasks)
            # we're now up to date
            logger.debug('Old balance was: %s', self._balance)
            self._balance = balance
            logger.debug('New balance is: %s', self._balance)

            # check for orders to cancel
            if to_cancel == []:
                logger.info('Nothing to cancel; Synchronisation done!')
                break
            # pick 'invalid' orders first, then 'open', last 'pending'
            def key(x):
                s = x['status']
                if s == 'invalid':
                    return 0
                elif s == 'open':
                    return 1
                elif s == 'pending':
                    return 2
                return 0
            random.shuffle(to_cancel) # avoid always going for lowest bid
            cancelled = sorted(to_cancel, key = key)[0]
            # cancelled = to_cancel[random.randrange(0, len(to_cancel))]
            logger.debug('Cancelling order: %s at %.2f USD' % (cancelled['oid'], cancelled['price']))
            data = self._core.cancel(cancelled['oid'])
            orders = convert.orders(data)
            balance = convert.balance(data)
        #end while
        logger.debug('Releasing lock')
        self._lock.release()
Exemple #5
0
from mtgoxcore import MtGoxCore
from config import KEY, SEC

import time, json

gox = MtGoxCore(KEY, SEC)

file_raw = 'history.raw.json'
file_prices = 'history.prices.pickled'

try:
    with open(file_raw) as f:
        print "Reading saved trades from disk"
        trades = json.load(f)
        since = trades[-1]['tid']
        print "Read %d trades from disk" % len(trades)
except:
    since = 0
    trades = []

while True:
    t = gox.trades(since)
    print "%s -- %s" % (time.ctime(t[0]['date']), time.ctime(t[-1]['date']))
    trades = trades + t
    if len(t) < 100:
        break
    since = t[-1]['tid']

with open(file_raw, 'w') as f:
    print "Writing %d trades to disk" % len(trades)
    json.dump(trades, f)