コード例 #1
0
ファイル: views.py プロジェクト: manosai/bitsurf
def send_payment(conn, bitcoin_address, user, curr_business, website,
                 new_total, amount, counter):
    transaction_dic = {}
    account = CoinbaseAccount(api_key=os.environ['coinbase_api_key'])
    bitcoin_address = sanitization(bitcoin_address)

    # send actual payment
    print "send_amount :", amount
    transaction = account.send(bitcoin_address, amount)
    transaction_dic['transaction_status'] = str(transaction.status)

    if str(transaction.status) == 'complete':
        counter += 1
        new_amount = (-30) * math.exp(counter - 20) + amount
        if new_amount < 0:
            new_amount = 0
        user['total_earned'] = str(float(user['total_earned']) + amount)
        user[website] = new_total
        curr_business['counter'] = str(counter)
        #calculate new rate
        curr_business['rate'] = str(new_amount)
        #subtract from funds
        curr_business['funds'] = str(float(curr_business['funds']) - amount)
    user.save()
    curr_business.save()
    transaction_dic['total_earned'] = user['total_earned']
    transaction_dic['capped'] = False
    json_response = json.dumps(transaction_dic)

    return HttpResponse(json_response)
コード例 #2
0
    def __init__(self,
                 api_key=None,
                 oauth2_credentials=None,
                 orderbook=None,
                 logname="traderlog.txt"):
        if (api_key is None) and (oauth2_credentials is None):
            raise ValueError("api_key and oauth2_credentials cannot be None")
        if (api_key is not None) and (oauth2_credentials is not None):
            raise ValueError(
                "User Provided both api_key and oauth2_credentials, select one"
            )  # I might want to instead just use one or the other

        with _traderIdLock:
            global TRADER_ID
            self.traderid = TRADER_ID
            TRADER_ID += 1

        self.orderbook = [] if orderbook is None else orderbook

        f = open(logname, 'w')
        f.close()
        self.logname = logname
        self.logwrite(str(datetime.now()) + '\n')

        self.account = CoinbaseAccount(oauth2_credentials, api_key)
コード例 #3
0
def with_oauth():
    # Don't actually set up oauth2 credentials, because this will fail if
    # we're testing under python3. Some day when we have an oauth2 client
    # that supports python 3, we can change this.
    a = CoinbaseAccount()
    a.authenticated = True
    a.auth_params = {}
    return a
コード例 #4
0
ファイル: coinbase_exchange.py プロジェクト: rozap/arb
class CoinbaseExchange(Exchange):

    def __init__(self, settings):
        super(CoinbaseExchange, self).__init__(settings)
        self._trading = CoinbaseAccount(api_key = settings['COINBASE']['api']['key'])


    '''
        How much can you buy a coin for, fee included for the exchange
    '''
    def _buy_price(self):
        price = self._trading.buy_price()
        return price



    '''
        How much can you get if you sell a coin, fee subtracted
    '''
    def _sell_price(self):
        price = self._trading.sell_price()
        return price
コード例 #5
0
ファイル: trader.py プロジェクト: iewnait/coinbase_trader
    def __init__(self,api_key = None, oauth2_credentials = None, orderbook = None, logname = "traderlog.txt"):
        if (api_key is None) and (oauth2_credentials is None):
            raise ValueError("api_key and oauth2_credentials cannot be None")
        if (api_key is not None) and (oauth2_credentials is not None):
            raise ValueError("User Provided both api_key and oauth2_credentials, select one")        # I might want to instead just use one or the other 

        
        self.orderbook = [] if orderbook is None else orderbook

        f = open(logname, 'w')
        f.close()
        self.logname = logname
        self.logwrite(str(datetime.now()) + '\n')

        self.account = CoinbaseAccount(oauth2_credentials,api_key)
コード例 #6
0
def guess_bitcoin(request):
    try:
        member_pay = Member_Pay.objects.filter(user=request.user).last()
        if member_pay:
            day_result = datetime.now() - member_pay.pay_date.replace(
                tzinfo=None)
            print day_result.days
            if member_pay.package == '1':
                if day_result.days > 30:
                    return HttpResponseRedirect('/pricing_table')
            else:
                if day_result.days > 365:
                    return HttpResponseRedirect('/pricing_table')
        else:
            return HttpResponseRedirect('/pricing_table')
    except Exception as e:
        print e
        return HttpResponseRedirect('/sorry')
    bitcoin_value = CoinbaseAccount().exchange_rates['btc_to_usd']
    btc_analyze = analyze()
    result_for_bitcoin = btc_analyze.guess_what()
    return render_to_response('guess_bitcoin.html',
                              locals(),
                              context_instance=RequestContext(request))
コード例 #7
0
ファイル: allPythonContent.py プロジェクト: Mondego/pyreco
 def setUp(self):
     self.account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)
コード例 #8
0
ファイル: allPythonContent.py プロジェクト: Mondego/pyreco
class CoinBaseLibraryTests(unittest.TestCase):

    def setUp(self):
        self.account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)

    @httprettified
    def test_retrieve_balance(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/balance",
                               body='''{"amount":"0.00000000","currency":"BTC"}''',
                               content_type='text/json')

        this(self.account.balance).should.equal(0.0)
        this(self.account.balance.currency).should.equal('BTC')

        #TODO:  Switch to decimals
        #this(self.account.balance).should.equal(CoinbaseAmount('0.00000000', 'USD'))
        #this(self.account.balance.currency).should.equal(CoinbaseAmount('0.00000000', 'USD').currency)

    @httprettified
    def test_receive_addresses(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/receive_address",
                               body='''{"address" : "1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt"}''',
                               content_type='text/json')

        this(self.account.receive_address).should.equal(u'1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt')

    @httprettified
    def test_contacts(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/contacts",
                               body='''{"contacts":[{"contact":{"email":"*****@*****.**"}}],"total_count":1,"num_pages":1,"current_page":1}''',
                               content_type='text/json')

        this(self.account.contacts).should.equal([{u'email': u'*****@*****.**'}])

    @httprettified
    def test_buy_price_1(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        buy_price_1 = self.account.buy_price(1)
        this(buy_price_1).should.be.an(float)
        this(buy_price_1).should.be.lower_than(100)
        this(buy_price_1.currency).should.equal('USD')

    @httprettified
    def test_buy_price_2(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=10",
                               body='''{"amount":"633.25","currency":"USD"}''',
                               content_type='text/json')

        buy_price_10 = self.account.buy_price(10)
        this(buy_price_10).should.be.greater_than(100)

    @httprettified
    def test_sell_price(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_1 = self.account.sell_price(1)
        this(sell_price_1).should.be.an(float)
        this(sell_price_1).should.be.lower_than(100)
        this(sell_price_1.currency).should.equal('USD')

    @httprettified
    def test_sell_price_10(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"630.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_10 = self.account.sell_price(10)
        this(sell_price_10).should.be.greater_than(100)

    @httprettified
    def test_request_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/request_money",
                               body='''{"success":true,"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}}''',
                               content_type='text/json')

        new_request = self.account.request('*****@*****.**', 1, 'Testing')

        this(new_request.amount).should.equal(1)
        this(new_request.request).should.equal(True)
        this(new_request.sender.email).should.equal('*****@*****.**')
        this(new_request.recipient.email).should.equal('*****@*****.**')
        this(new_request.notes).should.equal('Testing')

    @httprettified
    def test_send_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}    ''',
                               content_type='text/json')

        new_transaction_with_btc_address = self.account.send('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP', amount=0.1)

        this(new_transaction_with_btc_address.amount).should.equal(-0.1)
        this(new_transaction_with_btc_address.request).should.equal(False)
        this(new_transaction_with_btc_address.sender.email).should.equal('*****@*****.**')
        this(new_transaction_with_btc_address.recipient).should.equal(None)
        this(new_transaction_with_btc_address.recipient_address).should.equal('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP')

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b2920b974ea4cb000003","created_at":"2013-03-31T15:02:58-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}}
''',
                               content_type='text/json')

        new_transaction_with_email = self.account.send('*****@*****.**', amount=0.1)

        this(new_transaction_with_email.recipient.email).should.equal('*****@*****.**')

    @httprettified
    def test_transaction_list(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions",
                               body='''{"current_user":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"balance":{"amount":"0.00000000","currency":"BTC"},"total_count":4,"num_pages":1,"current_page":1,"transactions":[{"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514e4c1c802e1bef98000020","created_at":"2013-03-23T17:43:08-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514b9fb1b8377ee36500000d","created_at":"2013-03-21T17:02:57-07:00","hsh":"42dd65a18dbea0779f32021663e60b1fab8ee0f859db7172a078d4528e01c6c8","notes":"You gave me this a while ago. It's turning into a fair amount of cash and thought you might want it back :) Building something on your API this weekend. Take care!","amount":{"amount":"-1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}},{"transaction":{"id":"509e01cb12838e0200000224","created_at":"2012-11-09T23:27:07-08:00","hsh":"ac9b0ffbe36dbe12c5ca047a5bdf9cadca3c9b89b74751dff83b3ac863ccc0b3","notes":"","amount":{"amount":"1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"*****@*****.**"}}]}''',
                           content_type='text/json')

        transaction_list = self.account.transactions()

        this(transaction_list).should.be.an(list)

    @httprettified
    def test_getting_transaction(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions/5158b227802669269c000009",
                               body='''{"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":"223a404485c39173ab41f343439e59b53a5d6cba94a02501fc6c67eeca0d9d9e","notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}''',
                               content_type='text/json')

        transaction = self.account.get_transaction('5158b227802669269c000009')

        this(transaction.status).should.equal('pending')
        this(transaction.amount).should.equal(-0.1)

    @httprettified
    def test_getting_user_details(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/users",
                               body='''{"users":[{"user":{"id":"509f01da12837e0201100212","name":"New User","email":"*****@*****.**","time_zone":"Pacific Time (US & Canada)","native_currency":"USD","buy_level":1,"sell_level":1,"balance":{"amount":"1225.86084181","currency":"BTC"},"buy_limit":{"amount":"10.00000000","currency":"BTC"},"sell_limit":{"amount":"50.00000000","currency":"BTC"}}}]}''',
                               content_type='text/json')

        user = self.account.get_user_details()

        this(user.id).should.equal("509f01da12837e0201100212")
        this(user.balance).should.equal(1225.86084181)

    @httprettified
    def test_creating_a_button(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/buttons",
                               body='''{"button": {"style": "buy_now_large", "code": "b123456783q812e381cd9d39a5783277", "name": "Test Button", "info_url": null, "text": "Pay With Bitcoin", "price": {"cents": 2000, "currency_iso": "USD"}, "include_email": false, "custom": "", "cancel_url": null, "auto_redirect": false, "success_url": null, "variable_price": false, "include_address": false, "callback_url": null, "type": "buy_now", "choose_price": false, "description": ""}, "success": true}''',
                               content_type='text/json')

        button = self.account.create_button('Test Button', '20.00', 'USD')

        this(button.code).should.equal('b123456783q812e381cd9d39a5783277')
        this(button.name).should.equal('Test Button')
        this(button.price['cents']).should.equal(2000)
