Skip to content

Commit

Permalink
Merge pull request #1317 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
GuillaumeDSM authored Aug 4, 2024
2 parents 4131ffd + f0f22ee commit 0bc6b2b
Show file tree
Hide file tree
Showing 26 changed files with 266 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
{% if IS_DEMO or IS_CLOUD or IS_ALLOWING_TRACKING%}
<script>
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('{{PH_TRACKING_ID}}',{api_host:'https://eu.i.posthog.com',
posthog.init('{{PH_TRACKING_ID}}',{api_host:'https://eu.i.posthog.com', person_profiles: 'always'
})
</script>
{% endif %}
Expand Down
3 changes: 3 additions & 0 deletions Services/Interfaces/web_interface/controllers/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ def home():
sandbox_exchanges=sandbox_exchanges,
display_ph_launch=display_ph_launch,
is_launching=is_launching,
latest_release_url=f"{octobot_commons.constants.GITHUB_BASE_URL}/"
f"{octobot_commons.constants.GITHUB_ORGANISATION}/"
f"{constants.PROJECT_NAME}/releases/latest",
)
else:
return flask.redirect(flask.url_for("terms"))
5 changes: 4 additions & 1 deletion Services/Interfaces/web_interface/models/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ def format_trades(dict_trade_history):
float(dict_trade[trading_enums.ExchangeConstantsOrderColumns.PRICE.value]))
trades[trade_description_key].append(
f"{trade_type.name.replace('_', ' ')}: "
f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value]}")
f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value]} "
f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.QUANTITY_CURRENCY.value]} "
f"at {dict_trade[trading_enums.ExchangeConstantsOrderColumns.PRICE.value]} "
f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.MARKET.value]}")
trades[trade_order_side_key].append(trade_side.value)

return trades
Expand Down
3 changes: 2 additions & 1 deletion Services/Interfaces/web_interface/models/trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ def get_exchanges_load():
"load": trading_api.get_currently_handled_pair_with_time_frame(exchange_manager),
"max_load": trading_api.get_max_handled_pair_with_time_frame(exchange_manager),
"overloaded": trading_api.is_overloaded(exchange_manager),
"has_websocket": trading_api.get_has_websocket(exchange_manager)
"has_websocket": trading_api.get_has_websocket(exchange_manager),
"has_reached_websocket_limit": trading_api.get_has_reached_websocket_limit(exchange_manager)
}
for exchange_manager in interfaces_util.get_exchange_managers()
}
Expand Down
36 changes: 29 additions & 7 deletions Services/Interfaces/web_interface/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
:root {
--mdb-body-font-family: DM Sans, sans-serif;
--local-secondary-bg-text-color: #0f1237; /* same as dark mdb-primary */
--local-price-chart-sell-color: #F65A33;
--local-price-chart-stop-color: #FFA500;
}

:root[data-mdb-theme=light] {
Expand Down Expand Up @@ -72,14 +74,22 @@
--mdb-card-long-border-color: var(--mdb-secondary);
--mdb-card-short-border-color: var(--mdb-orange);
--mdb-card-very-short-border-color: var(--mdb-red);
--mdb-card-bg: var(--mdb-bg);
--mdb-card-color: var(--mdb-primary);
--mdb-surface-bg: var(--mdb-bg);

/* navbar */
--mdb-navbar-bg: var(--mdb-bg);
--mdb-navbar-brand-color: var(--mdb-primary);

--mdb-card-bg: var(--mdb-bg);
--mdb-card-color: var(--mdb-primary);
--mdb-surface-bg: var(--mdb-bg);
/* local */
/* config cards */
--local-config-card--border-width: 0px;

/* price charts */
--local-price-chart-buy-color: #6cb596;
--local-price-chart-candle-sell-color: var(--local-price-chart-sell-color);
--local-price-chart-candle-buy-color: #6cb596;
}

