2 from ccxt
import ExchangeError
5 def move_balances(market
, debug
=False):
9 for currency
in BalanceStore
.all
:
10 if BalanceStore
.all
[currency
].margin_free
!= 0:
11 needed_in_margin
[currency
] = 0
12 for trade
in TradeStore
.all
:
13 if trade
.value_to
.currency
not in needed_in_margin
:
14 needed_in_margin
[trade
.value_to
.currency
] = 0
15 if trade
.trade_type
== "short":
16 needed_in_margin
[trade
.value_to
.currency
] += abs(trade
.value_to
)
17 for currency
, needed
in needed_in_margin
.items():
18 current_balance
= BalanceStore
.all
[currency
].margin_free
19 moving_to_margin
[currency
] = (needed
- current_balance
)
20 delta
= moving_to_margin
[currency
].value
22 ReportStore
.log_debug_action("Moving {} from exchange to margin".format(moving_to_margin
[currency
]))
25 market
.transfer_balance(currency
, delta
, "exchange", "margin")
27 market
.transfer_balance(currency
, -delta
, "margin", "exchange")
28 ReportStore
.log_move_balances(needed_in_margin
, moving_to_margin
, debug
)
30 BalanceStore
.fetch_balances(market
)
33 ticker_cache_timestamp
= time
.time()
34 def get_ticker(c1
, c2
, market
, refresh
=False):
35 global ticker_cache
, ticker_cache_timestamp
39 "average": (1/ticker
["bid"] + 1/ticker
["ask"]) / 2,
42 def augment_ticker(ticker
):
45 "average": (ticker
["bid"] + ticker
["ask"] ) / 2,
48 if time
.time() - ticker_cache_timestamp
> 5:
50 ticker_cache_timestamp
= time
.time()
52 if (c1
, c2
, market
.__class
__) in ticker_cache
:
53 return ticker_cache
[(c1
, c2
, market
.__class
__)]
54 if (c2
, c1
, market
.__class
__) in ticker_cache
:
55 return invert(ticker_cache
[(c2
, c1
, market
.__class
__)])
58 ticker_cache
[(c1
, c2
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c1
, c2
))
59 augment_ticker(ticker_cache
[(c1
, c2
, market
.__class
__)])
62 ticker_cache
[(c2
, c1
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c2
, c1
))
63 augment_ticker(ticker_cache
[(c2
, c1
, market
.__class
__)])
65 ticker_cache
[(c1
, c2
, market
.__class
__)] = None
66 return get_ticker(c1
, c2
, market
)
69 def fetch_fees(market
):
71 if market
.__class
__ not in fees_cache
:
72 fees_cache
[market
.__class
__] = market
.fetch_fees()
73 return fees_cache
[market
.__class
__]
75 def prepare_trades(market
, base_currency
="BTC", liquidity
="medium", compute_value
="average", debug
=False):
76 ReportStore
.log_stage("prepare_trades")
77 values_in_base
= BalanceStore
.in_currency(base_currency
, market
, compute_value
=compute_value
)
78 total_base_value
= sum(values_in_base
.values())
79 new_repartition
= BalanceStore
.dispatch_assets(total_base_value
, liquidity
=liquidity
)
80 # Recompute it in case we have new currencies
81 values_in_base
= BalanceStore
.in_currency(base_currency
, market
, compute_value
=compute_value
)
82 TradeStore
.compute_trades(values_in_base
, new_repartition
, market
=market
, debug
=debug
)
84 def update_trades(market
, base_currency
="BTC", liquidity
="medium", compute_value
="average", only
=None, debug
=False):
85 ReportStore
.log_stage("update_trades")
86 values_in_base
= BalanceStore
.in_currency(base_currency
, market
, compute_value
=compute_value
)
87 total_base_value
= sum(values_in_base
.values())
88 new_repartition
= BalanceStore
.dispatch_assets(total_base_value
, liquidity
=liquidity
)
89 TradeStore
.compute_trades(values_in_base
, new_repartition
, only
=only
, market
=market
, debug
=debug
)
91 def prepare_trades_to_sell_all(market
, base_currency
="BTC", compute_value
="average", debug
=False):
92 ReportStore
.log_stage("prepare_trades_to_sell_all")
93 values_in_base
= BalanceStore
.in_currency(base_currency
, market
, compute_value
=compute_value
)
94 total_base_value
= sum(values_in_base
.values())
95 new_repartition
= BalanceStore
.dispatch_assets(total_base_value
, repartition
={ base_currency: (1, "long") }
)
96 TradeStore
.compute_trades(values_in_base
, new_repartition
, market
=market
, debug
=debug
)
98 def follow_orders(sleep
=None):
100 sleep
= 7 if TradeStore
.debug
else 30
102 ReportStore
.log_debug_action("Set follow_orders tick to {}s".format(sleep
))
104 ReportStore
.log_stage("follow_orders_begin")
105 while len(TradeStore
.all_orders(state
="open")) > 0:
108 open_orders
= TradeStore
.all_orders(state
="open")
109 ReportStore
.log_stage("follow_orders_tick_{}".format(tick
))
110 ReportStore
.log_orders(open_orders
, tick
=tick
)
111 for order
in open_orders
:
112 if order
.get_status() != "open":
113 ReportStore
.log_order(order
, tick
, finished
=True)
115 order
.trade
.update_order(order
, tick
)
116 ReportStore
.log_stage("follow_orders_end")
118 def print_orders(market
, base_currency
="BTC"):
119 ReportStore
.log_stage("print_orders")
120 BalanceStore
.fetch_balances(market
, tag
="print_orders")
121 prepare_trades(market
, base_currency
=base_currency
, compute_value
="average", debug
=True)
122 TradeStore
.prepare_orders(compute_value
="average")
124 def print_balances(market
, base_currency
="BTC"):
125 BalanceStore
.fetch_balances(market
)
126 if base_currency
is not None:
127 ReportStore
.print_log("total:")
128 ReportStore
.print_log(sum(BalanceStore
.in_currency(base_currency
, market
).values()))
131 # use them as regular classes, sub-object of market
132 ReportStore
.logs
= []
133 BalanceStore
.all
= {}
136 def process_sell_needed__1_sell(market
, liquidity
="medium", base_currency
="BTC", debug
=False):
137 ReportStore
.log_stage("process_sell_needed__1_sell_begin")
138 BalanceStore
.fetch_balances(market
, tag
="process_sell_needed__1_sell_begin")
139 prepare_trades(market
, liquidity
=liquidity
, base_currency
=base_currency
, debug
=debug
)
140 TradeStore
.prepare_orders(compute_value
="average", only
="dispose")
141 TradeStore
.run_orders()
143 BalanceStore
.fetch_balances(market
, tag
="process_sell_needed__1_sell_end")
144 ReportStore
.log_stage("process_sell_needed__1_sell_end")
146 def process_sell_needed__2_buy(market
, liquidity
="medium", base_currency
="BTC", debug
=False):
147 ReportStore
.log_stage("process_sell_needed__2_buy_begin")
148 BalanceStore
.fetch_balances(market
, tag
="process_sell_needed__2_buy_begin")
149 update_trades(market
, base_currency
=base_currency
, liquidity
=liquidity
, debug
=debug
, only
="acquire")
150 TradeStore
.prepare_orders(compute_value
="average", only
="acquire")
151 move_balances(market
, debug
=debug
)
152 TradeStore
.run_orders()
154 BalanceStore
.fetch_balances(market
, tag
="process_sell_needed__2_buy_end")
155 ReportStore
.log_stage("process_sell_needed__2_buy_end")
157 def process_sell_all__1_all_sell(market
, base_currency
="BTC", debug
=False, liquidity
="medium"):
158 ReportStore
.log_stage("process_sell_all__1_all_sell_begin")
159 BalanceStore
.fetch_balances(market
, tag
="process_sell_all__1_all_sell_begin")
160 prepare_trades_to_sell_all(market
, base_currency
=base_currency
, debug
=debug
)
161 TradeStore
.prepare_orders(compute_value
="average")
162 TradeStore
.run_orders()
164 BalanceStore
.fetch_balances(market
, tag
="process_sell_all__1_all_sell_end")
165 ReportStore
.log_stage("process_sell_all__1_all_sell_end")
167 def process_sell_all__2_all_buy(market
, base_currency
="BTC", debug
=False, liquidity
="medium"):
168 ReportStore
.log_stage("process_sell_all__2_all_buy_begin")
169 BalanceStore
.fetch_balances(market
, tag
="process_sell_all__2_all_buy_begin")
170 prepare_trades(market
, liquidity
=liquidity
, base_currency
=base_currency
, debug
=debug
)
171 TradeStore
.prepare_orders(compute_value
="average")
172 move_balances(market
, debug
=debug
)
173 TradeStore
.run_orders()
175 BalanceStore
.fetch_balances(market
, tag
="process_sell_all__2_all_buy_end")
176 ReportStore
.log_stage("process_sell_all__2_all_buy_end")