コード例 #9
0
class Trader(object):

    _orderbookLock = threading.Lock()
    _executeLock = threading.Lock()
    _stopTradeLock = threading.Lock()
    stopTrade = False

    def __init__(self,
                 api_key=None,
                 oauth2_credentials=None,
                 orderbook=None,
                 logname="traderlog.txt"):
        if (api_key is None) and (oauth2_credentials is None):
            raise ValueError("api_key and oauth2_credentials cannot be None")
        if (api_key is not None) and (oauth2_credentials is not None):
            raise ValueError(
                "User Provided both api_key and oauth2_credentials, select one"
            )  # I might want to instead just use one or the other

        with _traderIdLock:
            global TRADER_ID
            self.traderid = TRADER_ID
            TRADER_ID += 1

        self.orderbook = [] if orderbook is None else orderbook

        f = open(logname, 'w')
        f.close()
        self.logname = logname
        self.logwrite(str(datetime.now()) + '\n')

        self.account = CoinbaseAccount(oauth2_credentials, api_key)

    def logwrite(self, message):
        """
        Writes to the logfile with appended newline. 
        """
        with open(self.logname, 'a') as log:
            with _logwriteLock:
                log.write(message + '\n')

    def logexecution(self, order, result):
        """
        Write the result and order to the log file
        """
        self.logorder(order)
        logstr = "Order Type: " + str(result.type) + " Code: " + str(
            result.code) + " Executed at: " + str(result.created_at)
        logstr = logstr + "\nBTC Amount: " + str(
            result.btc_amount) + " Total Price: " + str(
                result.total_amount) + " Fees: " + str(result.fees_bank +
                                                       result.fees_coinbase)
        logstr = "Result of Order\n" + logstr
        self.logwrite(logstr)

    def logorder(self, order, header=None):
        """
        Writes the order the log file
        """
        logstr = header + '\n' if isinstance(header, str) else ''
        logstr = "OrderID: %s OrderType: %s Quantity: %s Price: %s" % (
            order.orderid, order.ordertype, order.qty, order.price)
        logstr = logstr + " Change Value: " + str(order.changeval)
        logstr = logstr + " Executed: " + str(order.executed) + '\n'
        if order.parentorder is not None:
            self.logorder(order.parentorder, "Parent Order:")
        self.logwrite(logstr)

    def ExecuteOrder(self, order):
        """
        Executes an order based on its order.ordertype
        Returns None if the trade is valid is not yet active(i.e limit not met)
        Returns a CoinbaseError or CoinbaseTransfer object if order attempted to execute
        Returns False if the order should be Deleted or removed from the orderbook. 
        """
        with self._executeLock:
            traderesult = None
            currentprice = -1

            if order.ordertype in [MARKET_BUY, LIMIT_BUY]:
                currentprice = self.account.buy_price(qty=order.qty)
                print "Current Buy Price: " + str(currentprice / order.qty)
            elif order.ordertype in [
                    MARKET_SELL, LIMIT_SELL, STOP_LOSS, TRAIL_STOP_VALUE,
                    TRAIL_STOP_PERCENT
            ]:
                currentprice = self.account.sell_price(qty=order.qty)
                print "Current Sell Price: " + str(currentprice / order.qty)

            if order.ordertype == MARKET_BUY:
                traderesult = self.account.buy_btc(qty=order.qty)
            elif order.ordertype == MARKET_SELL:
                traderesult = self.account.sell_btc(qty=order.qty)
            elif order.ordertype == LIMIT_BUY:
                if currentprice <= order.price:
                    traderesult = self.account.buy_btc(qty=order.qty)
            elif order.ordertype == LIMIT_SELL:
                if currentprice >= order.price:
                    traderesult = self.account.sell_btc(qty=order.qty)
            elif order.ordertype == STOP_LOSS:
                if currentprice <= order.price:
                    traderesult = CoinOrder(ordertype=MARKET_SELL,
                                            qty=order.qty,
                                            parentorder=order)
            elif order.ordertype == TRAIL_STOP_VALUE:
                if currentprice > order.price:
                    order.price = currentprice
                elif currentprice <= (order.price - order.changeval):
                    traderesult = CoinOrder(ordertype=MARKET_SELL,
                                            qty=order.qty,
                                            parentorder=order)
            elif order.ordertype == TRAIL_STOP_PERCENT:
                if currentprice > order.price:
                    order.price = currentprice
                elif currentprice <= (order.price * (1.0 - order.changeval)):
                    traderesult = CoinOrder(ordertype=MARKET_SELL,
                                            qty=order.qty,
                                            parentorder=order)
            else:
                traderesult = False  # deletes the order from the order book

        if isinstance(order.nextOrder, CoinOrder):
            if isinstance(traderesult, CoinbaseTransfer):
                traderesult = (traderesult, order.nextOrder)
            if isinstance(traderesult, CoinbaseError):
                print "Triggered Order Lost due to error"
        return traderesult

    def trade(self, runtime=None, sleeptime=60, startNewThread=False):
        """ 
        Call this function to execute trades in added to the order book. Returns True on success and Writes
        the specified log file.

        :param runtime: Number of seconds to trade should execute, infinity (None) is the default.
        :param sleeptime: Interval of time between checking orders (coinbase updates their prices once per 60 seconds)
        :param startNewThread: Optionally run trade in a new thread, orders can then be added while trade() runs (using the usual methods)
        """
        if startNewThread == True:
            newThread = threading.Thread(target=self.trade,
                                         args=[runtime, sleeptime, False])
            newThread.daemon = True
            newThread.start()
            return True

        with self._stopTradeLock:
            self.stopTrade = False
        initialBtcBal = self.account.balance
        initialUsdVal = self.account.sell_price(initialBtcBal)
        initialSellRate = initialUsdVal / initialBtcBal if initialBtcBal != 0 else 0
        self.logwrite("Initial BTC Balance: " + str(initialBtcBal) +
                      " Initial USD Value: " + str(initialUsdVal) +
                      " Price Per Coin: " + str(initialSellRate))
        while ((runtime is None) or
               (runtime > 0)) and (len(self.orderbook) > 0):

            with self._stopTradeLock:
                if self.traderid in _stoppedTraders:
                    _stoppedTraders.remove(self.traderid)
                    return True

            sleep = True
            temporderbook = []
            with self._orderbookLock:
                constantorderbook = self.orderbook

            for order in constantorderbook:
                result = self.ExecuteOrder(order)
                if isinstance(result, tuple):
                    # Append next order and process the trade result
                    temporderbook.append(result[1])
                    result = result[0]
                if result is False:
                    # Invalid Order ID, discard order
                    pass
                elif isinstance(result, CoinbaseError):
                    # There is an error, check if its due to improper supply.
                    self.logorder(order, result.error[0])
                    if result.error[
                            0] == "You must acknowledge that the price can vary by checking the box below.":
                        temporderbook.append(
                            order
                        )  # Means the order failed due to low supply and not agreeing to the price varying.
                    elif len(self.orderbook) == 1:
                        print result.error
                        sleep = False  # This is done to exit quickly if the last trade errors
                elif isinstance(result, CoinOrder):
                    order.executed = True
                    temporderbook.append(result)
                    sleep = False  # If a coinorder is returned it should be executed asap.
                    sleeptime = 1  # If I can't be executed after the first time, keep trying every second otherwise
                elif isinstance(result, CoinbaseTransfer):
                    # Trade executed
                    order.executed = True
                    self.logexecution(order, result)
                elif result is None:
                    temporderbook.append(order)

            with self._orderbookLock:
                self.orderbook = temporderbook

            if sleep is True:
                if runtime is not None:
                    runtime = runtime - sleeptime
                if runtime is None or runtime > 0:
                    time.sleep(sleeptime)

        return True

    def stoptrade(self):
        """
        Call to stop trade() method from executing. Only needed for threading mode. 
        """
        with self._stopTradeLock:
            _stoppedTraders.append(self.traderid)

    def _addOrder(self,
                  ordertype,
                  qty,
                  price=0,
                  changeval=None,
                  queueExecution=True):
        """
        Generic Order Adding Function. price is in price per share. User shouldn't call.

        ordertype: type of order, constant
        qty: qty in order
        price: price to execute 
        changeval: change to observer for stoploss trades
        queueExecution: True or False to add to orderbook list, True if you want to
                          execute with trade(). False if you just want the order object to be returned
        """
        price = price * qty
        order = CoinOrder(ordertype=ordertype,
                          qty=qty,
                          price=price,
                          changeval=changeval)

        if queueExecution is True:
            with self._orderbookLock:
                self.orderbook.append(order)

        self.logorder(order, "Added Order:")
        return order

    def setMarketBuy(self, qty, queue=True):
        """
        Buy qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype=MARKET_BUY,
                              qty=qty,
                              queueExecution=queue)

    def setMarketSell(self, qty, queue=True):
        """
        Sell qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype=MARKET_SELL,
                              qty=qty,
                              queueExecution=queue)

    def setLimitBuy(self, qty, price, queue=True):
        """
        Helps buy low, Buy at specified price or lower. Input price per share
        """
        return self._addOrder(ordertype=LIMIT_BUY,
                              qty=qty,
                              price=price,
                              queueExecution=queue)

    def setLimitSell(self, qty, price, queue=True):
        """
        Helps sell high, Sell at specified price or higher. Input execution price per share
        """
        return self._addOrder(ordertype=LIMIT_SELL,
                              qty=qty,
                              price=price,
                              queueExecution=queue)

    def setStopLoss(self, qty, price, queue=True):
        """
        If the price goes below a specified price, sell it all ASAP via market sell order. Input execution price per share
        """
        return self._addOrder(ordertype=STOP_LOSS,
                              qty=qty,
                              price=price,
                              queueExecution=queue)

    def setTrailStopLossValue(self, qty, changeval, queue=True):
        """
        Sell qty bitcoins when they drop "value" below their maximum per share value since purchase. Basically a Moving Limit sell at: maxPriceSeen - value
        """
        return self._addOrder(ordertype=TRAIL_STOP_VALUE,
                              qty=qty,
                              price=0,
                              changeval=changeval * qty,
                              queueExecution=queue)

    def setTrailStopLossPercent(self, qty, changeval, maxprice=0, queue=True):
        """
        Sell qty bitcoins when they have a changepercent drop below their maximum value since purchase. Basically a Moving Limit sell at: maxPriceSeen * (1 - (changepercent/100) ) 
        """
        return self._addOrder(ordertype=TRAIL_STOP_PERCENT,
                              qty=qty,
                              price=maxprice,
                              changeval=changeval / 100.0,
                              queueExecution=queue)

    def oneStartsAnother(self, initialOrder, triggerOrder, queue=True):
        """
        Input two orders then once ExecuteOrder() executes the order (in trade) it Returns
        that value to the trade() method which will then begin executing the next order specified.
        This can be used to execute a buy which upon execution will trigger a sell order at a higher price.
        These orders could be combined multiple times by having any order trigger another oneStartsAnother order.
        These order should NOT be added to the queue (i.e. set queue = False upon order creation).
        """
        initialOrder.nextOrder = triggerOrder
        with self._orderbookLock:
            if queue is True:
                self.orderbook.append(initialOrder)

        self.logorder(initialOrder, "Added Order:")
        return initialOrder

    def RemoveOrder(self, orderid):
        """
        Accepts either the orderid (starts at 0 and increments to the number of total orders)
        Or the CoinOrder object returned when the order was created.
        """
        removedOrder = None
        if isinstance(orderid, int):
            temp = []
            with self._orderbookLock:
                constorderbook = self.orderbook

            for order in self.orderbook:
                if order.id != orderid:
                    temp.append(order)
                else:
                    removedOrder = order
            with self._orderbookLock:
                self.orderbook = temp

        if isinstance(orderid, CoinOrder):
            try:
                with self._orderbookLock:
                    self.orderbook.remove(order)

                removedOrder = order
            except:
                pass
        return removedOrder
