aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-03-04 12:59:57 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-03-04 12:59:57 +0100
commit17598517c544a3dda8b9f773dfeb669c886ea92b (patch)
treeeb02553743f2aa2cdd64e2b1cdd02d3c02d4a6cd
parent9db7d156833cd384baa64b6148b5c646bfcc41f8 (diff)
downloadTrader-17598517c544a3dda8b9f773dfeb669c886ea92b.tar.gz
Trader-17598517c544a3dda8b9f773dfeb669c886ea92b.tar.zst
Trader-17598517c544a3dda8b9f773dfeb669c886ea92b.zip
Add close trades action
-rw-r--r--helper.py3
-rw-r--r--portfolio.py8
-rw-r--r--store.py6
-rw-r--r--test.py56
4 files changed, 66 insertions, 7 deletions
diff --git a/helper.py b/helper.py
index f14fd58..95b233a 100644
--- a/helper.py
+++ b/helper.py
@@ -179,6 +179,7 @@ class Processor:
179 "prepare_orders": { "only": "dispose", "compute_value": "average" }, 179 "prepare_orders": { "only": "dispose", "compute_value": "average" },
180 "run_orders": {}, 180 "run_orders": {},
181 "follow_orders": {}, 181 "follow_orders": {},
182 "close_trades": {},
182 }, 183 },
183 { 184 {
184 "name": "buy", 185 "name": "buy",
@@ -191,6 +192,7 @@ class Processor:
191 "move_balances": {}, 192 "move_balances": {},
192 "run_orders": {}, 193 "run_orders": {},
193 "follow_orders": {}, 194 "follow_orders": {},
195 "close_trades": {},
194 }, 196 },
195 ], 197 ],
196 "sell_all": [ 198 "sell_all": [
@@ -204,6 +206,7 @@ class Processor:
204 "prepare_orders": { "compute_value": "average" }, 206 "prepare_orders": { "compute_value": "average" },
205 "run_orders": {}, 207 "run_orders": {},
206 "follow_orders": {}, 208 "follow_orders": {},
209 "close_trades": {},
207 }, 210 },
208 { 211 {
209 "name": "wait", 212 "name": "wait",
diff --git a/portfolio.py b/portfolio.py
index b77850b..f27e84f 100644
--- a/portfolio.py
+++ b/portfolio.py
@@ -290,6 +290,7 @@ class Trade:
290 self.value_to = value_to 290 self.value_to = value_to
291 self.orders = [] 291 self.orders = []
292 self.market = market 292 self.market = market
293 self.closed = False
293 assert self.value_from.value * self.value_to.value >= 0 294 assert self.value_from.value * self.value_to.value >= 0
294 assert self.value_from.currency == self.value_to.currency 295 assert self.value_from.currency == self.value_to.currency
295 if self.value_from != 0: 296 if self.value_from != 0:
@@ -328,6 +329,13 @@ class Trade:
328 return "long" 329 return "long"
329 330
330 @property 331 @property
332 def pending(self):
333 return not (self.is_fullfiled or self.closed)
334
335 def close(self):
336 self.closed = True
337
338 @property
331 def is_fullfiled(self): 339 def is_fullfiled(self):
332 return abs(self.filled_amount(in_base_currency=True)) >= abs(self.delta) 340 return abs(self.filled_amount(in_base_currency=True)) >= abs(self.delta)
333 341
diff --git a/store.py b/store.py
index 43fee03..d9038b7 100644
--- a/store.py
+++ b/store.py
@@ -234,7 +234,7 @@ class TradeStore:
234 234
235 @property 235 @property
236 def pending(self): 236 def pending(self):
237 return list(filter(lambda t: not t.is_fullfiled, self.all)) 237 return list(filter(lambda t: t.pending, self.all))
238 238
239 def compute_trades(self, values_in_base, new_repartition, only=None): 239 def compute_trades(self, values_in_base, new_repartition, only=None):
240 computed_trades = [] 240 computed_trades = []
@@ -275,6 +275,10 @@ class TradeStore:
275 orders.append(trade.prepare_order(compute_value=compute_value)) 275 orders.append(trade.prepare_order(compute_value=compute_value))
276 self.market.report.log_orders(orders, only, compute_value) 276 self.market.report.log_orders(orders, only, compute_value)
277 277
278 def close_trades(self):
279 for trade in self.all:
280 trade.close()
281
278 def print_all_with_order(self, ind=""): 282 def print_all_with_order(self, ind=""):
279 for trade in self.all: 283 for trade in self.all:
280 trade.print_with_order(ind=ind) 284 trade.print_with_order(ind=ind)
diff --git a/test.py b/test.py
index 7409212..78de76e 100644
--- a/test.py
+++ b/test.py
@@ -991,9 +991,9 @@ class TradeStoreTest(WebMockTestCase):
991 trade_mock2.prepare_order.return_value = 2 991 trade_mock2.prepare_order.return_value = 2
992 trade_mock3.prepare_order.return_value = 3 992 trade_mock3.prepare_order.return_value = 3
993 993
994 trade_mock1.is_fullfiled = False 994 trade_mock1.pending = True
995 trade_mock2.is_fullfiled = False 995 trade_mock2.pending = True
996 trade_mock3.is_fullfiled = True 996 trade_mock3.pending = False
997 997
998 trade_store.all.append(trade_mock1) 998 trade_store.all.append(trade_mock1)
999 trade_store.all.append(trade_mock2) 999 trade_store.all.append(trade_mock2)
@@ -1100,13 +1100,30 @@ class TradeStoreTest(WebMockTestCase):
1100 order_mock2.get_status.assert_called() 1100 order_mock2.get_status.assert_called()
1101 order_mock3.get_status.assert_called() 1101 order_mock3.get_status.assert_called()
1102 1102
1103 def test_close_trades(self):
1104 trade_mock1 = mock.Mock()
1105 trade_mock2 = mock.Mock()
1106 trade_mock3 = mock.Mock()
1107
1108 trade_store = market.TradeStore(self.m)
1109
1110 trade_store.all.append(trade_mock1)
1111 trade_store.all.append(trade_mock2)
1112 trade_store.all.append(trade_mock3)
1113
1114 trade_store.close_trades()
1115
1116 trade_mock1.close.assert_called_once_with()
1117 trade_mock2.close.assert_called_once_with()
1118 trade_mock3.close.assert_called_once_with()
1119
1103 def test_pending(self): 1120 def test_pending(self):
1104 trade_mock1 = mock.Mock() 1121 trade_mock1 = mock.Mock()
1105 trade_mock1.is_fullfiled = False 1122 trade_mock1.pending = True
1106 trade_mock2 = mock.Mock() 1123 trade_mock2 = mock.Mock()
1107 trade_mock2.is_fullfiled = False 1124 trade_mock2.pending = True
1108 trade_mock3 = mock.Mock() 1125 trade_mock3 = mock.Mock()
1109 trade_mock3.is_fullfiled = True 1126 trade_mock3.pending = False
1110 1127
1111 trade_store = market.TradeStore(self.m) 1128 trade_store = market.TradeStore(self.m)
1112 1129
@@ -1739,6 +1756,33 @@ class TradeTest(WebMockTestCase):
1739 self.assertEqual("\t\tMouvement 1", str(calls[3][1][0])) 1756 self.assertEqual("\t\tMouvement 1", str(calls[3][1][0]))
1740 self.assertEqual("\t\tMouvement 2", str(calls[4][1][0])) 1757 self.assertEqual("\t\tMouvement 2", str(calls[4][1][0]))
1741 1758
1759 def test_close(self):
1760 value_from = portfolio.Amount("BTC", "0.5")
1761 value_from.linked_to = portfolio.Amount("ETH", "10.0")
1762 value_to = portfolio.Amount("BTC", "1.0")
1763 trade = portfolio.Trade(value_from, value_to, "ETH", self.m)
1764
1765 trade.close()
1766
1767 self.assertEqual(True, trade.closed)
1768
1769 def test_pending(self):
1770 value_from = portfolio.Amount("BTC", "0.5")
1771 value_from.linked_to = portfolio.Amount("ETH", "10.0")
1772 value_to = portfolio.Amount("BTC", "1.0")
1773 trade = portfolio.Trade(value_from, value_to, "ETH", self.m)
1774
1775 trade.closed = True
1776 self.assertEqual(False, trade.pending)
1777
1778 trade.closed = False
1779 self.assertEqual(True, trade.pending)
1780
1781 order1 = mock.Mock()
1782 order1.filled_amount.return_value = portfolio.Amount("BTC", "0.5")
1783 trade.orders.append(order1)
1784 self.assertEqual(False, trade.pending)
1785
1742 def test__repr(self): 1786 def test__repr(self):
1743 value_from = portfolio.Amount("BTC", "0.5") 1787 value_from = portfolio.Amount("BTC", "0.5")
1744 value_from.linked_to = portfolio.Amount("ETH", "10.0") 1788 value_from.linked_to = portfolio.Amount("ETH", "10.0")