3 @unittest.skipUnless("acceptance" in limits
, "Acceptance skipped")
4 class AcceptanceTest(WebMockTestCase
):
5 @unittest.expectedFailure
6 def test_success_sell_only_necessary(self
):
8 self
.m
.report
.verbose_print
= False
11 "exchange_free": D("1.0"),
12 "exchange_used": D("0.0"),
13 "exchange_total": D("1.0"),
17 "exchange_free": D("4.0"),
18 "exchange_used": D("0.0"),
19 "exchange_total": D("4.0"),
23 "exchange_free": D("1000.0"),
24 "exchange_used": D("0.0"),
25 "exchange_total": D("1000.0"),
30 "ETH": (D("0.25"), "long"),
31 "ETC": (D("0.25"), "long"),
32 "BTC": (D("0.4"), "long"),
33 "BTD": (D("0.01"), "short"),
34 "B2X": (D("0.04"), "long"),
35 "USDT": (D("0.05"), "long"),
38 def fetch_ticker(symbol
):
39 if symbol
== "ETH/BTC":
45 if symbol
== "ETC/BTC":
51 if symbol
== "XVG/BTC":
57 if symbol
== "BTD/BTC":
63 if symbol
== "B2X/BTC":
69 if symbol
== "USDT/BTC":
70 raise helper
.ExchangeError
71 if symbol
== "BTC/USDT":
77 self
.fail("Shouldn't have been called with {}".format(symbol
))
80 market
.fetch_all_balances
.return_value
= fetch_balance
81 market
.fetch_ticker
.side_effect
= fetch_ticker
82 with mock
.patch
.object(market
.Portfolio
, "repartition", return_value
=repartition
):
84 helper
.prepare_trades(market
)
86 balances
= portfolio
.BalanceStore
.all
87 self
.assertEqual(portfolio
.Amount("ETH", 1), balances
["ETH"].total
)
88 self
.assertEqual(portfolio
.Amount("ETC", 4), balances
["ETC"].total
)
89 self
.assertEqual(portfolio
.Amount("XVG", 1000), balances
["XVG"].total
)
92 trades
= portfolio
.TradeStore
.all
93 self
.assertEqual(portfolio
.Amount("BTC", D("0.15")), trades
[0].value_from
)
94 self
.assertEqual(portfolio
.Amount("BTC", D("0.05")), trades
[0].value_to
)
95 self
.assertEqual("dispose", trades
[0].action
)
97 self
.assertEqual(portfolio
.Amount("BTC", D("0.01")), trades
[1].value_from
)
98 self
.assertEqual(portfolio
.Amount("BTC", D("0.05")), trades
[1].value_to
)
99 self
.assertEqual("acquire", trades
[1].action
)
101 self
.assertEqual(portfolio
.Amount("BTC", D("0.04")), trades
[2].value_from
)
102 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[2].value_to
)
103 self
.assertEqual("dispose", trades
[2].action
)
105 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[3].value_from
)
106 self
.assertEqual(portfolio
.Amount("BTC", D("-0.002")), trades
[3].value_to
)
107 self
.assertEqual("acquire", trades
[3].action
)
109 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[4].value_from
)
110 self
.assertEqual(portfolio
.Amount("BTC", D("0.008")), trades
[4].value_to
)
111 self
.assertEqual("acquire", trades
[4].action
)
113 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[5].value_from
)
114 self
.assertEqual(portfolio
.Amount("BTC", D("0.01")), trades
[5].value_to
)
115 self
.assertEqual("acquire", trades
[5].action
)
118 portfolio
.TradeStore
.prepare_orders(only
="dispose", compute_value
=lambda x
, y
: x
["bid"] * D("1.001"))
120 all_orders
= portfolio
.TradeStore
.all_orders(state
="pending")
121 self
.assertEqual(2, len(all_orders
))
122 self
.assertEqual(2, 3*all_orders
[0].amount
.value
)
123 self
.assertEqual(D("0.14014"), all_orders
[0].rate
)
124 self
.assertEqual(1000, all_orders
[1].amount
.value
)
125 self
.assertEqual(D("0.00003003"), all_orders
[1].rate
)
128 def create_order(symbol
, type, action
, amount
, price
=None, account
="exchange"):
129 self
.assertEqual("limit", type)
130 if symbol
== "ETH/BTC":
131 self
.assertEqual("sell", action
)
132 self
.assertEqual(D('0.66666666'), amount
)
133 self
.assertEqual(D("0.14014"), price
)
134 elif symbol
== "XVG/BTC":
135 self
.assertEqual("sell", action
)
136 self
.assertEqual(1000, amount
)
137 self
.assertEqual(D("0.00003003"), price
)
139 self
.fail("I shouldn't have been called")
144 market
.create_order
.side_effect
= create_order
145 market
.order_precision
.return_value
= 8
148 portfolio
.TradeStore
.run_orders()
150 self
.assertEqual("open", all_orders
[0].status
)
151 self
.assertEqual("open", all_orders
[1].status
)
153 market
.fetch_order
.return_value
= { "status": "closed", "datetime": "2018-01-20 13:40:00" }
154 market
.privatePostReturnOrderTrades
.return_value
= [
156 "tradeID": 42, "type": "buy", "fee": "0.0015",
157 "date": "2017-12-30 12:00:12", "rate": "0.1",
158 "amount": "10", "total": "1"
161 with mock
.patch
.object(market
.time
, "sleep") as sleep
:
163 helper
.follow_orders(verbose
=False)
165 sleep
.assert_called_with(30)
167 for order
in all_orders
:
168 self
.assertEqual("closed", order
.status
)
172 "exchange_free": D("1.0") / 3,
173 "exchange_used": D("0.0"),
174 "exchange_total": D("1.0") / 3,
176 "total": D("1.0") / 3,
179 "exchange_free": D("0.134"),
180 "exchange_used": D("0.0"),
181 "exchange_total": D("0.134"),
186 "exchange_free": D("4.0"),
187 "exchange_used": D("0.0"),
188 "exchange_total": D("4.0"),
193 "exchange_free": D("0.0"),
194 "exchange_used": D("0.0"),
195 "exchange_total": D("0.0"),
200 market
.fetch_all_balances
.return_value
= fetch_balance
202 with mock
.patch
.object(market
.Portfolio
, "repartition", return_value
=repartition
):
204 helper
.prepare_trades(market
, only
="acquire", compute_value
="average")
206 balances
= portfolio
.BalanceStore
.all
207 self
.assertEqual(portfolio
.Amount("ETH", 1 / D("3")), balances
["ETH"].total
)
208 self
.assertEqual(portfolio
.Amount("ETC", 4), balances
["ETC"].total
)
209 self
.assertEqual(portfolio
.Amount("BTC", D("0.134")), balances
["BTC"].total
)
210 self
.assertEqual(portfolio
.Amount("XVG", 0), balances
["XVG"].total
)
213 trades
= portfolio
.TradeStore
.all
214 self
.assertEqual(portfolio
.Amount("BTC", D("0.15")), trades
[0].value_from
)
215 self
.assertEqual(portfolio
.Amount("BTC", D("0.05")), trades
[0].value_to
)
216 self
.assertEqual("dispose", trades
[0].action
)
218 self
.assertEqual(portfolio
.Amount("BTC", D("0.01")), trades
[1].value_from
)
219 self
.assertEqual(portfolio
.Amount("BTC", D("0.05")), trades
[1].value_to
)
220 self
.assertEqual("acquire", trades
[1].action
)
222 self
.assertNotIn("BTC", trades
)
224 self
.assertEqual(portfolio
.Amount("BTC", D("0.04")), trades
[2].value_from
)
225 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[2].value_to
)
226 self
.assertEqual("dispose", trades
[2].action
)
228 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[3].value_from
)
229 self
.assertEqual(portfolio
.Amount("BTC", D("-0.002")), trades
[3].value_to
)
230 self
.assertEqual("acquire", trades
[3].action
)
232 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[4].value_from
)
233 self
.assertEqual(portfolio
.Amount("BTC", D("0.008")), trades
[4].value_to
)
234 self
.assertEqual("acquire", trades
[4].action
)
236 self
.assertEqual(portfolio
.Amount("BTC", D("0.00")), trades
[5].value_from
)
237 self
.assertEqual(portfolio
.Amount("BTC", D("0.01")), trades
[5].value_to
)
238 self
.assertEqual("acquire", trades
[5].action
)
241 portfolio
.TradeStore
.prepare_orders(only
="acquire", compute_value
=lambda x
, y
: x
["ask"])
243 all_orders
= portfolio
.TradeStore
.all_orders(state
="pending")
244 self
.assertEqual(4, len(all_orders
))
245 self
.assertEqual(portfolio
.Amount("ETC", D("12.83333333")), round(all_orders
[0].amount
))
246 self
.assertEqual(D("0.003"), all_orders
[0].rate
)
247 self
.assertEqual("buy", all_orders
[0].action
)
248 self
.assertEqual("long", all_orders
[0].trade_type
)
250 self
.assertEqual(portfolio
.Amount("BTD", D("1.61666666")), round(all_orders
[1].amount
))
251 self
.assertEqual(D("0.0012"), all_orders
[1].rate
)
252 self
.assertEqual("sell", all_orders
[1].action
)
253 self
.assertEqual("short", all_orders
[1].trade_type
)
255 diff
= portfolio
.Amount("B2X", D("19.4")/3) - all_orders
[2].amount
256 self
.assertAlmostEqual(0, diff
.value
)
257 self
.assertEqual(D("0.0012"), all_orders
[2].rate
)
258 self
.assertEqual("buy", all_orders
[2].action
)
259 self
.assertEqual("long", all_orders
[2].trade_type
)
261 self
.assertEqual(portfolio
.Amount("BTC", D("0.0097")), all_orders
[3].amount
)
262 self
.assertEqual(D("16000"), all_orders
[3].rate
)
263 self
.assertEqual("sell", all_orders
[3].action
)
264 self
.assertEqual("long", all_orders
[3].trade_type
)
268 # Move balances to margin
272 # portfolio.TradeStore.run_orders()
274 with mock
.patch
.object(market
.time
, "sleep") as sleep
:
276 helper
.follow_orders(verbose
=False)
278 sleep
.assert_called_with(30)