コード例 #10
0
ファイル: tests.py プロジェクト: sylvainblot/coinbase_python
class CoinBaseLibraryTests(unittest.TestCase):

    def setUp(self):
        self.account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)

    @httprettified
    def test_status_error(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/balance",
                               body='''{"error": "Invalid api_key"}''',
                               content_type='text/json',
                               status=401)

        try:
            self.account.balance
        except CoinbaseError as e:
            e.error.should.equal("Invalid api_key")
            unicode(e).should.equal(u"Invalid api_key")
            str(e).should.equal("Invalid api_key")
        except Exception:
            assert False

    @httprettified
    def test_success_false(self):
        # Success is added when posting, putting or deleting
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/balance",
                               body='''{"success": false, "errors":["Error 1","Error 2"]}''',
                               content_type='text/json')

        try:
            self.account.balance
        except CoinbaseError as e:
            e.error.should.equal(["Error 1", "Error 2"])
        except Exception:
            assert False

    @httprettified
    def test_retrieve_balance(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/balance",
                               body='''{"amount":"0.00000000","currency":"BTC"}''',
                               content_type='text/json')

        this(float(self.account.balance)).should.equal(0.0)
        this(self.account.balance.currency).should.equal('BTC')

    @httprettified
    def test_receive_addresses(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/receive_address",
                               body='''{"address" : "1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt"}''',
                               content_type='text/json')

        this(self.account.receive_address).should.equal(u'1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt')

    @httprettified
    def test_contacts(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/contacts",
                               body='''{"contacts":[{"contact":{"email":"*****@*****.**"}}],"total_count":1,"num_pages":1,"current_page":1}''',
                               content_type='text/json')

        this(self.account.contacts).should.equal([{u'email': u'*****@*****.**'}])

    @httprettified
    def test_buy_price_1(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        buy_price_1 = self.account.buy_price(1)
        this(buy_price_1).should.be.a(Decimal)
        this(buy_price_1).should.be.lower_than(100)
        this(buy_price_1.currency).should.equal('USD')

    @httprettified
    def test_buy_price_2(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=10",
                               body='''{"amount":"633.25","currency":"USD"}''',
                               content_type='text/json')

        buy_price_10 = self.account.buy_price(10)
        this(buy_price_10).should.be.greater_than(100)

    @httprettified
    def test_sell_price(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_1 = self.account.sell_price(1)
        this(sell_price_1).should.be.a(Decimal)
        this(sell_price_1).should.be.lower_than(100)
        this(sell_price_1.currency).should.equal('USD')

    @httprettified
    def test_sell_price_10(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"630.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_10 = self.account.sell_price(10)
        this(sell_price_10).should.be.greater_than(100)

    @httprettified
    def test_request_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/request_money",
                               body='''{"success":true,"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}}''',
                               content_type='text/json')

        new_request = self.account.request('*****@*****.**', 1, 'Testing')

        this(new_request.amount).should.equal(CoinbaseAmount(Decimal(1), 'BTC'))
        this(new_request.request).should.equal(True)
        this(new_request.sender.email).should.equal('*****@*****.**')
        this(new_request.recipient.email).should.equal('*****@*****.**')
        this(new_request.notes).should.equal('Testing')

    @httprettified
    def test_send_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}    ''',
                               content_type='text/json')

        new_transaction_with_btc_address = self.account.send('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP', amount=0.1)

        this(new_transaction_with_btc_address.amount).should.equal(CoinbaseAmount(Decimal('-0.1'), 'BTC'))
        this(new_transaction_with_btc_address.request).should.equal(False)
        this(new_transaction_with_btc_address.sender.email).should.equal('*****@*****.**')
        this(new_transaction_with_btc_address.recipient).should.equal(None)
        this(new_transaction_with_btc_address.recipient_address).should.equal('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP')

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b2920b974ea4cb000003","created_at":"2013-03-31T15:02:58-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}}''',
                               content_type='text/json')

        new_transaction_with_email = self.account.send('*****@*****.**', amount=0.1)

        this(new_transaction_with_email.recipient.email).should.equal('*****@*****.**')

    @httprettified
    def test_transaction_list(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions",
                               body='''{"current_user":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"balance":{"amount":"0.00000000","currency":"BTC"},"total_count":4,"num_pages":1,"current_page":1,"transactions":[{"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514e4c1c802e1bef98000020","created_at":"2013-03-23T17:43:08-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514b9fb1b8377ee36500000d","created_at":"2013-03-21T17:02:57-07:00","hsh":"42dd65a18dbea0779f32021663e60b1fab8ee0f859db7172a078d4528e01c6c8","notes":"You gave me this a while ago. It's turning into a fair amount of cash and thought you might want it back :) Building something on your API this weekend. Take care!","amount":{"amount":"-1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}},{"transaction":{"id":"509e01cb12838e0200000224","created_at":"2012-11-09T23:27:07-08:00","hsh":"ac9b0ffbe36dbe12c5ca047a5bdf9cadca3c9b89b74751dff83b3ac863ccc0b3","notes":"","amount":{"amount":"1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"*****@*****.**"}}]}''',
                               content_type='text/json')

        transaction_list = self.account.transactions()

        this(transaction_list).should.be.a(list)

    @httprettified
    def test_getting_transaction(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions/5158b227802669269c000009",
                               body='''{"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":"223a404485c39173ab41f343439e59b53a5d6cba94a02501fc6c67eeca0d9d9e","notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}''',
                               content_type='text/json')

        transaction = self.account.get_transaction('5158b227802669269c000009')

        this(transaction.status).should.equal('pending')
        this(transaction.amount).should.equal(CoinbaseAmount(Decimal("-0.1"), "BTC"))

    @httprettified
    def test_getting_user_details(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/users",
                               body='''{"users":[{"user":{"id":"509f01da12837e0201100212","name":"New User","email":"*****@*****.**","time_zone":"Pacific Time (US & Canada)","native_currency":"USD","buy_level":1,"sell_level":1,"balance":{"amount":"1225.86084181","currency":"BTC"},"buy_limit":{"amount":"10.00000000","currency":"BTC"},"sell_limit":{"amount":"50.00000000","currency":"BTC"}}}]}''',
                               content_type='text/json')

        user = self.account.get_user_details()

        this(user.id).should.equal("509f01da12837e0201100212")
        this(user.balance).should.equal(CoinbaseAmount(Decimal("1225.86084181"), "BTC"))

    # The following tests use the example request/responses from the coinbase API docs:
    # test_creating_button, test_creating_order, test_getting_order
    @httprettified
    def test_creating_button(self):
        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/buttons",
                               body='''{"success":true,"button":{"code":"93865b9cae83706ae59220c013bc0afd","type":"buy_now","style":"custom_large","text":"Pay With Bitcoin","name":"test","description":"Sample description","custom":"Order123","callback_url":"http://www.example.com/my_custom_button_callback","price":{"cents":123,"currency_iso":"USD"}}}''',
                               content_type='text/json')

        button = self.account.create_button(
            name="test",
            type="buy_now",
            price=1.23,
            currency="USD",
            custom="Order123",
            callback_url="http://www.example.com/my_custom_button_callback",
            description="Sample description",
            style="custom_large",
            include_email=True
        )
        this(button.code).should.equal("93865b9cae83706ae59220c013bc0afd")
        this(button.name).should.equal("test")
        this(button.price).should.equal(CoinbaseAmount(Decimal('1.23'), "USD"))
        this(button.include_address).should.equal(None)

    @httprettified
    def test_creating_order(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/buttons/93865b9cae83706ae59220c013bc0afd/create_order",
                               body='''{"success":true,"order":{"id":"7RTTRDVP","created_at":"2013-11-09T22:47:10-08:00","status":"new","total_btc":{"cents":100000000,"currency_iso":"BTC"},"total_native":{"cents":100000000,"currency_iso":"BTC"},"custom":"Order123","receive_address":"mgrmKftH5CeuFBU3THLWuTNKaZoCGJU5jQ","button":{"type":"buy_now","name":"test","description":"Sample description","id":"93865b9cae83706ae59220c013bc0afd"},"transaction":null}}''',
                               content_type='text/json')

        order = self.account.create_order("93865b9cae83706ae59220c013bc0afd")

        this(order.order_id).should.equal("7RTTRDVP")
        this(order.total_btc).should.equal(CoinbaseAmount(1, 'BTC'))

        this(order.button.button_id).should.equal("93865b9cae83706ae59220c013bc0afd")
        this(order.transaction).should.equal(None)

    @httprettified
    def test_order_list(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/orders",
                               body='''{"orders":[{"order":{"id":"A7C52JQT","created_at":"2013-03-11T22:04:37-07:00","status":"completed","total_btc":{"cents":100000000,"currency_iso":"BTC"},"total_native":{"cents":3000,"currency_iso":"USD"},"custom":"","button":{"type":"buy_now","name":"Order #1234","description":"order description","id":"eec6d08e9e215195a471eae432a49fc7"},"transaction":{"id":"513eb768f12a9cf27400000b","hash":"4cc5eec20cd692f3cdb7fc264a0e1d78b9a7e3d7b862dec1e39cf7e37ababc14","confirmations":0}}}],"total_count":1,"num_pages":1,"current_page":1}''',
                               content_type='text/json')

        orders = self.account.orders()
        this(orders).should.be.a(list)
        this(orders[0].order_id).should.equal("A7C52JQT")

    @httprettified
    def test_getting_order(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/orders/A7C52JQT",
                               body='''{"order":{"id":"A7C52JQT","created_at":"2013-03-11T22:04:37-07:00","status":"completed","total_btc":{"cents":10000000,"currency_iso":"BTC"},"total_native":{"cents":10000000,"currency_iso":"BTC"},"custom":"","button":{"type":"buy_now","name":"test","description":"","id":"eec6d08e9e215195a471eae432a49fc7"},"transaction":{"id":"513eb768f12a9cf27400000b","hash":"4cc5eec20cd692f3cdb7fc264a0e1d78b9a7e3d7b862dec1e39cf7e37ababc14","confirmations":0}}}''',
                               content_type='text/json')

        order = self.account.get_order("A7C52JQT")

        this(order.order_id).should.equal("A7C52JQT")
        this(order.status).should.equal("completed")
        this(order.total_btc).should.equal(CoinbaseAmount(Decimal(".1"), "BTC"))
        this(order.button.name).should.equal("test")
        this(order.transaction.transaction_id).should.equal("513eb768f12a9cf27400000b")
