def __floordiv__(self, value):
if not isinstance(value, (int, float, D)):
- raise TypeError("Amount may only be multiplied by integers")
+ raise TypeError("Amount may only be divided by numbers")
return Amount(self.currency, self.value / value)
def __truediv__(self, value):
else:
return "long"
- @property
- def filled_amount(self):
+ def filled_amount(self, in_base_currency=False):
filled_amount = 0
for order in self.orders:
- filled_amount += order.filled_amount
+ filled_amount += order.filled_amount(in_base_currency=in_base_currency)
return filled_amount
def update_order(self, order, tick):
if inverted:
ticker = ticker["original"]
rate = Computation.compute_value(ticker, self.order_action(inverted), compute_value=compute_value)
- # 0.1
delta_in_base = abs(self.value_from - self.value_to)
# 9 BTC's worth of move (10 - 1 or 1 - 10 depending on case)
if not inverted:
- currency = self.base_currency
+ base_currency = self.base_currency
# BTC
if self.action == "dispose":
- # I have 10 BTC worth of FOO, and I want to sell 9 BTC worth of it
- # At rate 1 Foo = 0.1 BTC
- value_from = self.value_from.linked_to
- # value_from = 100 FOO
- value_to = self.value_to.in_currency(self.currency, self.market, rate=1/self.value_from.rate)
- # value_to = 10 FOO (1 BTC * 1/0.1)
- delta = abs(value_to - value_from)
- # delta = 90 FOO
- # Action: "sell" "90 FOO" at rate "0.1" "BTC" on "market"
-
- # Note: no rounding error possible: if we have value_to == 0, then delta == value_from
+ filled = self.filled_amount(in_base_currency=False)
+ delta = delta_in_base.in_currency(self.currency, self.market, rate=1/self.value_from.rate)
+ # I have 10 BTC worth of FOO, and I want to sell 9 BTC
+ # worth of it, computed first with rate 10 FOO = 1 BTC.
+ # -> I "sell" "90" FOO at proposed rate "rate".
+
+ delta = delta - filled
+ # I already sold 60 FOO, 30 left
else:
- delta = delta_in_base.in_currency(self.currency, self.market, rate=1/rate)
- # I want to buy 9 / 0.1 FOO
- # Action: "buy" "90 FOO" at rate "0.1" "BTC" on "market"
+ filled = self.filled_amount(in_base_currency=True)
+ delta = (delta_in_base - filled).in_currency(self.currency, self.market, rate=1/rate)
+ # I want to buy 9 BTC worth of FOO, computed with rate
+ # 10 FOO = 1 BTC
+ # -> I "buy" "9 / rate" FOO at proposed rate "rate"
+
+ # I already bought 3 / rate FOO, 6 / rate left
else:
- currency = self.currency
+ base_currency = self.currency
# FOO
- delta = delta_in_base
- # sell:
- # I have 10 BTC worth of FOO, and I want to sell 9 BTC worth of it
- # At rate 1 Foo = 0.1 BTC
- # Action: "buy" "9 BTC" at rate "1/0.1" "FOO" on market
- # buy:
- # I want to buy 9 / 0.1 FOO
- # Action: "sell" "9 BTC" at rate "1/0.1" "FOO" on "market"
- if self.value_to == 0:
- rate = self.value_from.linked_to.value / self.value_from.value
- # Recompute the rate to avoid any rounding error
+ if self.action == "dispose":
+ filled = self.filled_amount(in_base_currency=True)
+ # Base is FOO
+
+ delta = (delta_in_base.in_currency(self.currency, self.market, rate=1/self.value_from.rate)
+ - filled).in_currency(self.base_currency, self.market, rate=1/rate)
+ # I have 10 BTC worth of FOO, and I want to sell 9 BTC worth of it
+ # computed at rate 1 Foo = 0.01 BTC
+ # Computation says I should sell it at 125 FOO / BTC
+ # -> delta_in_base = 9 BTC
+ # -> delta = (9 * 1/0.01 FOO) * 1/125 = 7.2 BTC
+ # Action: "buy" "7.2 BTC" at rate "125" "FOO" on market
+
+ # I already bought 300/125 BTC, only 600/125 left
+ else:
+ filled = self.filled_amount(in_base_currency=False)
+ # Base is FOO
+
+ delta = delta_in_base
+ # I have 1 BTC worth of FOO, and I want to buy 9 BTC worth of it
+ # At rate 100 Foo / BTC
+ # Computation says I should buy it at 125 FOO / BTC
+ # -> delta_in_base = 9 BTC
+ # Action: "sell" "9 BTC" at rate "125" "FOO" on market
+
+ delta = delta - filled
+ # I already sold 4 BTC, only 5 left
close_if_possible = (self.value_to == 0)
- if delta <= self.filled_amount:
- print("Less to do than already filled: {} <= {}".format(delta,
- self.filled_amount))
+ if delta <= 0:
+ print("Less to do than already filled: {}".format(delta))
return
self.orders.append(Order(self.order_action(inverted),
- delta - self.filled_amount, rate, currency, self.trade_type,
+ delta, rate, base_currency, self.trade_type,
self.market, self, close_if_possible=close_if_possible))
def __repr__(self):
def remaining_amount(self):
if self.status == "open":
self.fetch()
- return self.amount - self.filled_amount
+ return self.amount - self.filled_amount()
- @property
- def filled_amount(self):
+ def filled_amount(self, in_base_currency=False):
if self.status == "open":
self.fetch()
- filled_amount = Amount(self.amount.currency, 0)
+ filled_amount = 0
for mouvement in self.mouvements:
- filled_amount += mouvement.total
+ if in_base_currency:
+ filled_amount += mouvement.total_in_base
+ else:
+ filled_amount += mouvement.total
return filled_amount
def fetch_mouvements(self):