Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulator #2470

Merged
merged 5 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions octobot/community/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ class CommunityAuthentication(authentication.Authenticator):
SESSION_HEADER = "X-Session"
GQL_AUTHORIZATION_HEADER = "Authorization"

def __init__(self, feed_url, config=None, backend_url=None, backend_key=None):
super().__init__()
def __init__(self, feed_url, config=None, backend_url=None, backend_key=None, use_as_singleton=True):
super().__init__(use_as_singleton=use_as_singleton)
self.feed_url = feed_url
self.backend_url = backend_url or identifiers_provider.IdentifiersProvider.BACKEND_URL
self.backend_key = backend_key or identifiers_provider.IdentifiersProvider.BACKEND_KEY
Expand Down Expand Up @@ -364,6 +364,12 @@ async def refresh_selected_bot(self):
await self.supabase_client.fetch_bot(self.user_account.bot_id)
)

async def refresh_selected_bot_if_unset(self):
if not self.user_account.has_selected_bot_data():
self.user_account.set_selected_bot_raw_data(
await self.supabase_client.fetch_bot(self.user_account.bot_id)
Copy link
Member

Choose a reason for hiding this comment

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

Should we also check that self.user_account.bot_id is not None ?

Copy link
Member Author

Choose a reason for hiding this comment

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

it's initialized in constructor, it should never be None, we are fine :)

Copy link
Member

Choose a reason for hiding this comment

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

Great!

)

def _get_self_hosted_bots(self, bots):
return [
bot
Expand Down
7 changes: 4 additions & 3 deletions octobot/community/models/community_user_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ def is_self_hosted(self, bot):
) == backend_enums.DeploymentTypes.SELF_HOSTED.value

def get_selected_bot_deployment_id(self):
return self._get_bot_deployment(self._selected_bot_raw_data)[
backend_enums.BotDeploymentKeys.ID.value
]
return self.get_bot_deployment_value(backend_enums.BotDeploymentKeys.ID)

def get_bot_deployment_status(self) -> (str, str):
deployment = self._get_bot_deployment(self._selected_bot_raw_data)
Expand All @@ -86,6 +84,9 @@ def get_bot_deployment_status(self) -> (str, str):
deployment[backend_enums.BotDeploymentKeys.DESIRED_STATUS.value]
)

def get_bot_deployment_value(self, key: backend_enums.BotDeploymentKeys):
return self._get_bot_deployment(self._selected_bot_raw_data)[key.value]

def get_bot_deployment_url(self, deployment_url_data):
return deployment_url_data[backend_enums.BotDeploymentURLKeys.URL.value]

Expand Down
15 changes: 15 additions & 0 deletions octobot/community/models/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ def format_orders(orders: list, exchange_name: str) -> list:
),
backend_enums.OrderKeys.QUANTITY.value: storage_order[trading_constants.STORAGE_ORIGIN_VALUE][
trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value],
backend_enums.OrderKeys.EXCHANGE_ID.value: storage_order[trading_constants.STORAGE_ORIGIN_VALUE][
trading_enums.ExchangeConstantsOrderColumns.EXCHANGE_ID.value],
backend_enums.OrderKeys.CHAINED.value: format_orders(
storage_order.get(trading_enums.StoredOrdersAttr.CHAINED_ORDERS.value, []), exchange_name
) if storage_order.get(trading_enums.StoredOrdersAttr.CHAINED_ORDERS.value, []) else []
}
for storage_order in orders
if storage_order.get(trading_constants.STORAGE_ORIGIN_VALUE, {}).get(
Expand Down Expand Up @@ -133,3 +138,13 @@ def format_portfolio_history(history: dict, unit: str, portfolio_id: str) -> lis
]
except KeyError:
return []


def get_adapted_portfolio(usd_like_asset, portfolio):
Copy link
Member

Choose a reason for hiding this comment

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

👍

formatted = {}
for asset in portfolio:
currency = asset[backend_enums.PortfolioAssetKeys.ASSET.value]
if currency == "USD-like":
currency = usd_like_asset
formatted[currency] = asset[backend_enums.PortfolioAssetKeys.VALUE.value]
return formatted
36 changes: 32 additions & 4 deletions octobot/community/supabase_backend/community_supabase_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
import octobot_commons.profiles as commons_profiles
import octobot_commons.enums as commons_enums
import octobot_commons.constants as commons_constants
import octobot_trading.api as trading_api
import octobot.constants as constants
import octobot.community.errors as errors
import octobot.community.models.formatters as formatters
import octobot.community.supabase_backend.enums as enums
import octobot.community.supabase_backend.supabase_client as supabase_client
import octobot.community.supabase_backend.configuration_storage as configuration_storage
Expand Down Expand Up @@ -247,6 +249,7 @@ async def fetch_bot_profile_data(self, bot_config_id: str) -> commons_profiles.P
"bot_id, "
"options, "
"exchanges, "
"is_simulated, "
"product_config:product_configs("
" config, "
" version, "
Expand All @@ -263,10 +266,30 @@ async def fetch_bot_profile_data(self, bot_config_id: str) -> commons_profiles.P
].get("minimal_funds", [])
] if bot_config[enums.BotConfigKeys.EXCHANGES.value] else []
profile_data.profile_details.version = bot_config["product_config"][enums.ProfileConfigKeys.VERSION.value]
profile_data.trader_simulator.enabled = bot_config.get("is_simulated", False)
if profile_data.trader_simulator.enabled:
portfolio = (bot_config.get(
enums.BotConfigKeys.OPTIONS.value
) or {}).get("portfolio")
if trading_api.is_usd_like_coin(profile_data.trading.reference_market):
usd_like_asset = profile_data.trading.reference_market
Comment on lines +274 to +275
Copy link
Member

