Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented ActiveParticipant for MtGox. #16

Merged
merged 2 commits into from Jan 31, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions mexbtcapi/api/mtgox/__init__.py
@@ -1,4 +1,5 @@
from mexbtcapi.api.mtgox.http_v1.high_level import Market
from mexbtcapi.api.mtgox.http_v1.high_level import MtGoxMarket, MtGoxParticipant

name = Market.MARKET_NAME
market = Market
name = MtGoxMarket.MARKET_NAME
market = MtGoxMarket
participant = MtGoxParticipant
109 changes: 106 additions & 3 deletions mexbtcapi/api/mtgox/http_v1/high_level.py
@@ -1,19 +1,43 @@
from datetime import datetime, timedelta
from decimal import Decimal
from functools import partial
import logging

from mexbtcapi import concepts
from mexbtcapi.concepts.currencies import BTC
from mexbtcapi.concepts.currency import Amount, ExchangeRate
from mexbtcapi.concepts.market import Market as BaseMarket, Order, Trade
from mexbtcapi.concepts.currency import Amount, Currency, ExchangeRate
from mexbtcapi.concepts.market import ActiveParticipant, Market as BaseMarket, Order, Trade
import mtgox as low_level


logger = logging.getLogger(__name__)


class MtgoxTicker(concepts.market.Ticker):
TIME_PERIOD = timedelta(days=1)

def __repr__(self):
return \
"<MtgoxTicker({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8})" \
.format(self.market, self.time, self.high, self.high, self.last,
self.volume, self.average, self.buy, self.sell)


class MtGoxOrder(Order):

def __init__(self, market, oid, timestamp, buy_or_sell, from_amount,
exchange_rate, properties="", entity=None):
super(MtGoxOrder, self).__init__(market, timestamp, buy_or_sell, from_amount, exchange_rate, properties, entity)
self.oid = oid

class Market(BaseMarket):
def __repr__(self):
return \
"<MtGoxOrder({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}>" \
.format(self.market, self.timestamp, self.oid, self.buy_or_sell,
self.from_amount, self.exchange_rate, self.properties, self.entity)


class MtGoxMarket(BaseMarket):
MARKET_NAME = "MtGox"

def __init__(self, currency):
Expand All @@ -28,6 +52,8 @@ def _multiplier(self, currency):
return self.multiplier[currency.name]

def getTicker(self):
logger.debug("getting ticker")

time = datetime.now()
data = low_level.ticker(self.currency1.name)

Expand All @@ -43,6 +69,8 @@ def getTicker(self):
return ticker

def getDepth(self):
logger.debug("getting depth")

low_level_depth = low_level.depth()