:root[data-mdb-theme=dark] {
Expand Down Expand Up @@ -130,14 +140,22 @@
--mdb-card-long-border-color: var(--mdb-secondary);
--mdb-card-short-border-color: var(--mdb-orange);
--mdb-card-very-short-border-color: var(--mdb-red);
--mdb-card-bg: var(--mdb-secondary);
--mdb-card-color: var(--mdb-primary);
--mdb-surface-bg: var(--mdb-bg-500);

/* navbar */
--mdb-navbar-bg: var(--mdb-bg);
--mdb-navbar-brand-color: var(--mdb-primary);

--mdb-card-bg: var(--mdb-secondary);
--mdb-card-color: var(--mdb-primary);
--mdb-surface-bg: var(--mdb-bg-500);
/* local */
/* config cards */
--local-config-card--border-width: 1px;

/* price charts */
--local-price-chart-buy-color: #6cb596;
--local-price-chart-candle-sell-color: var(--local-price-chart-sell-color);
--local-price-chart-candle-buy-color: #65e7cf;
}

/* Fix incompatibility with bootstrap 4 */
Expand Down Expand Up @@ -459,6 +477,10 @@ footer.page-footer {
flex-basis: inherit !important;
}

.config-card {
border: var(--local-config-card--border-width) solid rgba(var(--mdb-primary-rgb), 0.3);
}

.community-bot-stats-label {
font-weight: bold;
font-size: x-large;
Expand Down Expand Up @@ -563,7 +585,7 @@ footer.page-footer {
/* Theme */
/* Elegant */
.card-body.candle-graph {
min-height: 30.625rem;
height: 30.625rem;
background-color: inherit;
}

Expand Down
23 changes: 13 additions & 10 deletions Services/Interfaces/web_interface/static/js/common/candlesticks.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ function get_watched_symbol_price_graph(element, callback=undefined, no_data_cal
});
}

const stop_color = "#FFA500";
const sell_color = "#F65A33";
const buy_color = isDarkTheme() ? '#299a39' : "#009900";
const stop_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-stop-color');
const sell_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-sell-color');
const buy_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-buy-color');
const candle_sell_color = getComputedStyle(document.body).getPropertyValue('----local-price-chart-candle-sell-color');
const candle_buy_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-candle-buy-color');

