Skip to content

Commit

Permalink
Update default_strategy.py
Browse files Browse the repository at this point in the history
  • Loading branch information
bassdeth1 authored Apr 17, 2024
1 parent caca9ad commit 6a1c379
Showing 1 changed file with 30 additions and 27 deletions.
57 changes: 30 additions & 27 deletions binance_trade_bot/strategies/default_strategy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import random
import sys
from datetime import datetime
import concurrent.futures

from binance_trade_bot.auto_trader import AutoTrader

Expand All @@ -14,33 +15,34 @@ def scout(self):
"""
Scout for potential jumps from the current coin to another coin
"""
current_coin = self.db.get_current_coin()
# Display on the console, the current coin+Bridge, so users can see *some* activity and not think the bot has
# stopped. Not logging though to reduce log size.
print(
f"{datetime.now()} - CONSOLE - INFO - I am scouting the best trades. "
f"Current coin: {current_coin + self.config.BRIDGE} ",
end="\r",
)
with concurrent.futures.ThreadPoolExecutor() as executor:
current_coin = self.db.get_current_coin()
print(
f"{datetime.now()} - CONSOLA - INFO - Estoy buscando los mejores intercambios. "
f"Moneda actual: {current_coin + self.config.BRIDGE} ",
end="\r",
)

future_price = executor.submit(self.manager.get_ticker_price, current_coin + self.config.BRIDGE)
current_coin_price = future_price.result()

if current_coin_price is None:
self.logger.info(f"Skipping scouting... current coin {current_coin + self.config.BRIDGE} not found")
return

current_coin_price = self.manager.get_ticker_price(current_coin + self.config.BRIDGE)

if current_coin_price is None:
self.logger.info(f"Skipping scouting... current coin {current_coin + self.config.BRIDGE} not found")
return

self._jump_to_best_coin(current_coin, current_coin_price)
self._jump_to_best_coin(current_coin, current_coin_price)

def bridge_scout(self):
current_coin = self.db.get_current_coin()
if self.manager.get_currency_balance(current_coin.symbol) > self.manager.get_min_notional(
current_coin.symbol, self.config.BRIDGE.symbol
):
# Only scout if we don't have enough of the current coin
return
new_coin = super().bridge_scout()
if new_coin is not None:
self.db.set_current_coin(new_coin)
with concurrent.futures.ThreadPoolExecutor() as executor:
current_coin = self.db.get_current_coin()
if self.manager.get_currency_balance(current_coin.symbol) > self.manager.get_min_notional(
current_coin.symbol, self.config.BRIDGE.symbol
):
return
new_coin = super().bridge_scout()
if new_coin is not None:
future_set_coin = executor.submit(self.db.set_current_coin, new_coin)
future_set_coin.result() # Wait for the operation to complete.

def initialize_current_coin(self):
"""
Expand All @@ -51,13 +53,14 @@ def initialize_current_coin(self):
if not current_coin_symbol:
current_coin_symbol = random.choice(self.config.SUPPORTED_COIN_LIST)

self.logger.info(f"Setting initial coin to {current_coin_symbol}")
self.logger.info(f"Estableciendo moneda inicial en {current_coin_symbol}")

if current_coin_symbol not in self.config.SUPPORTED_COIN_LIST:
sys.exit("***\nERROR!\nSince there is no backup file, a proper coin name must be provided at init\n***")
self.db.set_current_coin(current_coin_symbol)
with concurrent.futures.ThreadPoolExecutor() as executor:
future_set_initial_coin = executor.submit(self.db.set_current_coin, current_coin_symbol)
future_set_initial_coin.result() # Wait for the operation to complete.

# if we don't have a configuration, we selected a coin at random... Buy it so we can start trading.
if self.config.CURRENT_COIN_SYMBOL == "":
current_coin = self.db.get_current_coin()
self.logger.info(f"Purchasing {current_coin} to begin trading")
Expand Down

1 comment on commit 6a1c379

@bassdeth1
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent Use of ThreadPoolExecutor: Each function, scout and bridge_scout, now utilizes its own instance of ThreadPoolExecutor. This allows each function to manage its tasks in isolation, avoiding interference between each other's operations.

Asynchronous Price Handling in scout: In the scout function, the process of fetching the current coin price is handled asynchronously. We use executor.submit to launch the task of getting the price, and then future.result() to wait for the outcome. This allows the method to continue executing other codes while waiting, optimizing response time.

Improved Flow Control: Both functions use executor.submit for tasks that might require waiting, such as database operations and API calls to fetch prices. This is particularly useful in real-time trading environments, where speed and efficiency in task execution can directly impact trading performance.

Code Improvements:

Operation Isolation: By running scout and bridge_scout independently, the risks of deadlocks and errors from race conditions between these two functions are minimized.
Performance Optimization: Asynchronous handling of heavy tasks allows the system to respond more quickly to market changes. This is crucial in automated trading, where opportunities can vanish in seconds.
Resource Management Efficiency: By using multiple executors, the code can more efficiently manage resources, allocating threads only when and where needed, potentially reducing system resource usage.

Please sign in to comment.