return {
Expand All @@ -66,6 +94,8 @@ def _depthToOrders(self, depth, order_type):
return orders

def getTrades(self):
logger.debug("getting trades")

low_level_trades = low_level.trades()

# convert tradres to array of Trades
Expand All @@ -86,3 +116,76 @@ def getTrades(self):
trades.append(t)

return trades


class MtGoxParticipant(MtGoxMarket, ActiveParticipant):

def __init__(self, currency, key, secret):
MtGoxMarket.__init__(self, currency)

self.private = low_level.Private(key, secret)

def placeBidOrder(self, amount, price):
"""places an Order in the market for price/amount"""

logger.debug("placing bid order")

oid = self.private.bid(amount.value, price.exchange_rate)

now = datetime.now()
return MtGoxOrder(self, oid, now, Order.BID, amount, price, entity=self)

def placeAskOrder(self, amount, price):
"""places an Order in the market for price/amount"""

logger.debug("placing ask order")

oid = self.private.ask(amount, price)

now = datetime.now()
return MtGoxOrder(self, oid, now, Order.ASK, amount, price, entity=self)

def cancelOrder(self, order):
"""Cancel an existing order"""
assert(isinstance(order, MtGoxOrder))

logger.debug("cancelling order {0}".format(order.oid))

oid = order.oid
if order.is_buy_order():
result = self.private.cancel_bid(oid)
else:
result = self.private.cancel_ask(oid)

if not result:
raise ActiveParticipant.ActiveParticipantError()

def getOpenOrders(self):
"""Gets all the open orders"""

logger.debug("getting open orders")

low_level_orders = self.private.orders()
orders = []

for o in low_level_orders:
currency = Currency(o['currency'])
oid = o['oid']
timestamp = datetime.fromtimestamp(o['date'])
order_type = Order.BID if o['type'] else Order.ASK
amount = Amount(Decimal(o['amount']['value_int']) / self._multiplier(BTC), BTC)
price = ExchangeRate(currency, BTC, Decimal(o['price']['value_int']) / self._multiplier(currency))
order = MtGoxOrder(self, oid, timestamp, order_type, amount, price, entity=self)

# add additional status from MtGox
order.status = o['status']

orders.append(order)

return orders

def __str__(self):
return self.__repr__()

def __repr__(self):
return "<MtGoxParticipant({0})>".format(self.currency1)
8 changes: 4 additions & 4 deletions mexbtcapi/api/mtgox/http_v1/mtgox.py
Expand Up @@ -212,11 +212,11 @@ def info(self):
def orders(self):
"""Return standing orders"""
return self._generic('orders')

def wallet_history(self,type='',date_start='',date_end='',trade_id='',page='',currency=CURRENCY) :
url = "https://mtgox.com/api/1/generic/wallet/history"
data = {
'currency' : currency,
'currency' : currency,
'type' : type,
'date_start' : date_start,
'date_end' : date_end,
Expand Down Expand Up @@ -252,7 +252,7 @@ def ask(self, amount, price, currency=CURRENCY):
an expanded format. For example, int(12300000)BTC
is interpreted as 1.23BTC.
"""
self._order_add('ask', amount, price, currency)
return self._order_add('ask', amount, price, currency)

def bid(self, amount, price, currency=CURRENCY):
"""Buy bitcoins
Expand All @@ -261,7 +261,7 @@ def bid(self, amount, price, currency=CURRENCY):
an expanded format. For example, int(12300000)BTC
is interpreted as 1.23BTC.
"""
self._order_add('bid', amount, price, currency)
return self._order_add('bid', amount, price, currency)

def _order_add(self, order_type, amount, price, currency):
if type(amount) in (Decimal, float):
Expand Down
44 changes: 30 additions & 14 deletions mexbtcapi/concepts/market.py
Expand Up @@ -43,31 +43,28 @@ class Order(object):
ASK = 'ASK'

def __init__(self, market, timestamp, buy_or_sell, from_amount,
exchange_rate, properties="",
from_entity=None, to_entity=None):
exchange_rate, properties="", entity=None):
assert isinstance(market, Market) # must not be null
assert isinstance(timestamp, datetime) # must not be null
assert buy_or_sell in [self.BID, self.ASK]
assert isinstance(from_amount, Amount)
assert isinstance(exchange_rate, ExchangeRate)
assert isinstance(properties, str)
assert all([x is None or isinstance(x, Participant) for x
in (from_entity, to_entity)])
assert entity is None or isinstance(entity, Participant)

self.market = market
self.timestamp = timestamp
self.buy_or_sell = buy_or_sell
self.from_amount = from_amount
self.exchange_rate = exchange_rate
self.properties = properties
self.from_entity = from_entity
self.to_entity = to_entity
self.entity = entity

def is_buy_order(self):
return self.buy_or_sell == self.BUY
return self.buy_or_sell == self.BID

def is_sell_order(self):
return self.buy_or_sell == self.SELL
return self.buy_or_sell != self.BID

def __str__(self):
return "{0} -> {1}".format(self.from_amount, self.exchange_rate)
Expand Down Expand Up @@ -127,18 +124,31 @@ class ActiveParticipant(Participant):
"""A participant under user control (may be the user itself)
"""

def placeTrade(trade):
"""places a trade in the market"""
def placeBidOrder(self, price, amount):
"""places an Order in the market for price/amount"""
raise NotImplementedError()

def cancelTrade(trade):
def placeAskOrder(self, price, amount):
"""places an Order in the market for price/amount"""
raise NotImplementedError()

class TradeAlreadyClosedError(Exception):
"""Occurs when trying to cancel a already-closed trade"""
def cancelOrder(self, order):
"""Cancel an existing order"""
raise NotImplementedError()

def getOpenOrders(self):
"""Gets all the open orders"""
raise NotImplementedError()

class ActiveParitipantError(Exception):
"""Base ActiveParticipant error"""
pass

class NotAuthorizedError(Exception):
class OrderAlreadyClosedError(ActiveParitipantError):
"""Occurs when trying to cancel a already-closed Order"""
pass

class NotAuthorizedError(ActiveParitipantError):
"""Occurs when the user is not authorized to do the requested operation
"""
pass
Expand Down Expand Up @@ -170,3 +180,9 @@ def __init__(self, market, time, high=None, low=None, average=None,
self.market, self.time, self.volume = market, time, volume
self.high, self.low, self.average, self.last, self.sell, self.buy = \
high, low, average, last, sell, buy

def __repr__(self):
return \
"<Ticker({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8})" \
.format(self.market, self.time, self.high, self.high, self.last,
self.volume, self.average, self.buy, self.sell)