Skip to content

Commit

Permalink
Merge pull request #790 from whittlem/beta
Browse files Browse the repository at this point in the history
Merging beta into main
  • Loading branch information
whittlem authored Apr 15, 2023
2 parents 5d0c771 + e89426f commit bff0c33
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 128 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Python Crypto Bot v8.0.4 (pycryptobot)
# Python Crypto Bot v8.0.5 (pycryptobot)

[![Docker](https://github.com/whittlem/pycryptobot/actions/workflows/container.yml/badge.svg)](https://github.com/whittlem/pycryptobot/actions/workflows/container.yml/badge.svg) [![Tests](https://github.com/whittlem/pycryptobot/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/whittlem/pycryptobot/actions/workflows/unit-tests.yml/badge.svg)

Expand Down
100 changes: 42 additions & 58 deletions controllers/PyCryptoBot.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ def execute_job(self):
if self.state.last_buy_price != exchange_last_buy["price"]:
self.state.last_buy_price = exchange_last_buy["price"]

if self.exchange == Exchange.COINBASEPRO or self.exchange == Exchange.KUCOIN:
if self.exchange == Exchange.COINBASE or self.exchange == Exchange.COINBASEPRO or self.exchange == Exchange.KUCOIN:
if self.state.last_buy_fee != exchange_last_buy["fee"]:
self.state.last_buy_fee = exchange_last_buy["fee"]

Expand Down Expand Up @@ -932,15 +932,19 @@ def _notify(notification: str = "", level: str = "normal") -> None:

# if live
if self.is_live:
ac = self.account.get_balance()
self.account.base_balance_before = 0.0
self.account.quote_balance_before = 0.0
self.insufficientfunds = False

try:
df_base = ac[ac["currency"] == self.base_currency]["available"]
self.account.base_balance_before = 0.0 if len(df_base) == 0 else float(df_base.values[0])
self.account.quote_balance_before = self.account.get_balance(self.quote_currency)
self.state.last_buy_size = float(self.account.quote_balance_before)

if self.buymaxsize and self.buylastsellsize and self.state.minimum_order_quote(quote=self.state.last_sell_size, balancechk=True):
self.state.last_buy_size = self.state.last_sell_size
elif self.buymaxsize and self.state.last_buy_size > self.buymaxsize:
self.state.last_buy_size = self.buymaxsize

df_quote = ac[ac["currency"] == self.quote_currency]["available"]
self.account.quote_balance_before = 0.0 if len(df_quote) == 0 else float(df_quote.values[0])
if self.account.quote_balance_before <= self.state.last_buy_size:
self.insufficientfunds = True
except Exception:
pass

Expand All @@ -949,34 +953,24 @@ def _notify(notification: str = "", level: str = "normal") -> None:
if not self.is_sim or (self.is_sim and not self.simresultonly):
_notify(f"*** Executing SIMULATION Buy Order at {str(self.price)} ***", "info")
else:
_notify("*** Executing LIVE Buy Order ***")
_notify("*** Executing LIVE Buy Order ***", "info")

# display balances
_notify(f"{self.base_currency} balance before order: {str(self.account.base_balance_before)}")
_notify(f"{self.quote_currency} balance before order: {str(self.account.quote_balance_before)}")

# execute a live market buy
self.state.last_buy_size = float(self.account.quote_balance_before)

if self.buymaxsize and self.buylastsellsize and self.state.minimum_order_quote(quote=self.state.last_sell_size, balancechk=True):
self.state.last_buy_size = self.state.last_sell_size
elif self.buymaxsize and self.state.last_buy_size > self.buymaxsize:
self.state.last_buy_size = self.buymaxsize
_notify(f"{self.base_currency} balance before order: {str(self.account.base_balance_before)}", "debug")
_notify(f"{self.quote_currency} balance before order: {str(self.account.quote_balance_before)}", "debug")

# place the buy order
resp_error = 0

try:
df_order = self.market_buy(
self.market_buy(
self.market,
self.state.last_buy_size,
self.get_buy_percent(),
)

if len(df_order) == 0:
resp_error = 1
else:
resp_error = 0
except Exception as err:
_notify(f"Trade Error: {err}", "warning")
_notify(f"Trade Error: {err}", "error")
resp_error = 1

if resp_error == 0:
Expand Down Expand Up @@ -1006,9 +1000,6 @@ def _notify(notification: str = "", level: str = "normal") -> None:
self.state.trailing_buy_immediate = False
self.telegram_bot.add_open_order()

_notify(f"{self.base_currency} balance after order: {str(self.account.base_balance_after)}")
_notify(f"{self.quote_currency} balance after order: {str(self.account.quote_balance_after)}")

if not self.disabletelegram:
self.notify_telegram(
self.market
Expand Down Expand Up @@ -1048,13 +1039,15 @@ def _notify(notification: str = "", level: str = "normal") -> None:

if not self.disabletelegramerrormsgs:
self.notify_telegram(f"API Error: Unable to place buy order for {self.market}")

time.sleep(30)

else:
_notify(
"Unable to place order, insufficient funds or buyminsize has not been reached. Check Logs.",
"warning",
)
if not self.is_live:
if not self.is_sim or (self.is_sim and not self.simresultonly):
_notify(f"*** Skipping SIMULATION Buy Order at {str(self.price)} -- Insufficient Funds ***", "warning")
else:
_notify("*** Skipping LIVE Buy Order -- Insufficient Funds ***", "warning")

self.state.last_api_call_datetime -= timedelta(seconds=60)

Expand Down Expand Up @@ -1163,7 +1156,11 @@ def _notify(notification: str = "", level: str = "normal") -> None:
elif self.state.action == "SELL":
# if live
if self.is_live:
_notify(f"{formatted_current_df_index} | {self.market} | {self.print_granularity()} | {str(self.price)} | SELL")
if not self.is_live:
if not self.is_sim or (self.is_sim and not self.simresultonly):
_notify(f"*** Executing SIMULATION Sell Order at {str(self.price)} ***", "info")
else:
_notify("*** Executing LIVE Sell Order ***", "info")

# check balances before and display
self.account.base_balance_before = 0
Expand All @@ -1174,22 +1171,24 @@ def _notify(notification: str = "", level: str = "normal") -> None:
except Exception:
pass

_notify(f"{self.base_currency} balance before order: {str(self.account.base_balance_before)}")
_notify(f"{self.quote_currency} balance before order: {str(self.account.quote_balance_before)}")
_notify(f"{self.base_currency} balance before order: {str(self.account.base_balance_before)}", "debug")
_notify(f"{self.quote_currency} balance before order: {str(self.account.quote_balance_before)}", "debug")

# execute a live market sell
baseamounttosell = float(self.account.base_balance_before) if self.sellfullbaseamount is True else float(self.state.last_buy_filled)

self.account.base_balance_after = 0
self.account.quote_balance_after = 0

# place the sell order
resp_error = 0

try:
self.market_sell(
self.market,
baseamounttosell,
self.get_sell_percent(),
)
resp_error = 0
except Exception as err:
_notify(f"Trade Error: {err}", "warning")
resp_error = 1
Expand Down Expand Up @@ -1462,7 +1461,7 @@ def _notify(notification: str = "", level: str = "normal") -> None:
# update order tracker csv
if self.exchange == Exchange.BINANCE:
self.account.save_tracker_csv(self.market)
elif self.exchange == Exchange.COINBASEPRO or self.exchange == Exchange.KUCOIN:
elif self.exchange == Exchange.COINBASE or self.exchange == Exchange.COINBASEPRO or self.exchange == Exchange.KUCOIN:
self.account.save_tracker_csv()

if self.is_sim:
Expand Down Expand Up @@ -1527,7 +1526,7 @@ def run(self):
if self.websocket and not self.is_sim:
RichText.notify("Opening websocket to Coinbase", self, "normal")
print("")
self.websocket_connection = CBWebSocketClient([self.market], self.granularity, app=self)
self.websocket_connection = CWebSocketClient([self.market], self.granularity, app=self)
self.websocket_connection.start()
elif self.exchange == Exchange.COINBASEPRO:
message += "Coinbase Pro bot"
Expand Down Expand Up @@ -1725,7 +1724,7 @@ def initialise(self, banner=True):

else:
end_date = self.get_date_from_iso8601_str(str(pd.Series(datetime.now()).dt.round(freq="H")[0]))
if self.exchange == Exchange.COINBASEPRO:
if self.exchange == Exchange.COINBASE or self.exchange == Exchange.COINBASEPRO:
end_date -= timedelta(hours=random.randint(0, 8760 * 3)) # 3 years in hours
else:
end_date -= timedelta(hours=random.randint(0, 8760 * 1))
Expand Down Expand Up @@ -3069,7 +3068,7 @@ def get_last_buy(self) -> dict:

try:
if self.exchange == Exchange.COINBASE:
api = CAuthAPI(self.api_key, self.api_secret, self.api_url, app=self)
api = CBAuthAPI(self.api_key, self.api_secret, self.api_url, app=self)
orders = api.get_orders(self.market, "", "done")

if len(orders) == 0:
Expand Down Expand Up @@ -3160,25 +3159,9 @@ def get_taker_fee(self):
return 0.005 # default lowest fee tier
elif not self.is_live and self.exchange == Exchange.BINANCE:
# https://www.binance.com/en/support/announcement/binance-launches-zero-fee-bitcoin-trading-10435147c55d4a40b64fcbf43cb46329
# UPDATE: https://www.binance.com/en/support/announcement/updates-on-zero-fee-bitcoin-trading-busd-zero-maker-fee-promotion-be13a645cca643d28eab5b9b34f2dc36
if self.get_market() in [
"BTCAUD",
"BTCBIDR",
"BTCBRL",
"BTCBUSD",
"BTCEUR",
"BTCGBP",
"BTCRUB",
"BTCTRY",
"BTCTUSD",
"BTCUAH",
"BTCUSDC",
"BTCUSDP",
"BTCUSDT",
"BUSDUSDT",
"PAXBUSD",
"SUSDUSDT",
"USTBUSD",
"USTUSDT",
"BTCTUSD"
]:
return 0.0 # no fees for those pairs
else:
Expand All @@ -3190,6 +3173,7 @@ def get_taker_fee(self):
elif self.exchange == Exchange.COINBASE:
api = CBAuthAPI(self.api_key, self.api_secret, self.api_url, app=self)
self.takerfee = api.get_taker_fee()
return self.takerfee
elif self.exchange == Exchange.COINBASEPRO:
api = CAuthAPI(self.api_key, self.api_secret, self.api_passphrase, self.api_url, app=self)
self.takerfee = api.get_taker_fee()
Expand Down
2 changes: 2 additions & 0 deletions examples/script-coinbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
# print(df)
# df = model1.get_product("ADA-GBP")
# print(df)
# df = model1.auth_api("GET", "api/v3/brokerage/products/ADA-GBP")
# print(float(df[["base_min_size"]].values[0]))


""" COINBASE"""
Expand Down
34 changes: 29 additions & 5 deletions models/AppState.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,28 @@ def minimum_order_base(self, base: float = 0.0, balancechk: bool = False):
if self.app.exchange == Exchange.BINANCE:
df = self.api.get_market_info_filters(self.app.market)
if len(df) > 0:
sys.tracebacklimit = 0
raise Exception(f"Market not found! ({self.app.market})")

base = float(base)
try:
base_min = float(
df[df["filterType"] == "LOT_SIZE"][["minQty"]].values[0][0]
)
base = float(base)
except Exception:
base_min = 0.0

elif self.app.exchange == Exchange.COINBASE:
product = self.api.auth_api("GET", f"api/v3/brokerage/products/{self.app.market}")
if len(product) == 0:
sys.tracebacklimit = 0
raise Exception(f"Market not found! ({self.app.market})")

base = float(base)
try:
base_min = float(product[["base_min_size"]].values[0])
except Exception:
base_min = 0.0

elif self.app.exchange == Exchange.COINBASEPRO:
product = self.api.auth_api("GET", f"products/{self.app.market}")
Expand All @@ -126,8 +144,10 @@ def minimum_order_base(self, base: float = 0.0, balancechk: bool = False):
raise Exception(f"Market not found! ({self.app.market})")

base = float(base)
# base_min = float(product["base_min_size"])
base_min = float(0)
try:
base_min = float(product[["base_min_size"]].values[0])
except Exception:
base_min = 0.0

elif self.app.exchange == Exchange.KUCOIN:
resp = self.api.auth_api("GET", "api/v1/symbols")
Expand All @@ -137,7 +157,10 @@ def minimum_order_base(self, base: float = 0.0, balancechk: bool = False):
raise Exception(f"Market not found! ({self.app.market})")

base = float(base)
base_min = float(product["baseMinSize"])
try:
base_min = float(product["baseMinSize"])
except Exception:
base_min = 0.0

# additional check for last order type
if balancechk:
Expand Down Expand Up @@ -280,7 +303,8 @@ def get_last_order(self):

# binance orders do not show fees
if (
self.app.exchange == Exchange.COINBASEPRO
self.app.exchange == Exchange.COINBASE
or self.app.exchange == Exchange.COINBASEPRO
or self.app.exchange == Exchange.KUCOIN
):
self.last_buy_fee = float(
Expand Down
4 changes: 2 additions & 2 deletions models/Stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_data(self, market):
time = row["created_at"].to_pydatetime()

if row["action"] == "buy":
if self.app.exchange == Exchange.COINBASEPRO:
if self.app.exchange == Exchange.COINBASE or self.app.exchange == Exchange.COINBASEPRO:
amount = row["filled"] * row["price"] + row["fees"]
else:
amount = row["size"]
Expand All @@ -47,7 +47,7 @@ def get_data(self, market):
else:
self.order_pairs[-1]["buy"]["size"] += float(amount)
else:
if self.app.exchange == Exchange.COINBASEPRO:
if self.app.exchange == Exchange.COINBASE or self.app.exchange == Exchange.COINBASEPRO:
amount = (row["filled"] * row["price"]) - row["fees"]
else:
amount = (float(row["filled"]) * float(row["price"])) - row["fees"]
Expand Down
Loading

0 comments on commit bff0c33

Please sign in to comment.