import time
+from datetime import datetime
from decimal import Decimal as D, ROUND_DOWN
# Put your poloniex api key in market.py
from json import JSONDecodeError
+from ccxt import ExchangeError, ExchangeNotAvailable
import requests
import helper as h
from store import *
if self.base_currency == self.currency:
return None
- if self.value_from < self.value_to:
+ if abs(self.value_from) < abs(self.value_to):
return "acquire"
else:
return "dispose"
if tick in [0, 1, 3, 4, 6]:
print("{}, tick {}, waiting".format(order, tick))
elif tick == 2:
- self.prepare_order(compute_value=lambda x, y: (x[y] + x["average"]) / 2)
- new_order = self.orders[-1]
+ new_order = self.prepare_order(compute_value=lambda x, y: (x[y] + x["average"]) / 2)
print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order))
elif tick ==5:
- self.prepare_order(compute_value=lambda x, y: (x[y]*2 + x["average"]) / 3)
- new_order = self.orders[-1]
+ new_order = self.prepare_order(compute_value=lambda x, y: (x[y]*2 + x["average"]) / 3)
print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order))
elif tick >= 7:
if tick == 7:
print("{}, tick {}, fallbacking to market value".format(order, tick))
if (tick - 7) % 3 == 0:
- self.prepare_order(compute_value="default")
- new_order = self.orders[-1]
+ new_order = self.prepare_order(compute_value="default")
print("{}, tick {}, market value, cancelling and adjusting to {}".format(order, tick, new_order))
if new_order is not None:
def prepare_order(self, compute_value="default"):
if self.action is None:
- return
+ return None
ticker = h.get_ticker(self.currency, self.base_currency, self.market)
inverted = ticker["inverted"]
if inverted:
if delta <= 0:
print("Less to do than already filled: {}".format(delta))
- return
+ return None
- self.orders.append(Order(self.order_action(inverted),
+ order = Order(self.order_action(inverted),
delta, rate, base_currency, self.trade_type,
- self.market, self, close_if_possible=close_if_possible))
+ self.market, self, close_if_possible=close_if_possible)
+ self.orders.append(order)
+ return order
def __repr__(self):
return "Trade({} -> {} in {}, {})".format(
self.status = "pending"
self.trade = trade
self.close_if_possible = close_if_possible
+ self.id = None
+ self.fetch_cache_timestamp = None
def __repr__(self):
return "Order({} {} {} at {} {} [{}]{})".format(
else:
return "margin"
+ @property
+ def open(self):
+ return self.status == "open"
+
@property
def pending(self):
return self.status == "pending"
def finished(self):
return self.status == "closed" or self.status == "canceled" or self.status == "error"
- @property
- def id(self):
- return self.results[0]["id"]
-
def run(self):
symbol = "{}/{}".format(self.amount.currency, self.base_currency)
amount = round(self.amount, self.market.order_precision(symbol)).value
if TradeStore.debug:
print("market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(
symbol, self.action, amount, self.rate, self.account))
- self.status = "open"
self.results.append({"debug": True, "id": -1})
else:
try:
self.results.append(self.market.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account))
- self.status = "open"
+ except ExchangeNotAvailable:
+ # Impossible to honor the order (dust amount)
+ self.status = "closed"
+ self.mark_finished_order()
+ return
except Exception as e:
self.status = "error"
print("error when running market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(
symbol, self.action, amount, self.rate, self.account))
self.error_message = str("{}: {}".format(e.__class__.__name__, e))
print(self.error_message)
+ return
+ self.id = self.results[0]["id"]
+ self.status = "open"
def get_status(self):
if TradeStore.debug:
return self.status
# other states are "closed" and "canceled"
- if self.status == "open":
+ if not self.finished:
self.fetch()
- if self.status != "open":
+ if self.finished:
self.mark_finished_order()
return self.status
if self.trade_type == "short" and self.action == "buy" and self.close_if_possible:
self.market.close_margin_position(self.amount.currency, self.base_currency)
- fetch_cache_timestamp = None
def fetch(self, force=False):
if TradeStore.debug or (not force and self.fetch_cache_timestamp is not None
and time.time() - self.fetch_cache_timestamp < 10):
return
self.fetch_cache_timestamp = time.time()
- self.results.append(self.market.fetch_order(self.id))
- result = self.results[-1]
+ result = self.market.fetch_order(self.id)
+ self.results.append(result)
+
self.status = result["status"]
# Time at which the order started
self.timestamp = result["datetime"]
# FIXME: consider open order with dust remaining as closed
- @property
def dust_amount_remaining(self):
- return self.remaining_amount < 0.001
+ return self.remaining_amount() < Amount(self.amount.currency, D("0.001"))
- @property
def remaining_amount(self):
if self.status == "open":
self.fetch()
return filled_amount
def fetch_mouvements(self):
- mouvements = self.market.privatePostReturnOrderTrades({"orderNumber": self.id})
+ try:
+ mouvements = self.market.privatePostReturnOrderTrades({"orderNumber": self.id})
+ except ExchangeError:
+ mouvements = []
self.mouvements = []
for mouvement_hash in mouvements:
if TradeStore.debug:
self.status = "canceled"
return
- self.market.cancel_order(self.result['id'])
+ self.market.cancel_order(self.id)
self.fetch()
class Mouvement:
def __init__(self, currency, base_currency, hash_):
self.currency = currency
self.base_currency = base_currency
- self.id = hash_["id"]
- self.action = hash_["type"]
- self.fee_rate = D(hash_["fee"])
- self.date = datetime.strptime(hash_["date"], '%Y-%m-%d %H:%M:%S')
- self.rate = D(hash_["rate"])
- self.total = Amount(currency, hash_["amount"])
+ self.id = hash_.get("tradeID")
+ self.action = hash_.get("type")
+ self.fee_rate = D(hash_.get("fee", -1))
+ try:
+ self.date = datetime.strptime(hash_.get("date", ""), '%Y-%m-%d %H:%M:%S')
+ except ValueError:
+ self.date = None
+ self.rate = D(hash_.get("rate", 0))
+ self.total = Amount(currency, hash_.get("amount", 0))
# rate * total = total_in_base
- self.total_in_base = Amount(base_currency, hash_["total"])
+ self.total_in_base = Amount(base_currency, hash_.get("total", 0))
-if __name__ == '__main__':
+if __name__ == '__main__': # pragma: no cover
from market import market
h.print_orders(market)