Skip to content

Commit

Permalink
Merge pull request #1301 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
Dev merge
  • Loading branch information
GuillaumeDSM authored Jul 14, 2024
2 parents cc1a26d + ffd538b commit 9acafa5
Show file tree
Hide file tree
Showing 16 changed files with 57 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ def config_tentacle():
tentacle_name = flask.request.args.get("name")
action = flask.request.args.get("action")
profile_id = flask.request.args.get("profile_id")
restart = flask.request.args.get("restart", "false") == "true"
tentacles_setup_config = models.get_tentacles_setup_config_from_profile_id(profile_id) if profile_id else None
success = True
response = ""
Expand Down Expand Up @@ -311,6 +312,8 @@ def config_tentacle():
success = False
response = f"Error when reloading configuration {e}"
if success:
if restart:
models.schedule_delayed_command(models.restart_bot)
return util.get_rest_reply(flask.jsonify(response))
else:
return util.get_rest_reply(response, 500)
Expand Down
4 changes: 4 additions & 0 deletions Services/Interfaces/web_interface/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ a:hover {
--mdb-table-striped-color: var(--mdb-primary);
}

.table td, .table th {
border-top: none;
}

/* toast */
#toast-container>.toast-warning {
background-image: none !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ function get_watched_symbol_price_graph(element, callback=undefined, no_data_cal
});
}

const sell_color = "#ff0000";
const buy_color = "#009900";
const stop_color = "#FFA500";
const sell_color = "#F65A33";
const buy_color = isDarkTheme() ? '#299a39' : "#009900";