Choose a reason for hiding this comment

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

👍

else:
usd_like_asset = "USDT" # todo use dynamic value when exchange is not supporting USDT
profile_data.trader_simulator.starting_portfolio = formatters.get_adapted_portfolio(
usd_like_asset, portfolio
)
exchanges_config = (
# use product config exchanges when no exchange is set in bot_config and when in simulator mode
bot_config["product_config"][enums.ProfileConfigKeys.CONFIG.value]["exchanges"]
if profile_data.trader_simulator.enabled
# otherwise use botconfig exchange id
else bot_config[enums.BotConfigKeys.EXCHANGES.value] if bot_config[enums.BotConfigKeys.EXCHANGES.value]
else []
)
profile_data.exchanges = [
commons_profiles.ExchangeData.from_dict(exchange_data)
for exchange_data in bot_config[enums.BotConfigKeys.EXCHANGES.value]
] if bot_config[enums.BotConfigKeys.EXCHANGES.value] else []
for exchange_data in exchanges_config
]
if options := bot_config.get(enums.BotConfigKeys.OPTIONS.value):
profile_data.options = commons_profiles.OptionsData.from_dict(options)
profile_data.profile_details.id = bot_config_id
Expand All @@ -287,17 +310,22 @@ async def fetch_product_config(self, product_id: str) -> commons_profiles.Profil
profile_data.profile_details.version = product["product_config"][enums.ProfileConfigKeys.VERSION.value]
return profile_data

async def fetch_configs(self, bot_id) -> list:
async def fetch_configs(self, bot_id: str) -> list:
# use a new current portfolio for the given bot
return (await self.table("bot_configs").select("*").eq(
enums.BotConfigKeys.BOT_ID.value, bot_id
).execute()).data

async def fetch_portfolios(self, bot_id) -> list:
async def fetch_portfolios(self, bot_id: str) -> list:
return (await self.table("bot_portfolios").select("*").eq(
enums.PortfolioKeys.BOT_ID.value, bot_id
).execute()).data

async def fetch_portfolio_from_id(self, portfolio_id: str) -> list:
return (await self.table("bot_portfolios").select("*").eq(
enums.PortfolioKeys.ID.value, portfolio_id
).execute()).data

async def update_portfolio(self, portfolio) -> list:
# use a new current portfolio for the given bot
return (await self.table("bot_portfolios").update(portfolio).eq(
Expand Down
6 changes: 6 additions & 0 deletions octobot/community/supabase_backend/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class BotDeploymentKeys(enum.Enum):
METADATA = "metadata"
ERROR_STATUS = "error_status"
ACTIVITIES = "activities"
EXPIRATION_TIME = "expiration_time"


class BotDeploymentActivitiesKeys(enum.Enum):
Expand Down Expand Up @@ -91,6 +92,8 @@ class BotDeploymentErrorsStatuses(enum.Enum):
ALREADY_USED_EXCHANGE_ACCOUNT = "already_used_exchange_account"
MISSING_MINIMAL_FUNDS = "missing_minimal_funds"
MISSING_CONFIG = "missing_config"
EXPIRED_BOT = "expired_bot"
MAX_SIMULATORS_REACHED = "max_simulators_reached"


class ExchangeAccountStatuses(enum.Enum):
Expand Down Expand Up @@ -144,8 +147,10 @@ class OrderKeys(enum.Enum):
EXCHANGE = "exchange"
PRICE = "price"
QUANTITY = "quantity"
EXCHANGE_ID = "exchange_id"
SYMBOL = "symbol"
TYPE = "type"
CHAINED = "chained"


class PortfolioKeys(enum.Enum):
Expand Down Expand Up @@ -176,6 +181,7 @@ class BotConfigKeys(enum.Enum):
PRODUCT_CONFIG_ID = "product_config_id"
EXCHANGES = "exchanges"
OPTIONS = "options"
SIMULATED = "simulated"


class ProfileConfigKeys(enum.Enum):
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Drakkar-Software requirements
OctoBot-Commons==1.9.30
OctoBot-Trading==2.4.40
OctoBot-Commons==1.9.31
OctoBot-Trading==2.4.41
OctoBot-Evaluators==1.9.3
OctoBot-Tentacles-Manager==2.9.5
OctoBot-Services==1.6.5
Expand Down
Loading