Esempio n. 1
0
 def process_withdrawals(self):
     # Set wallet from relevant currency according to side
     to_wallet = (
         self.buda.wallets.base if self.side == Side.BUY else self.buda.wallets.quote
     )
     for deposit in self.deposits.values():
         # Load money amounts
         original_amount = Money.loads(deposit["amounts"]["original_amount"])
         converted_amount = Money.loads(deposit["amounts"]["converted_amount"])
         converted_value = Money.loads(deposit["amounts"]["converted_value"])
         remaining = original_amount - converted_amount
         if (
             self.side == Side.BUY
         ):  # Change remaining amount to base currency for minimum order amount check
             remaining = (
                 self.buda.fetch_order_book().quote(self.side, remaining).base_amount
             )
         # Filter deposits already converted and pending withdrawal
         original_amount_is_converted = remaining < self.buda.min_order_amount
         if (
             deposit["status"] == TxStatus.OK.value
             and deposit["pending_withdrawal"]
             and original_amount_is_converted
         ):
             withdrawal_amount = truncate_money(converted_value)
             available = to_wallet.fetch_balance().free
             if (
                 withdrawal_amount <= available
             ):  # We cannot withdraw more than available balance
                 w = to_wallet.request_withdrawal(
                     withdrawal_amount, self.to_address, subtract_fee=True
                 )
                 if (
                     w.status == TxStatus.PENDING
                 ):  # Check state to set and store updated values
                     self.log.info(
                         f"{self.to_currency} withdrawal request received, updating store values"
                     )
                     deposit["pending_withdrawal"] = False
                     self.store.set(self.from_currency + "_deposits", self.deposits)
                 else:
                     self.log.warning("Withdrawal failed")
             else:
                 self.log.warning(
                     f"Available balance not enough for withdrawal amount {withdrawal_amount}"
                 )
Esempio n. 2
0
 def process_conversions(self):
     for deposit in self.deposits.values():
         # Calculate remaining amount to convert
         original_amount = Money.loads(deposit["amounts"]["original_amount"])
         converted_amount = Money.loads(deposit["amounts"]["converted_amount"])
         converted_value = Money.loads(deposit["amounts"]["converted_value"])
         remaining = original_amount - converted_amount
         if (
             self.side == Side.BUY
         ):  # Change remaining amount to base currency for order creation purposes
             remaining = (
                 self.buda.fetch_order_book().quote(self.side, remaining).base_amount
             )
         if (
             deposit["status"] == TxStatus.OK.value
             and remaining > self.buda.min_order_amount
         ):
             remaining = truncate_money(remaining)
             # Convert remaining amount using market order
             order = self.buda.place_market_order(self.side, remaining)
             # Wait for traded state to set updated values
             if order:
                 self.log.info(
                     f"{self.side} market order placed, waiting for traded state"
                 )
                 while order.status != OrderStatus.CLOSED:
                     order = self.buda.fetch_order(order.id)
                     maya.time.sleep(1)
                 self.log.info(f"{self.side} order traded, updating store values")
                 if self.side == Side.BUY:
                     converted_amount += order.cost
                     converted_value += order.filled - order.fee
                 if self.side == Side.SELL:
                     converted_amount += order.filled
                     converted_value += order.cost - order.fee
                 deposit["orders"].append(
                     order.id
                 )  # Save related orders for debugging
             # Save new values __str__
             deposit["amounts"]["converted_amount"] = repr(converted_amount)
             deposit["amounts"]["converted_value"] = repr(converted_value)
     # Store all deposits
     self.store.set(self.from_currency + "_deposits", self.deposits)