function create_candlesticks(candles){
const data_time = candles["time"];
Expand All @@ -132,9 +132,9 @@ function create_candlesticks(candles){
return {
x: data_time,
close: data_close,
decreasing: {line: {color: '#F65A33'}},
decreasing: {line: {color: sell_color}},
high: data_high,
increasing: {line: {color: '#7DF98D'}},
increasing: {line: {color: buy_color}},
line: {color: 'rgba(31,119,180,1)'},
low: data_low,
open: data_open,
Expand Down Expand Up @@ -315,12 +315,12 @@ function create_layout(graph_title){
domain: [0.2, 1],
autorange: true,
title: 'Price',
gridcolor: getTextColor(),
gridcolor: `rgba(${getTextColorRGB()}, 0.2)`,
},
paper_bgcolor: 'rgba(0,0,0,0)',
plot_bgcolor: 'rgba(0,0,0,0)',
font: {
color: "white"
color: getTextColor(),
}
};
}
Expand Down
8 changes: 8 additions & 0 deletions Services/Interfaces/web_interface/static/js/common/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ const getTextColor = () => {
return getComputedStyle(document.body).getPropertyValue('--mdb-primary-text-emphasis')
}

const getTextColorRGB = () => {
return getComputedStyle(document.body).getPropertyValue('--mdb-emphasis-color-rgb')
}

const isDarkTheme = () => {
return $("html").data("mdb-theme") === "dark"
}

const handle_rounded_numbers_display = () => {
$(".rounded-number").each(function (){
const text = $(this).text().trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ $(document).ready(function() {
}
};
const onEditorChange = (newValue) => {
updateTentacleConfig(newValue);
const update_url = $("button[data-role='saveConfig']").attr(update_url_attr);
updateTentacleConfig(newValue, update_url);
};
const startAutomations = () => {
const successCallback = (updated_data, update_url, dom_root_element, msg, status) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ function handle_apply_evaluator_default_config_success_callback(updated_data, up
location.reload();
}

function updateTentacleConfig(updatedConfig){
const update_url = $("button[data-role='saveConfig']").attr(update_url_attr);
function updateTentacleConfig(updatedConfig, update_url){
send_and_interpret_bot_update(updatedConfig, update_url, null, handle_tentacle_config_update_success_callback, handle_tentacle_config_update_error_callback);
}

Expand Down Expand Up @@ -67,13 +66,15 @@ function handleConfigDisplay(success){
$("#configErrorDetails").hide();
if(canEditConfig()) {
$("#saveConfigFooter").show();
$("button[data-role='saveConfig']").removeClass(hidden_class).unbind("click").click(function () {
$("button[data-role='saveConfig']").removeClass(hidden_class).unbind("click").click(function (event) {
const errorsDesc = validateJSONEditor(configEditor);
if (errorsDesc.length) {
create_alert("error", "Error when saving configuration",
`Invalid configuration data: ${errorsDesc}.`);
} else
updateTentacleConfig(configEditor.getValue());
} else{
const url = $(event.currentTarget).attr(update_url_attr)
updateTentacleConfig(configEditor.getValue(), url);
}
});
}else{
$("#noConfigMessage").show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ $(document).ready(function() {
if(checkoutUrl.url === null){
create_alert("success", "User already owns this extension", "");
} else {
const newTab = window.open(checkoutUrl.url, '_blank');
if(newTab !== null) {
newTab.focus();
}
document.location.href = checkoutUrl.url;
}
} finally {
checkoutButtons.removeClass("disabled");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ <h2><i class="fa fa-spinner fa-spin"></i></h2>
</div>
</div>
<div class="card-footer" id='saveConfigFooter' style='display: none;'>
<button class="btn btn-outline-success waves-effect" data-role='saveConfig' update-url="{{ url_for('config_tentacle', name=name, action='update') }}">Save configuration and restart later</button>
<button class="btn btn-primary waves-effect" data-role='saveConfig' update-url="{{ url_for('config_tentacle', name=name, action='update', restart='false') }}"><i class="fas fa-save"></i> Save configuration and restart later</button>
<button class="btn btn-outline-primary waves-effect mx-5" data-role='saveConfig' update-url="{{ url_for('config_tentacle', name=name, action='update', restart='true') }}">Save and restart</button>
<button class="btn btn-outline-warning waves-effect float-right" data-role='factoryResetConfig'
update-url="{{ url_for('config_tentacle', name=name, action='factory_reset') }}"><i class="fas fa-recycle"></i> Reset configuration to default values</button>
</div>
Expand All @@ -79,7 +80,7 @@ <h2>Commands</h2>
<div class="card-body">
{% for command_action, command_params in user_commands.items() %}
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary waves-effect"
<button type="button" class="btn btn-outline-primary waves-effect"
data-toggle="modal" data-target="#{{ command_action | replace (' ', '') }}Modal">
{{ command_action }}
</button>
Expand Down
2 changes: 1 addition & 1 deletion Trading/Exchange/binance/binance_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class BinanceCCXTAdapter(exchanges.CCXTAdapter):
BINANCE_DEFAULT_FUNDING_TIME = 8 * commons_constants.HOURS_TO_SECONDS

def fix_order(self, raw, symbol=None, **kwargs):
fixed = super().fix_order(raw, **kwargs)
fixed = super().fix_order(raw, symbol=symbol, **kwargs)
self._adapt_order_type(fixed)
if fixed.get(ccxt_enums.ExchangeOrderCCXTColumns.STATUS.value, None) == "PENDING_NEW":
# PENDING_NEW order are old orders on binance and should be considered as open
Expand Down
3 changes: 3 additions & 0 deletions Trading/Exchange/bybit/bybit_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class Bybit(exchanges.RestExchange):
EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION = True # set True when get_order() can return None
# (order not found) when orders are instantly filled on exchange and are not fully processed on the exchange side.

# Set True when get_open_order() can return outdated orders (cancelled or not yet created)
CAN_HAVE_DELAYED_CANCELLED_ORDERS = True

BUY_STR = "Buy"
SELL_STR = "Sell"

Expand Down
1 change: 1 addition & 0 deletions Trading/Exchange/coinex/coinex_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Coinex(exchanges.RestExchange):
# ExchangeError('coinex Order not found')
("order not found", )
]
SUPPORT_FETCHING_CANCELLED_ORDERS = False

@classmethod
def get_name(cls):
Expand Down
2 changes: 2 additions & 0 deletions Trading/Exchange/cryptocom/cryptocom_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class CryptoCom(exchanges.RestExchange):
EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION = True # set True when get_order() can return None
# (order not found) when orders are instantly filled on exchange and are not fully processed on the exchange side.

SUPPORT_FETCHING_CANCELLED_ORDERS = False

@classmethod
def get_name(cls):
return 'cryptocom'
3 changes: 2 additions & 1 deletion Trading/Exchange/hollaex/hollaex_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class hollaex(exchanges.RestExchange):
REST_KEY = "rest"
HAS_WEBSOCKETS_KEY = "has_websockets"
REQUIRE_ORDER_FEES_FROM_TRADES = True # set True when get_order is not giving fees on closed orders and fees
SUPPORT_FETCHING_CANCELLED_ORDERS = False

DEFAULT_MAX_LIMIT = 500

Expand Down Expand Up @@ -102,7 +103,7 @@ class HollaexCCXTAdapter(exchanges.CCXTAdapter):
def fix_order(self, raw, symbol=None, **kwargs):
raw_order_info = raw[ccxt_enums.ExchangePositionCCXTColumns.INFO.value]
# average is not supported by ccxt
fixed = super().fix_order(raw, **kwargs)
fixed = super().fix_order(raw, symbol=symbol, **kwargs)
if not fixed[trading_enums.ExchangeConstantsOrderColumns.PRICE.value] and "average" in raw_order_info:
fixed[trading_enums.ExchangeConstantsOrderColumns.PRICE.value] = raw_order_info.get("average", 0)
return fixed
6 changes: 5 additions & 1 deletion Trading/Exchange/kucoin/kucoin_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ class Kucoin(exchanges.RestExchange):
FIX_MARKET_STATUS = True
REMOVE_MARKET_STATUS_PRICE_LIMITS = True
ADAPT_MARKET_STATUS_FOR_CONTRACT_SIZE = True
# Set True when get_open_order() can return outdated orders (cancelled or not yet created)
CAN_HAVE_DELAYED_OPEN_ORDERS = True
# Set True when get_cancelled_order() can return outdated open orders
CAN_HAVE_DELAYED_CANCELLED_ORDERS = True
DEFAULT_CONNECTOR_CLASS = KucoinConnector

FAKE_DDOS_ERROR_INSTANT_RETRY_COUNT = 5
Expand Down Expand Up @@ -452,7 +456,7 @@ class KucoinCCXTAdapter(exchanges.CCXTAdapter):

def fix_order(self, raw, symbol=None, **kwargs):
raw_order_info = raw[ccxt_enums.ExchangePositionCCXTColumns.INFO.value]
fixed = super().fix_order(raw, **kwargs)
fixed = super().fix_order(raw, symbol=symbol, **kwargs)
self._ensure_fees(fixed)
if self.connector.exchange_manager.is_future and \
fixed[trading_enums.ExchangeConstantsOrderColumns.COST.value] is not None:
Expand Down
2 changes: 1 addition & 1 deletion Trading/Exchange/okx/okx_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class OKXCCXTAdapter(exchanges.CCXTAdapter):
OKX_DEFAULT_FUNDING_TIME = 8 * commons_constants.HOURS_TO_SECONDS

def fix_order(self, raw, symbol=None, **kwargs):
fixed = super().fix_order(raw, **kwargs)
fixed = super().fix_order(raw, symbol=symbol, **kwargs)
self._adapt_order_type(fixed)
return fixed

Expand Down
15 changes: 9 additions & 6 deletions Trading/Mode/index_trading_mode/index_trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,16 @@ async def _buy_coin(self, symbol, ideal_amount) -> list:
await trading_personal_data.get_pre_order_data(
self.exchange_manager, symbol=symbol, timeout=trading_constants.ORDER_DATA_FETCHING_TIMEOUT
)
order_target_price = price
# ideally use the expected reference_market_available_holdings ratio, fallback to available
# holdings if necessary
target_quantity = min(ideal_amount, current_market_holding / price)
target_quantity = min(ideal_amount, current_market_holding / order_target_price)
ideal_quantity = target_quantity - current_symbol_holding
if ideal_quantity <= trading_constants.ZERO:
return []
quantity = trading_personal_data.decimal_adapt_order_quantity_because_fees(
self.exchange_manager, symbol, trading_enums.TraderOrderType.BUY_MARKET, ideal_quantity,
price, trading_enums.ExchangeConstantsMarketPropertyColumns.TAKER,
order_target_price, trading_enums.ExchangeConstantsMarketPropertyColumns.TAKER,
trading_enums.TradeOrderSide.BUY, current_market_holding
)
created_orders = []
Expand All @@ -196,19 +197,21 @@ async def _buy_coin(self, symbol, ideal_amount) -> list:

if trading_personal_data.get_trade_order_type(order_type) is not trading_enums.TradeOrderType.MARKET:
# can't use market orders: use limit orders with price a bit above the current price to instant fill it.
price, quantity = \
trading_modes.get_instantly_filled_limit_order_adapted_price_and_quantity(price, quantity, order_type)
order_target_price, quantity = \
trading_modes.get_instantly_filled_limit_order_adapted_price_and_quantity(
order_target_price, quantity, order_type
)
for order_quantity, order_price in trading_personal_data.decimal_check_and_adapt_order_details_if_necessary(
quantity,
price,
order_target_price,
symbol_market
):
orders_should_have_been_created = True
current_order = trading_personal_data.create_order_instance(
trader=self.exchange_manager.trader,
order_type=order_type,
symbol=symbol,
current_price=order_price,
current_price=price,
quantity=order_quantity,
price=order_price,
)
Expand Down

0 comments on commit 9acafa5

Please sign in to comment.