function create_candlesticks(candles){
const data_time = candles["time"];
Expand All @@ -132,9 +134,9 @@ function create_candlesticks(candles){
return {
x: data_time,
close: data_close,
decreasing: {line: {color: sell_color}},
decreasing: {line: {color: candle_sell_color}},
high: data_high,
increasing: {line: {color: buy_color}},
increasing: {line: {color: candle_buy_color}},
line: {color: 'rgba(31,119,180,1)'},
low: data_low,
open: data_open,
Expand Down Expand Up @@ -187,22 +189,23 @@ function create_trades(trades, trader){
const data_trade_description = trades["trade_description"];
const data_order_side = trades["order_side"];

const marker_size = trader === "Simulator" ? 14 : 16;
const marker_opacity = trader === "Simulator" ? 0.5 : 0.65;
const border_line_color = "#b6b8c3";
const marker_size = 16;
const marker_opacity = 0.9;
const border_line_color = getTextColor();
const colors = [];
$.each(data_order_side, function (index, value) {
colors.push(_getOrderColor(trades["trade_description"][index], value));
});

const line_with = trader === "Simulator" ? 0 : 1;
const line_with = isDarkTheme() ? 1 : 0.2;

return {
x: data_time,
y: data_price,
mode: 'markers',
name: trader,
name: "",
text: data_trade_description,
hovertemplate: `%{text}<br>%{x}`,
marker: {
color: colors,
size: marker_size,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function register_exchanges_checks(check_existing_accounts){

const check_account = (exchangeCard, source, newValue) => {
const exchange = exchangeCard.find(".card-body").attr("name");
if(exchange !== config_default_value){
if(exchange !== config_default_value && exchangeCard.find("#exchange_api-key").length > 0){
const apiKey = source.attr("id") === "exchange_api-key" ? newValue : exchangeCard.find("#exchange_api-key").editable('getValue', true).trim();
const apiSecret = source.attr("id") === "exchange_api-secret" ? newValue : exchangeCard.find("#exchange_api-secret").editable('getValue', true).trim();
const apiPassword = source.attr("id") === "exchange_api-password" ? newValue : exchangeCard.find("#exchange_api-password").editable('getValue', true).trim();
Expand Down
27 changes: 19 additions & 8 deletions Services/Interfaces/web_interface/static/js/common/tracking.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
$(document).ready(function() {

const getUserEmail = () => {
return getUserDetails().email
return getUserDetails().email || "";
}

const getUserDetails = () => {
if (_USER_DETAILS.email === ""){
// do not erase email if unset
delete _USER_DETAILS.email;
}
return _USER_DETAILS
}

const updateUserDetails = () => {
posthog.capture(
getUserEmail(),
event='update_user_details',
'up_user_details',
properties={
'$set': getUserDetails(),
}
Expand All @@ -21,11 +24,19 @@ $(document).ready(function() {

const shouldUpdateUserDetails = () => {
const currentProperties = posthog.get_property('$stored_person_properties');
return (
getUserEmail() !== ""
&& isDefined(currentProperties)
&& JSON.stringify(currentProperties) !== JSON.stringify(getUserDetails())
)
if(currentProperties === undefined){
return true;
}
if(isDefined(currentProperties)){
const currentDetails = getUserDetails();
if(currentDetails.email === undefined){
// compare without email (otherwise result is always different as no email is currently set)
const localProperties = JSON.parse(JSON.stringify(currentProperties));
delete localProperties.email
return JSON.stringify(localProperties) !== JSON.stringify(getUserDetails());
}
}
return JSON.stringify(currentProperties) !== JSON.stringify(getUserDetails());
}

const shouldReset = (newEmail) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<!--Card image-->
<div class="view overlay animated fadeIn">
<img class="card-img-top currency-image {{additional_classes}}"
<img class="card-img-top currency-image p-2 {{additional_classes}}"
src="{{ url_for('static', filename='img/svg/loading_currency.svg') }}"
alt="{{ crypto_currency }}"
data-currency-id="{{get_currency_id(full_symbol_list, crypto_currency)}}"
Expand All @@ -18,7 +18,7 @@
<!--Card content-->
<div class="card-body" name="{{crypto_currency}}" config-key="crypto-currencies_{{crypto_currency}}">

<p class="card-text symbols {{additional_classes}}">
<p class="card-text symbols my-0 {{additional_classes}}">
{{ m_editable_config.editable_key( config_symbols,
crypto_currency,
"crypto-currencies_" + crypto_currency,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<!-- Card -->
<div data-role="exchange" class="card mb-4 {{add_class}} config-card">

<div class="card-header row">
<div class="card-header d-flex">
<div class="col-7 col-lg-5">
<h4 class="text-capitalize">
{{exchange}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<!-- Card -->
<div class="card mb-4 {{add_class}} config-card">

<div class="card-header row">
<div class="card-header d-flex">
<div class="d-flex justify-content-between w-100 px-3">
<div>
<h4 class="text-capitalize">
Expand Down
9 changes: 8 additions & 1 deletion Services/Interfaces/web_interface/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ <h5 class="">
{% endif %}
{% if not IS_CLOUD %}
<div class="d-none alert alert-success text-center my-2" role="alert">
<h5 class="d-none d-sm-inline"><span class="d-none d-md-inline"><i class="far fa-bell"></i> Good news ! </span>OctoBot version <span update-url="{{ url_for('api.upgrade_version') }}" id="upgradeVersion"></span> is available.</h5><button route="{{ url_for('commands', cmd='update') }}" type="button" class="btn btn-warning waves-effect">Upgrade now <i class="fas fa-cloud-download-alt"></i></button>
<h5 class="d-none d-sm-inline">
<span class="d-none d-md-inline"><i class="far fa-bell"></i> Good news ! </span>
OctoBot version <span update-url="{{ url_for('api.upgrade_version') }}" id="upgradeVersion"></span>
is available.
</h5>
<button route="{{ url_for('commands', cmd='update') }}" type="button" class="btn btn-outline-primary waves-effect">
Upgrade now <i class="fas fa-cloud-download-alt"></i>
</button>
</div>
{% endif %}
<span id="exchange-specific-data">
Expand Down
2 changes: 1 addition & 1 deletion Services/Interfaces/web_interface/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
{% if IS_DEMO or IS_CLOUD or IS_ALLOWING_TRACKING%}
<script>
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('{{PH_TRACKING_ID}}',{api_host:'https://eu.i.posthog.com',
posthog.init('{{PH_TRACKING_ID}}',{api_host:'https://eu.i.posthog.com', person_profiles: 'always'
})
</script>
{% endif %}
Expand Down
8 changes: 7 additions & 1 deletion Services/Interfaces/web_interface/templates/trading.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
{% set vars = {'exchange_overload': False} %}

{% macro exchange_overload_warning(exchange, load) -%}
{% if load["overloaded"] %}
{% if load["has_reached_websocket_limit"] %}
<div class="alert alert-info font-weight-normal offset-md-3 offset-lg-2 offset-1" role="alert">
<span class="text-capitalize">{{ exchange }}</span> exchange websocket can't handle the required
{{load["load"]}} simultaneous feed. Exchange maximum is {{load["max_load"]}}. Falling back to the
slower "REST" connection.
</div>
{% elif load["overloaded"] %}
<div class="alert alert-danger font-weight-normal offset-md-3 offset-lg-2 offset-1" role="alert">
<span class="text-capitalize">{{ exchange }}</span> exchange is overloaded by
<span class="font-weight-bold">{{ (load["load"] * 100 / load["max_load"] - 100) | round | int }}%</span>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h5><i class="fa fa-coins"></i> <span class="d-none d-md-inline">Trade using</sp
<div class="text-left">
<div data-role="exchange" class="card mb-4 config-card">

<div class="card-header row" id="simulated-config-header">
<div class="card-header d-flex" id="simulated-config-header">
<div class="col-7 col-lg-5">
<h4 class="text-capitalize">
{{enabled_exchanges[0]}}
Expand Down
4 changes: 4 additions & 0 deletions Trading/Exchange/kucoin_websocket_feed/kucoin_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class KucoinCCXTWebsocketConnector(exchanges.CCXTWebsocketConnector):
Feeds.TICKER: [Feeds.KLINE]
}

# Feeds to create above which not to use websockets
# Kucoin raises "exceed max permits per second" when subscribing to more than 100 feeds
MAX_HANDLED_FEEDS = 100

RECREATE_CLIENT_ON_DISCONNECT = True # when True, a new ccxt websocket client will replace the previous
# one when the exchange is disconnected

Expand Down
5 changes: 5 additions & 0 deletions Trading/Mode/dca_trading_mode/dca_trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,11 @@ def get_current_state(self) -> (str, float):
async def single_exchange_process_optimize_initial_portfolio(
self, sellable_assets, target_asset: str, tickers: dict
) -> list:
traded_coins = [
symbol.base
for symbol in self.exchange_manager.exchange_config.traded_symbols
]
sellable_assets = sorted(list(set(sellable_assets + traded_coins)))
self.logger.info(f"Optimizing portfolio: selling {sellable_assets} to buy {target_asset}")
return await trading_modes.convert_assets_to_target_asset(
self, sellable_assets, target_asset, tickers
Expand Down
11 changes: 11 additions & 0 deletions Trading/Mode/dca_trading_mode/tests/test_dca_trading_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,17 @@ async def test_single_exchange_process_optimize_initial_portfolio(tools):
orders = await mode.single_exchange_process_optimize_initial_portfolio(["BTC", "ETH"], "USDT", {})
convert_assets_to_target_asset_mock.assert_called_once_with(mode, ["BTC", "ETH"], "USDT", {})
assert orders == ["order_1"]
convert_assets_to_target_asset_mock.reset_mock()

mode.exchange_manager.exchange_config.traded_symbols = [
commons_symbols.parse_symbol("SOL/USDT"),
commons_symbols.parse_symbol("BCC/ATOM"),
]
orders = await mode.single_exchange_process_optimize_initial_portfolio(["BTC", "ETH"], "USDT", {})
convert_assets_to_target_asset_mock.assert_called_once_with(
mode, ["BCC", "BTC", "ETH", "SOL"], "USDT", {}
)
assert orders == ["order_1"]


async def test_single_exchange_process_health_check(tools):
Expand Down
2 changes: 1 addition & 1 deletion Trading/Mode/grid_trading_mode/grid_trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def init_user_inputs(self, inputs: dict) -> None:
default_config[self.CONFIG_PAIR], inputs,
other_schema_values={"minLength": 3, "pattern": "([a-zA-Z]|\\d){2,}\\/([a-zA-Z]|\\d){2,}"},
parent_input_name=self.CONFIG_PAIR_SETTINGS,
title="Name of the traded pair."),
title="Name of the traded pair.")
self.UI.user_input(
self.CONFIG_FLAT_SPREAD, commons_enums.UserInputTypes.FLOAT,
default_config[self.CONFIG_FLAT_SPREAD], inputs,
Expand Down
Loading

0 comments on commit 0bc6b2b

Please sign in to comment.