Esempio n. 3
0
 def _algorithm(self):
     # Update candle data and TA indicators
     self.log.info(
         f"Getting trades from {self.reference.name} {self.reference.market.code}"
     )
     from_time = maya.when("1 day ago").epoch
     trades = self.get_trades(from_time)
     # Create pandas DataFrame from trades and set date as index
     df = pd.DataFrame(trades)
     df.index = df.timestamp.apply(lambda x: pd.datetime.utcfromtimestamp(x))
     # Build 5min candles from trades DataFrame [open, high, close, low]
     df = df.rate.resample(self.candle_interval).ohlc()
     # Calculate Bollinger Bands and RSI from talib
     df["bb_lower"], df["bb_middle"], df["bb_upper"] = talib.BBANDS(
         df.close, timeperiod=self.bbands_periods
     )
     df["rsi"] = talib.RSI(df.close, timeperiod=self.rsi_periods)
     lower = self.truncate_price(df.bb_lower[-1])
     middle = self.truncate_price(df.bb_middle[-1])
     upper = self.truncate_price(df.bb_upper[-1])
     self.log.info(f"BB_lower: {lower} | BB_middle: {middle} | BB_upper: {upper}")
     self.log.info(f"RSI: {df.rsi[-1]:.2f}")
     # Check if our position is open or closed
     if self.position["status"] == "closed":
         # Try conditions to open position
         self.log.info(f"Position is closed, checking to open")
         if df.close[-1] < df.bb_lower[-1] and df.rsi[-1] < self.rsi_oversold:
             # Last price is lower than the lower BBand and RSI is oversold, BUY!
             self.log.info(f"Market oversold! BUY!")
             amount = self.get_amount(Side.BUY)
             if amount >= self.buda.min_order_amount:
                 tx = self.buda.place_market_order(Side.BUY, amount)
                 self.position = {
                     "status": "open",
                     "side": Side.BUY.value,
                     "amount": repr(tx.amount),
                 }
             else:
                 self.log.warning(
                     f"Available amount is lower than minimum order amount"
                 )
         elif df.close[-1] > df.bb_upper[-1] and df.rsi[-1] > self.rsi_overbought:
             # Last price is higher than the upper BBand and RSI is overbought, SELL!
             self.log.info(f"Market overbought! SELL!")
             amount = self.get_amount(Side.SELL)
             if amount >= self.buda.min_order_amount:
                 tx = self.buda.place_market_order(Side.SELL, amount)
                 self.position = {
                     "status": "open",
                     "side": Side.SELL.value,
                     "amount": repr(tx.amount),
                 }
             else:
                 self.log.warning(
                     f"Available amount is lower than minimum order amount"
                 )
         else:
             self.log.info(f"Market conditions unmet to open position")
     else:
         self.log.info(f"Position is open, checking to close")
         if self.position["side"] == Side.BUY.value and df.rsi[-1] >= 30:
             # RSI is back to normal, close Buy position
             self.log.info(f"Market is back to normal, closing position")
             amount = Money.loads(self.position["amount"])
             if amount >= self.buda.min_order_amount:
                 tx = self.buda.place_market_order(Side.SELL, amount)
                 remaining = amount - tx.amount
                 if remaining < self.buda.min_order_amount:
                     self.position = {"status": "closed"}
                 else:
                     self.position["amount"] = remaining
             else:
                 self.log.warning(
                     f"Available amount is lower than minimum order amount"
                 )
         elif self.position["side"] == Side.SELL.value and df.rsi[-1] <= 70:
             # RSI is back to normal, close Sell position
             self.log.info(f"Market is back to normal, closing position")
             amount = Money.loads(self.position["amount"])
             if amount >= self.buda.min_order_amount:
                 tx = self.buda.place_market_order(Side.BUY, amount)
                 remaining = amount - tx.amount
                 if remaining < self.buda.min_order_amount:
                     self.position = {"status": "closed"}
                 else:
                     self.position["amount"] = repr(remaining)
             else:
                 self.log.warning(
                     f"Available amount is lower than minimum order amount"
                 )
         else:
             self.log.info(f"Market conditions unmet to close position")
     self.store.set("position", self.position)