コード例 #11
0
class CoinBaseLibraryTests(unittest.TestCase):

    def setUp(self):
        self.account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)

    @httprettified
    def test_retrieve_balance(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/balance",
                               body='''{"amount":"0.00000000","currency":"BTC"}''',
                               content_type='text/json')

        this(self.account.balance).should.equal(0.0)
        this(self.account.balance.currency).should.equal('BTC')

        #TODO:  Switch to decimals
        #this(self.account.balance).should.equal(CoinbaseAmount('0.00000000', 'USD'))
        #this(self.account.balance.currency).should.equal(CoinbaseAmount('0.00000000', 'USD').currency)

    @httprettified
    def test_receive_addresses(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/account/receive_address",
                               body='''{"address" : "1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt"}''',
                               content_type='text/json')

        this(self.account.receive_address).should.equal(u'1DX9ECEF3FbGUtzzoQhDT8CG3nLUEA2FJt')

    @httprettified
    def test_contacts(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/contacts",
                               body='''{"contacts":[{"contact":{"email":"*****@*****.**"}}],"total_count":1,"num_pages":1,"current_page":1}''',
                               content_type='text/json')

        this(self.account.contacts).should.equal([{u'email': u'*****@*****.**'}])

    @httprettified
    def test_buy_price_1(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        buy_price_1 = self.account.buy_price(1)
        this(buy_price_1).should.be.an(float)
        this(buy_price_1).should.be.lower_than(100)
        this(buy_price_1.currency).should.equal('USD')

    @httprettified
    def test_buy_price_2(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/buy?qty=10",
                               body='''{"amount":"633.25","currency":"USD"}''',
                               content_type='text/json')

        buy_price_10 = self.account.buy_price(10)
        this(buy_price_10).should.be.greater_than(100)

    @httprettified
    def test_sell_price(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"63.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_1 = self.account.sell_price(1)
        this(sell_price_1).should.be.an(float)
        this(sell_price_1).should.be.lower_than(100)
        this(sell_price_1.currency).should.equal('USD')

    @httprettified
    def test_sell_price_10(self):
        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/prices/sell?qty=1",
                               body='''{"amount":"630.31","currency":"USD"}''',
                               content_type='text/json')

        sell_price_10 = self.account.sell_price(10)
        this(sell_price_10).should.be.greater_than(100)

    @httprettified
    def test_request_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/request_money",
                               body='''{"success":true,"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}}''',
                               content_type='text/json')

        new_request = self.account.request('*****@*****.**', 1, 'Testing')

        this(new_request.amount).should.equal(1)
        this(new_request.request).should.equal(True)
        this(new_request.sender.email).should.equal('*****@*****.**')
        this(new_request.recipient.email).should.equal('*****@*****.**')
        this(new_request.notes).should.equal('Testing')

    @httprettified
    def test_send_bitcoin(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}    ''',
                               content_type='text/json')

        new_transaction_with_btc_address = self.account.send('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP', amount=0.1)

        this(new_transaction_with_btc_address.amount).should.equal(-0.1)
        this(new_transaction_with_btc_address.request).should.equal(False)
        this(new_transaction_with_btc_address.sender.email).should.equal('*****@*****.**')
        this(new_transaction_with_btc_address.recipient).should.equal(None)
        this(new_transaction_with_btc_address.recipient_address).should.equal('15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP')

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/transactions/send_money",
                               body='''{"success":true,"transaction":{"id":"5158b2920b974ea4cb000003","created_at":"2013-03-31T15:02:58-07:00","hsh":null,"notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}}
''',
                               content_type='text/json')

        new_transaction_with_email = self.account.send('*****@*****.**', amount=0.1)

        this(new_transaction_with_email.recipient.email).should.equal('*****@*****.**')

    @httprettified
    def test_transaction_list(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions",
                               body='''{"current_user":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"balance":{"amount":"0.00000000","currency":"BTC"},"total_count":4,"num_pages":1,"current_page":1,"transactions":[{"transaction":{"id":"514e4c37802e1bf69100000e","created_at":"2013-03-23T17:43:35-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514e4c1c802e1bef98000020","created_at":"2013-03-23T17:43:08-07:00","hsh":null,"notes":"Testing","amount":{"amount":"1.00000000","currency":"BTC"},"request":true,"status":"pending","sender":{"id":"514e4c1c802e1bef9800001e","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"}}},{"transaction":{"id":"514b9fb1b8377ee36500000d","created_at":"2013-03-21T17:02:57-07:00","hsh":"42dd65a18dbea0779f32021663e60b1fab8ee0f859db7172a078d4528e01c6c8","notes":"You gave me this a while ago. It's turning into a fair amount of cash and thought you might want it back :) Building something on your API this weekend. Take care!","amount":{"amount":"-1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient_address":"*****@*****.**"}},{"transaction":{"id":"509e01cb12838e0200000224","created_at":"2012-11-09T23:27:07-08:00","hsh":"ac9b0ffbe36dbe12c5ca047a5bdf9cadca3c9b89b74751dff83b3ac863ccc0b3","notes":"","amount":{"amount":"1.00000000","currency":"BTC"},"request":false,"status":"complete","sender":{"id":"4efec8d7bedd320001000003","email":"*****@*****.**","name":"Brian Armstrong"},"recipient":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"*****@*****.**"}}]}''',
                           content_type='text/json')

        transaction_list = self.account.transactions()

        this(transaction_list).should.be.an(list)

    @httprettified
    def test_getting_transaction(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/transactions/5158b227802669269c000009",
                               body='''{"transaction":{"id":"5158b227802669269c000009","created_at":"2013-03-31T15:01:11-07:00","hsh":"223a404485c39173ab41f343439e59b53a5d6cba94a02501fc6c67eeca0d9d9e","notes":"","amount":{"amount":"-0.10000000","currency":"BTC"},"request":false,"status":"pending","sender":{"id":"509e01ca12838e0200000212","email":"*****@*****.**","name":"*****@*****.**"},"recipient_address":"15yHmnB5vY68sXpAU9pR71rnyPAGLLWeRP"}}''',
                               content_type='text/json')

        transaction = self.account.get_transaction('5158b227802669269c000009')

        this(transaction.status).should.equal('pending')
        this(transaction.amount).should.equal(-0.1)

    @httprettified
    def test_getting_user_details(self):

        HTTPretty.register_uri(HTTPretty.GET, "https://coinbase.com/api/v1/users",
                               body='''{"users":[{"user":{"id":"509f01da12837e0201100212","name":"New User","email":"*****@*****.**","time_zone":"Pacific Time (US & Canada)","native_currency":"USD","buy_level":1,"sell_level":1,"balance":{"amount":"1225.86084181","currency":"BTC"},"buy_limit":{"amount":"10.00000000","currency":"BTC"},"sell_limit":{"amount":"50.00000000","currency":"BTC"}}}]}''',
                               content_type='text/json')

        user = self.account.get_user_details()

        this(user.id).should.equal("509f01da12837e0201100212")
        this(user.balance).should.equal(1225.86084181)

    @httprettified
    def test_creating_a_button(self):

        HTTPretty.register_uri(HTTPretty.POST, "https://coinbase.com/api/v1/buttons",
                               body='''{"button": {"style": "buy_now_large", "code": "b123456783q812e381cd9d39a5783277", "name": "Test Button", "info_url": null, "text": "Pay With Bitcoin", "price": {"cents": 2000, "currency_iso": "USD"}, "include_email": false, "custom": "", "cancel_url": null, "auto_redirect": false, "success_url": null, "variable_price": false, "include_address": false, "callback_url": null, "type": "buy_now", "choose_price": false, "description": ""}, "success": true}''',
                               content_type='text/json')

        button = self.account.create_button('Test Button', '20.00', 'USD')

        this(button.code).should.equal('b123456783q812e381cd9d39a5783277')
        this(button.name).should.equal('Test Button')
        this(button.price['cents']).should.equal(2000)
コード例 #12
0
def with_key():
    return CoinbaseAccount(api_key=api_key)
コード例 #13
0
def without_auth():
    return CoinbaseAccount()
コード例 #14
0
ファイル: coinbase_exchange.py プロジェクト: rozap/arb
 def __init__(self, settings):
     super(CoinbaseExchange, self).__init__(settings)
     self._trading = CoinbaseAccount(api_key = settings['COINBASE']['api']['key'])
コード例 #15
0
            send_transaction = account.send(to_address=send_btc_to,
                                            amount=amount_to_send,
                                            notes='Test send')

            print("We successfully sent " + str(send_transaction.amount) +
                  " " + send_transaction.amount.currency + " to " +
                  send_transaction.recipient_address)

            print("Your new balance is " + str(account.balance))

    transactions = account.transactions(count=30)

    print("Here are your last " + str(len(transactions)) + " transactions:")

    for index, transaction in enumerate(transactions):

        if transaction.amount > 0:
            print(
                str(index) + ": " + str(transaction.amount) + " " +
                transaction.amount.currency + " to your Coinbase wallet.")
        else:
            print(
                str(index) + ": " + str(transaction.amount) + " " +
                transaction.amount.currency + " out to a " +
                transaction.recipient_type + " address")


if __name__ == '__main__':
    account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)
    do_coinbase_stuff(account=account)
コード例 #16
0
ファイル: main.py プロジェクト: martindale/proof-of-existence
 def get_pay_address(self, d):
     account = CoinbaseAccount(api_key=COINBASE_API_KEY)
     callback_url = "http://www.proofofexistence.com/api/api_callback?secret=%s&d=%s" % (CALLBACK_SECRET, d)
     return account.generate_receive_address(callback_url).get("address")
コード例 #17
0
 def setUp(self):
     self.account = CoinbaseAccount(api_key='f64223978e5fd99d07cded069db2189a38c17142fee35625f6ab3635585f61ab')
コード例 #18
0
class Trader(object):
    
    _orderbookLock = threading.Lock()
    _executeLock = threading.Lock()
    _stopTradeLock = threading.Lock()
    stopTrade = False



    def __init__(self,api_key = None, oauth2_credentials = None, orderbook = None, logname = "traderlog.txt"):
        if (api_key is None) and (oauth2_credentials is None):
            raise ValueError("api_key and oauth2_credentials cannot be None")
        if (api_key is not None) and (oauth2_credentials is not None):
            raise ValueError("User Provided both api_key and oauth2_credentials, select one")        # I might want to instead just use one or the other 

        with _traderIdLock:
            global TRADER_ID
            self.traderid = TRADER_ID
            TRADER_ID+=1 
        
        self.orderbook = [] if orderbook is None else orderbook

        f = open(logname, 'w')
        f.close()
        self.logname = logname
        self.logwrite(str(datetime.now()) + '\n')

        self.account = CoinbaseAccount(oauth2_credentials,api_key)


    def logwrite(self, message):
        """
        Writes to the logfile with appended newline. 
        """
        with open(self.logname, 'a') as log:
            with _logwriteLock:
                log.write(message + '\n')

    def logexecution(self, order, result):
        """
        Write the result and order to the log file
        """
        self.logorder(order)
        logstr = "Order Type: " + str(result.type) + " Code: " + str(result.code) + " Executed at: " + str(result.created_at) 
        logstr = logstr + "\nBTC Amount: " + str(result.btc_amount) + " Total Price: " + str(result.total_amount) + " Fees: " + str(result.fees_bank+result.fees_coinbase) 
        logstr = "Result of Order\n" + logstr
        self.logwrite(logstr)     

    def logorder(self, order, header = None):
        """
        Writes the order the log file
        """
        logstr = header + '\n' if isinstance(header,str) else ''
        logstr = "OrderID: %s OrderType: %s Quantity: %s Price: %s" % (order.orderid, order.ordertype, order.qty, order.price)
        logstr = logstr + " Change Value: " + str(order.changeval)
        logstr = logstr + " Executed: " + str(order.executed) + '\n'
        if order.parentorder is not None:
            self.logorder(order.parentorder, "Parent Order:")
        self.logwrite(logstr)

    def ExecuteOrder(self, order):
        """
        Executes an order based on its order.ordertype
        Returns None if the trade is valid is not yet active(i.e limit not met)
        Returns a CoinbaseError or CoinbaseTransfer object if order attempted to execute
        Returns False if the order should be Deleted or removed from the orderbook. 
        """
        with self._executeLock:
            traderesult = None
            currentprice = -1

            if order.ordertype in [MARKET_BUY, LIMIT_BUY]:
                currentprice = self.account.buy_price(qty = order.qty)
                print "Current Buy Price: " + str(currentprice/order.qty) 
            elif order.ordertype in [MARKET_SELL, LIMIT_SELL, STOP_LOSS, TRAIL_STOP_VALUE, TRAIL_STOP_PERCENT]: 
                currentprice = self.account.sell_price(qty = order.qty)
                print "Current Sell Price: " + str(currentprice/order.qty)


            if order.ordertype == MARKET_BUY:
                traderesult = self.account.buy_btc(qty = order.qty)
            elif order.ordertype == MARKET_SELL:
                traderesult = self.account.sell_btc(qty = order.qty)
            elif order.ordertype == LIMIT_BUY:
                if currentprice <= order.price:
                    traderesult = self.account.buy_btc(qty = order.qty)
            elif order.ordertype == LIMIT_SELL:
                if currentprice >= order.price:
                    traderesult = self.account.sell_btc(qty = order.qty)
            elif order.ordertype == STOP_LOSS:
                if currentprice <= order.price:
                    traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            elif order.ordertype == TRAIL_STOP_VALUE:
                if currentprice > order.price:
                    order.price = currentprice
                elif currentprice <= (order.price - order.changeval):
                    traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            elif order.ordertype == TRAIL_STOP_PERCENT:
                if currentprice > order.price:
                    order.price = currentprice
                elif currentprice <= (order.price * (1.0 - order.changeval) ):
                    traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            else:
                traderesult = False         # deletes the order from the order book

        if isinstance(order.nextOrder, CoinOrder):
            if isinstance(traderesult, CoinbaseTransfer):
                traderesult = (traderesult, order.nextOrder)
            if isinstance(traderesult, CoinbaseError):
                print "Triggered Order Lost due to error"
        return traderesult


    def trade(self, runtime = None, sleeptime = 60, startNewThread = False):
        """ 
        Call this function to execute trades in added to the order book. Returns True on success and Writes
        the specified log file.

        :param runtime: Number of seconds to trade should execute, infinity (None) is the default.
        :param sleeptime: Interval of time between checking orders (coinbase updates their prices once per 60 seconds)
        :param startNewThread: Optionally run trade in a new thread, orders can then be added while trade() runs (using the usual methods)
        """
        if startNewThread == True:
            newThread = threading.Thread(target=self.trade, args=[runtime, sleeptime, False])
            newThread.daemon = True
            newThread.start()
            return True

        with self._stopTradeLock:
            self.stopTrade = False
        initialBtcBal = self.account.balance
        initialUsdVal = self.account.sell_price(initialBtcBal)
        initialSellRate = initialUsdVal/initialBtcBal if initialBtcBal != 0 else 0
        self.logwrite("Initial BTC Balance: " + str(initialBtcBal) + " Initial USD Value: " + str(initialUsdVal) + " Price Per Coin: " + str(initialSellRate)) 
        while ( (runtime is None) or (runtime>0) ) and (len(self.orderbook) > 0):

            with self._stopTradeLock:
                if self.traderid in _stoppedTraders:
                    _stoppedTraders.remove(self.traderid)
                    return True

            sleep = True
            temporderbook = []
            with self._orderbookLock:
                constantorderbook = self.orderbook

            for order in constantorderbook:
                result = self.ExecuteOrder(order)
                if isinstance(result, tuple):
                    # Append next order and process the trade result
                    temporderbook.append(result[1])
                    result = result[0]
                if result is False:
                    # Invalid Order ID, discard order
                    pass
                elif isinstance(result, CoinbaseError):
                    # There is an error, check if its due to improper supply.
                    self.logorder(order, result.error[0])
                    if result.error[0] == "You must acknowledge that the price can vary by checking the box below.":
                        temporderbook.append(order)     # Means the order failed due to low supply and not agreeing to the price varying.
                    elif len(self.orderbook) == 1:
                        print result.error
                        sleep = False       # This is done to exit quickly if the last trade errors
                elif isinstance(result, CoinOrder):
                    order.executed = True
                    temporderbook.append(result)
                    sleep = False           # If a coinorder is returned it should be executed asap. 
                    sleeptime = 1         # If I can't be executed after the first time, keep trying every second otherwise
                elif isinstance(result, CoinbaseTransfer):
                    # Trade executed
                    order.executed = True
                    self.logexecution(order, result)
                elif result is None:
                    temporderbook.append(order)

            with self._orderbookLock:
                self.orderbook = temporderbook

            if sleep is True:
                if runtime is not None:
                    runtime = runtime - sleeptime
                if runtime is None or runtime > 0:
                    time.sleep(sleeptime)

        return True

    def stoptrade(self):
        """
        Call to stop trade() method from executing. Only needed for threading mode. 
        """
        with self._stopTradeLock:
            _stoppedTraders.append(self.traderid)

    def _addOrder(self, ordertype, qty, price = 0, changeval = None, queueExecution = True):
        """
        Generic Order Adding Function. price is in price per share. User shouldn't call.

        ordertype: type of order, constant
        qty: qty in order
        price: price to execute 
        changeval: change to observer for stoploss trades
        queueExecution: True or False to add to orderbook list, True if you want to
                          execute with trade(). False if you just want the order object to be returned
        """
        price = price * qty
        order = CoinOrder(ordertype = ordertype, qty = qty, price = price, changeval = changeval)

        if queueExecution is True:
            with self._orderbookLock:
                self.orderbook.append(order)

        self.logorder(order, "Added Order:")
        return order

    def setMarketBuy(self, qty, queue = True):
        """
        Buy qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype = MARKET_BUY, qty = qty, queueExecution = queue)


    def setMarketSell(self, qty, queue = True):
        """
        Sell qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype = MARKET_SELL, qty = qty, queueExecution = queue)


    def setLimitBuy(self, qty, price, queue = True):
        """
        Helps buy low, Buy at specified price or lower. Input price per share
        """
        return self._addOrder(ordertype = LIMIT_BUY,qty = qty, price = price, queueExecution = queue)


    def setLimitSell(self, qty, price, queue = True):
        """
        Helps sell high, Sell at specified price or higher. Input execution price per share
        """
        return self._addOrder(ordertype = LIMIT_SELL, qty = qty, price = price, queueExecution = queue) 

    def setStopLoss(self, qty, price, queue = True):
        """
        If the price goes below a specified price, sell it all ASAP via market sell order. Input execution price per share
        """
        return self._addOrder(ordertype = STOP_LOSS, qty = qty, price = price, queueExecution = queue)


    def setTrailStopLossValue(self, qty, changeval, queue = True):
        """
        Sell qty bitcoins when they drop "value" below their maximum per share value since purchase. Basically a Moving Limit sell at: maxPriceSeen - value
        """
        return self._addOrder(ordertype = TRAIL_STOP_VALUE, qty = qty, price = 0, changeval = changeval*qty, queueExecution = queue)

    def setTrailStopLossPercent(self, qty, changeval, maxprice = 0, queue = True):
        """
        Sell qty bitcoins when they have a changepercent drop below their maximum value since purchase. Basically a Moving Limit sell at: maxPriceSeen * (1 - (changepercent/100) ) 
        """
        return self._addOrder(ordertype = TRAIL_STOP_PERCENT, qty = qty, price = maxprice, changeval = changeval/100.0, queueExecution = queue)

    def oneStartsAnother(self, initialOrder, triggerOrder, queue = True):
        """
        Input two orders then once ExecuteOrder() executes the order (in trade) it Returns
        that value to the trade() method which will then begin executing the next order specified.
        This can be used to execute a buy which upon execution will trigger a sell order at a higher price.
        These orders could be combined multiple times by having any order trigger another oneStartsAnother order.
        These order should NOT be added to the queue (i.e. set queue = False upon order creation).
        """
        initialOrder.nextOrder = triggerOrder
        with self._orderbookLock:
            if queue is True:
                self.orderbook.append(initialOrder)

        self.logorder(initialOrder, "Added Order:")
        return initialOrder


    def RemoveOrder(self, orderid):
        """
        Accepts either the orderid (starts at 0 and increments to the number of total orders)
        Or the CoinOrder object returned when the order was created.
        """
        removedOrder = None
        if isinstance(orderid, int):
            temp = []
            with self._orderbookLock:
                constorderbook = self.orderbook

            for order in self.orderbook:
                if order.id != orderid:
                    temp.append(order)
                else:
                    removedOrder = order
            with self._orderbookLock:
                self.orderbook = temp

        if isinstance(orderid, CoinOrder):
            try:
                with self._orderbookLock:
                    self.orderbook.remove(order)

                removedOrder = order         
            except:
                pass
        return removedOrder
コード例 #19
0
 def setUp(self):
     self.account = CoinbaseAccount(oauth2_credentials=TEMP_CREDENTIALS)
コード例 #20
0
ファイル: trader.py プロジェクト: iewnait/coinbase_trader
class Trader(object):

    def __init__(self,api_key = None, oauth2_credentials = None, orderbook = None, logname = "traderlog.txt"):
        if (api_key is None) and (oauth2_credentials is None):
            raise ValueError("api_key and oauth2_credentials cannot be None")
        if (api_key is not None) and (oauth2_credentials is not None):
            raise ValueError("User Provided both api_key and oauth2_credentials, select one")        # I might want to instead just use one or the other 

        
        self.orderbook = [] if orderbook is None else orderbook

        f = open(logname, 'w')
        f.close()
        self.logname = logname
        self.logwrite(str(datetime.now()) + '\n')

        self.account = CoinbaseAccount(oauth2_credentials,api_key)


    def logwrite(self, message):
        """
        Writes to the logfile with appended newline. 
        """
        with open(self.logname, 'a') as log:
            log.write(message + '\n')

    def logexecution(self, order, result):
        """
        Write the result and order to the log file
        """
        self.logorder(order)
        logstr = "Order Type: " + str(result.type) + " Code: " + str(result.code) + " Executed at: " + str(result.created_at) 
        logstr = logstr + "\nBTC Amount: " + str(result.btc_amount) + " Total Price: " + str(result.total_amount) + " Fees: " + str(result.fees_bank+result.fees_coinbase) 
        self.logwrite(logstr)     

    def logorder(self, order, header = None):
        """
        Writes the order the log file
        """
        logstr = header + '\n' if isinstance(header,str) else ''
        logstr = "OrderID: %s OrderType: %s Quantity: %s Price: %s" % (order.orderid, order.ordertype, order.qty, order.price)
        logstr = logstr + " Change Value: " + str(order.changeval)
        logstr = logstr + " Executed: " + str(order.executed) + '\n'
        if order.parentorder is not None:
            self.logorder(order.parentorder, "Parent Order:")
        self.logwrite(logstr)

    def ExecuteOrder(self, order):
        """
        Executes an order based on its order.ordertype
        Returns None if the trade is valid is not yet active(i.e limit not met)
        Returns a CoinbaseError or CoinbaseTransfer object if order attempted to execute
        Returns False if the order should be Deleted or removed from the orderbook. 
        """
        traderesult = None
        currentprice = -1

        if order.ordertype in [MARKET_BUY, LIMIT_BUY]:
            currentprice = self.account.buy_price(qty = order.qty)
            print "Current Buy Price: " + str(currentprice/order.qty) 
        elif order.ordertype in [MARKET_SELL, LIMIT_SELL, STOP_LOSS, TRAIL_STOP_VALUE, TRAIL_STOP_PERCENT]: 
            currentprice = self.account.sell_price(qty = order.qty)
            print "Current Sell Price: " + str(currentprice/order.qty)

        if order.ordertype == MARKET_BUY:
            traderesult = self.account.buy_btc(qty = order.qty)
        elif order.ordertype == MARKET_SELL:
            traderesult = self.account.sell_btc(qty = order.qty)
        elif order.ordertype == LIMIT_BUY:
            if currentprice <= order.price:
                traderesult = self.account.buy_btc(qty = order.qty)
            else:
                print "Did not met LIMIT_BUY price at: " + str(order.price / order.qty) + ' for ' + str(order.qty) + ' BTC'
        elif order.ordertype == LIMIT_SELL:
            if currentprice >= order.price:
                print currentprice, order.price
                traderesult = self.account.sell_btc(qty = order.qty)
            else:
                print "Did not met LIMIT_SELL price at: " + str(order.price / order.qty) + ' for ' + str(order.qty) + ' BTC'
        elif order.ordertype == STOP_LOSS:
            if currentprice <= order.price:
                traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            else:
                print "Did not met STOP_LOSS price at: " + str(order.price / order.qty) + ' for ' + str(order.qty) + ' BTC'
        elif order.ordertype == TRAIL_STOP_VALUE:
            if currentprice > order.price:
                order.price = currentprice
                print "Setting new TRAIL_STOP_VALUE max price seen: " + str(order.price / order.qty)
            elif currentprice <= (order.price - order.changeval):
                traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            else:
                print "Did not meet TRAIL_STOP_VALUE price at: " + str((order.price - order.changeval) / order.qty) + ' for ' + str(order.qty) + ' BTC'
        elif order.ordertype == TRAIL_STOP_PERCENT:
            if currentprice > order.price:
                order.price = currentprice
                print "Setting new TRAIL_STOP_PERCENT max price seen: " + str(order.price / order.qty)
            elif currentprice <= (order.price * (1.0 - order.changeval) ):
                traderesult = CoinOrder(ordertype = MARKET_SELL, qty = order.qty, parentorder = order)
            else:
                print "Did not meet TRAIL_STOP_PERCENT price at: " + str((order.price * (1.0 - order.changeval) ) / order.qty) + ' for ' + str(order.qty) + ' BTC'
        else:
            print order.ordertype          # Could throw an error on CoinOrder initialize 
            sys.exit(1)

        return traderesult


    def trade(self, runtime = None, sleeptime = 60):
        """ 
        Returns a table of transaction results when time runs out or runs continously. Writes a log file.

        :param runtime: Number of seconds to trade should execute, infinity (None) is the default.
        :param sleeptime: Interval of time between checking orders (coinbase updates their prices once per 60 seconds)
        """
        initialBtcBal = self.account.balance
        initialUsdVal = self.account.sell_price(initialBtcBal)
        initialSellRate = initialUsdVal/initialBtcBal if initialBtcBal != 0 else 0
        self.logwrite("Initial BTC Balance: " + str(initialBtcBal) + " Initial USD Value: " + str(initialUsdVal) + " Price Per Coin: " + str(initialSellRate)) 
        while ( (runtime is None) or (runtime>0) ) and (len(self.orderbook) > 0):
            try:
                temporderbook = []
                sleep = True

                os.system('clear')
                print "Current Balance: " + str(self.account.balance)
                order_counter = 0
                for order in self.orderbook:
                    order_counter = order_counter + 1
                    print str(order_counter) + ": ",
                    result = self.ExecuteOrder(order)
                    if result is False:
                        # Invalid Order ID
                        pass
                    elif isinstance(result, CoinbaseError):
                        # THere is an error, check if its due to improper supply.
                        print result.error
                        self.logorder(order, result.error[0])
                        if result.error[0] == "You must acknowledge that the price can vary by checking the box below.":
                            temporderbook.append(order)     # Means the order failed due to low supply and not agreeing to the price varying.
                        elif len(self.orderbook) == 1:
                            sleep = False       # This is done to exit quickly if the only trade errors
                    elif isinstance(result, CoinOrder):
                        order.executed = True
                        temporderbook.append(result)
                        sleep = False           # If a coinorder is returned it should be executed asap. 
                    elif isinstance(result, CoinbaseTransfer):
                        # Trade executed
                        order.executed = True
                        self.logexecution(order, result)
                    elif result is None:
                        temporderbook.append(order)

                self.orderbook = temporderbook
                if sleep is True:
                    if runtime is not None:
                        runtime = runtime - sleeptime
                    if runtime is None or runtime > 0:
                        time.sleep(sleeptime)
            except KeyboardInterrupt:
                print "Modifying orders"
                return self.orderbook
            except :
                print "Exception in orders, skipping.."

    def _addOrder(self, ordertype, qty, price = 0, changeval = None):
        """
        Generic Order Adding Function. price is in price per share. User shouldn't call.
        """
        price = price * qty
        order = CoinOrder(ordertype = ordertype, qty = qty, price = price, changeval = changeval)

        self.orderbook.append(order)
        self.logorder(order, "Added Order:")
        return order

    def resumeOrder(self, order):
        return self._addOrder(order.ordertype, order.qty, order.price, order.changeval)

    def setMarketBuy(self, qty):
        """
        Buy qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype = MARKET_BUY, qty = qty)


    def setMarketSell(self, qty):
        """
        Sell qty bitcoins as soon as possible
        """
        return self._addOrder(ordertype = MARKET_SELL, qty = qty)


    def setLimitBuy(self, qty, price):
        """
        Helps buy low, Buy at specified price or lower. Input price per share
        """
        return self._addOrder(ordertype = LIMIT_BUY,qty = qty, price = price)


    def setLimitSell(self, qty, price):
        """
        Helps sell high, Sell at specified price or higher. Input execution price per share
        """
        return self._addOrder(ordertype = LIMIT_SELL, qty = qty, price = price ) 

    def setStopLoss(self, qty, price):
        """
        If the price goes below a specified price, sell it all ASAP via market sell order. Input execution price per share
        """
        return self._addOrder(ordertype = STOP_LOSS, qty = qty, price = price)


    def setTrailStopLossValue(self, qty, changeval):
        """
        Sell qty bitcoins when they drop "value" below their maximum per share value since purchase. Basically a Moving Limit sell at: maxPriceSeen - value
        """
        return self._addOrder(ordertype = TRAIL_STOP_VALUE, qty = qty, price = 0, changeval = changeval*qty)

    def setTrailStopLossPercent(self, qty, changeval, maxprice = 0):
        """
        Sell qty bitcoins when they have a changepercent drop below their maximum value since purchase. Basically a Moving Limit sell at: maxPriceSeen * (1 - (changepercent/100) ) 
        """
        return self._addOrder(ordertype = TRAIL_STOP_PERCENT, qty = qty, price = maxprice, changeval = changeval/100.0)



    def RemoveOrder(self, orderid):
        """
        Accepts either the orderid (starts at 0 and increments to the number of total orders)
        Or the CoinOrder object returned when the order was created.
        """
        startlen = len(self.orderbook)
        # Remove the items if the order id matches
        removedOrder = None
        if isinstance(orderid, int):
            temp = []
            for order in self.orderbook:
                if order.orderid != orderid:
                    temp.append(order)
                else:
                    removedOrder = order
            self.orderbook = temp
        if isinstance(orderid, CoinOrder):
            try:
                self.orderbook.remove(order)
                removedOrder = order         
            except:
                pass
        return removedOrder