Skip to content

Commit 5c9b9c9

Browse files
committed
[DailyTrading] fix max ratio
1 parent 3878080 commit 5c9b9c9

File tree

2 files changed

+140
-96
lines changed

2 files changed

+140
-96
lines changed

Trading/Mode/daily_trading_mode/daily_trading.py

Lines changed: 51 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -313,95 +313,50 @@ def _get_stop_price_from_risk(self, is_long):
313313
factor = max_percent - risk_difference if is_long else min_percent + risk_difference
314314
return trading_modes.check_factor(min_percent, max_percent, factor)
315315

316-
"""
317-
Starting point : self.QUANTITY_MIN_PERCENT
318-
abs(eval_note) --> confirmation level --> high : sell/buy more quantity
319-
trader.risk --> high risk : sell / buy more quantity
320-
abs(eval_note) + weighted_risk --> result between 0 and 1 + self.QUANTITY_RISK_WEIGHT --> self.MAX_SUM_RESULT
321-
self.QUANTITY_ATTENUATION --> try to contains the result between self.QUANTITY_MIN_PERCENT
322-
and self.QUANTITY_MAX_PERCENT
323-
"""
324316

325-
async def _get_buy_limit_quantity_from_risk(self, ctx, eval_note, quantity, quote, increasing_position):
317+
async def _get_limit_quantity_from_risk(self, ctx, eval_note, max_quantity, base, selling, increasing_position):
318+
order_side = trading_enums.TradeOrderSide.SELL if selling else trading_enums.TradeOrderSide.BUY
326319
# check all in orders
327-
if increasing_position and self.BUY_WITH_MAXIMUM_SIZE_ORDERS:
328-
return quantity
320+
if increasing_position and (
321+
(selling and self.SELL_WITH_MAXIMUM_SIZE_ORDERS) or (not selling and self.BUY_WITH_MAXIMUM_SIZE_ORDERS)
322+
):
323+
return max_quantity
329324
# check configured quantity
325+
max_amount_from_ratio = self._get_max_amount_from_max_ratio(
326+
self.MAX_CURRENCY_RATIO, max_quantity, base, self.QUANTITY_MAX_PERCENT
327+
) if increasing_position else max_quantity
330328
if user_amount := trading_modes.get_user_selected_order_amount(
331329
self.trading_mode,
332330
self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE
333-
if self.USE_TARGET_PROFIT_MODE else trading_enums.TradeOrderSide.BUY
331+
if self.USE_TARGET_PROFIT_MODE else order_side
334332
):
335-
return await script_keywords.get_amount_from_input_amount(
333+
user_input_amount = await script_keywords.get_amount_from_input_amount(
336334
context=ctx,
337335
input_amount=user_amount,
338-
side=trading_enums.TradeOrderSide.BUY.value,
336+
side=order_side.value,
339337
reduce_only=False,
340338
is_stop_order=False,
341339
use_total_holding=False,
342340
)
341+
return min(user_input_amount, max_amount_from_ratio)
343342
# get quantity from risk
344-
max_amount = self._get_max_amount_from_max_ratio(
345-
self.MAX_CURRENCY_RATIO, quantity, quote, self.QUANTITY_MAX_PERCENT
346-
) if increasing_position else quantity
347343
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
348-
# consider buy quantity like a sell if quote is the reference market
349-
if quote == self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market \
350-
and increasing_position:
351-
weighted_risk *= self.SELL_MULTIPLIER
352-
if not increasing_position and self._get_ratio(quote) < self.FULL_SELL_MIN_RATIO:
353-
return quantity
354-
factor = self.QUANTITY_MIN_PERCENT + ((abs(eval_note) + weighted_risk) * self.QUANTITY_ATTENUATION)
355-
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT,
356-
factor)
357-
holding_ratio = self._get_quantity_ratio(quote) if increasing_position else trading_constants.ONE
358-
return min(checked_factor * quantity * holding_ratio, max_amount)
359-
360-
"""
361-
Starting point : self.QUANTITY_MIN_PERCENT
362-
abs(eval_note) --> confirmation level --> high : sell/buy more quantity
363-
trader.risk --> high risk : sell / buy more quantity
364-
use SELL_MULTIPLIER to increase sell volume relatively to risk
365-
if currency holding < FULL_SELL_MIN_RATIO, sell everything to free up funds
366-
abs(eval_note) + weighted_risk --> result between 0 and 1 + self.QUANTITY_RISK_WEIGHT --> self.MAX_SUM_RESULT
367-
self.QUANTITY_ATTENUATION --> try to contains the result between self.QUANTITY_MIN_PERCENT
368-
and self.QUANTITY_MAX_PERCENT
369-
"""
370-
371-
async def _get_sell_limit_quantity_from_risk(self, ctx, eval_note, quantity, quote, increasing_position):
372-
# check all in orders
373-
if not increasing_position and self.SELL_WITH_MAXIMUM_SIZE_ORDERS:
374-
return quantity
375-
if user_amount := trading_modes.get_user_selected_order_amount(
376-
self.trading_mode,
377-
self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE
378-
if self.USE_TARGET_PROFIT_MODE else trading_enums.TradeOrderSide.SELL
344+
if (
345+
# consider sell quantity like a buy if base is the reference market
346+
selling and base != self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
347+
and not increasing_position
348+
) or (
349+
# consider buy quantity like a sell if quote is the reference market
350+
not selling and base == self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
351+
and increasing_position
379352
):
380-
return await script_keywords.get_amount_from_input_amount(
381-
context=ctx,
382-
input_amount=user_amount,
383-
side=trading_enums.TradeOrderSide.SELL.value,
384-
reduce_only=False,
385-
is_stop_order=False,
386-
use_total_holding=False,
387-
)
388-
# check configured quantity
389-
# get quantity from risk
390-
max_amount = self._get_max_amount_from_max_ratio(
391-
self.MAX_CURRENCY_RATIO, quantity, quote, self.QUANTITY_MAX_PERCENT
392-
) if increasing_position else quantity
393-
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
394-
# consider sell quantity like a buy if base is the reference market
395-
if quote != self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market \
396-
and not increasing_position:
397353
weighted_risk *= self.SELL_MULTIPLIER
398-
if not increasing_position and self._get_ratio(quote) < self.FULL_SELL_MIN_RATIO:
399-
return quantity
354+
if not increasing_position and self._get_ratio(base) < self.FULL_SELL_MIN_RATIO:
355+
return max_quantity
400356
factor = self.QUANTITY_MIN_PERCENT + ((abs(eval_note) + weighted_risk) * self.QUANTITY_ATTENUATION)
401-
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT,
402-
factor)
403-
holding_ratio = self._get_quantity_ratio(quote) if increasing_position else trading_constants.ONE
404-
return min(checked_factor * quantity * holding_ratio, max_amount)
357+
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT, factor)
358+
holding_ratio = self._get_quantity_ratio(base) if increasing_position else trading_constants.ONE
359+
return min(checked_factor * max_quantity * holding_ratio, max_amount_from_ratio)
405360

406361
"""
407362
Starting point : self.QUANTITY_MARKET_MIN_PERCENT
@@ -413,35 +368,37 @@ async def _get_sell_limit_quantity_from_risk(self, ctx, eval_note, quantity, quo
413368
and self.QUANTITY_MARKET_MAX_PERCENT
414369
"""
415370

416-
async def _get_market_quantity_from_risk(self, ctx, eval_note, quantity, quote, selling, increasing_position):
371+
async def _get_market_quantity_from_risk(self, ctx, eval_note, quantity, base, selling, increasing_position):
417372
# check configured quantity
418373
side = self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE if self.USE_TARGET_PROFIT_MODE else (
419374
trading_enums.TradeOrderSide.SELL if selling else trading_enums.TradeOrderSide.BUY
420375
)
376+
max_amount_from_ratio = (
377+
self._get_max_amount_from_max_ratio(
378+
self.MAX_CURRENCY_RATIO, quantity, base, self.QUANTITY_MARKET_MAX_PERCENT
379+
) if increasing_position else quantity * self.QUANTITY_MARKET_MAX_PERCENT
380+
)
421381
if user_amount := trading_modes.get_user_selected_order_amount(self.trading_mode, side):
422-
return await script_keywords.get_amount_from_input_amount(
382+
user_input_amount = await script_keywords.get_amount_from_input_amount(
423383
context=ctx,
424384
input_amount=user_amount,
425385
side=side.value,
426386
reduce_only=False,
427387
is_stop_order=False,
428388
use_total_holding=False,
429389
)
390+
return min(user_input_amount, max_amount_from_ratio)
430391
# get quantity from risk
431-
max_amount = quantity * self.QUANTITY_MARKET_MAX_PERCENT if increasing_position \
432-
else self._get_max_amount_from_max_ratio(self.MAX_CURRENCY_RATIO, quantity,
433-
quote, self.QUANTITY_MARKET_MAX_PERCENT)
434392
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
435393
ref_market = self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
436-
if (not increasing_position and quote != ref_market) or (increasing_position and quote == ref_market):
394+
if (not increasing_position and base != ref_market) or (increasing_position and base == ref_market):
437395
weighted_risk *= self.SELL_MULTIPLIER
438-
factor = self.QUANTITY_MARKET_MIN_PERCENT + (
439-
(abs(eval_note) + weighted_risk) * self.QUANTITY_MARKET_ATTENUATION)
440-
441-
checked_factor = trading_modes.check_factor(self.QUANTITY_MARKET_MIN_PERCENT,
442-
self.QUANTITY_MARKET_MAX_PERCENT, factor)
443-
holding_ratio = 1 if not increasing_position else self._get_quantity_ratio(quote)
444-
return min(checked_factor * holding_ratio * quantity, max_amount)
396+
factor = self.QUANTITY_MARKET_MIN_PERCENT + (abs(eval_note) + weighted_risk) * self.QUANTITY_MARKET_ATTENUATION
397+
checked_factor = trading_modes.check_factor(
398+
self.QUANTITY_MARKET_MIN_PERCENT, self.QUANTITY_MARKET_MAX_PERCENT, factor
399+
)
400+
holding_ratio = 1 if not increasing_position else self._get_quantity_ratio(base)
401+
return min(checked_factor * holding_ratio * quantity, max_amount_from_ratio)
445402

446403
def _get_ratio(self, currency):
447404
try:
@@ -461,21 +418,21 @@ def _get_quantity_ratio(self, currency):
461418
else:
462419
return 1
463420

464-
def _get_max_amount_from_max_ratio(self, max_ratio, quantity, quote, default_ratio):
421+
def _get_max_amount_from_max_ratio(self, max_ratio, quantity, currency, default_ratio):
465422
# TODO ratios in futures trading
466423
# reduce max amount when self.MAX_CURRENCY_RATIO is defined
467424
if self.MAX_CURRENCY_RATIO is None or max_ratio == trading_constants.ONE or self.exchange_manager.is_future:
468425
return quantity * default_ratio
469-
max_amount_ratio = max_ratio - self._get_ratio(quote)
426+
max_amount_ratio = max_ratio - self._get_ratio(currency)
470427
if max_amount_ratio > 0:
471428
max_amount_in_ref_market = trading_api.get_current_portfolio_value(self.exchange_manager) * \
472429
max_amount_ratio
473430
try:
474431
max_theoretical_amount = max_amount_in_ref_market / trading_api.get_current_crypto_currency_value(
475-
self.exchange_manager, quote)
432+
self.exchange_manager, currency)
476433
return min(max_theoretical_amount, quantity)
477434
except KeyError:
478-
self.logger.error(f"Missing price information in reference market for {quote}. Skipping buy order "
435+
self.logger.error(f"Missing price information in reference market for {currency}. Skipping buy order "
479436
f"as is it required to ensure the maximum currency percent parameter. "
480437
f"Set it to 100 to buy anyway.")
481438
return trading_constants.ZERO
@@ -719,10 +676,9 @@ async def create_new_orders(self, symbol, final_note, state, **kwargs):
719676
created_orders.append(current_order)
720677

721678
elif state == trading_enums.EvaluatorStates.SHORT.value and not self.DISABLE_SELL_ORDERS:
722-
quantity = user_volume or \
723-
await self._get_sell_limit_quantity_from_risk(
724-
ctx, final_note, max_sell_size, base, increasing_position
725-
)
679+
quantity = user_volume or await self._get_limit_quantity_from_risk(
680+
ctx, final_note, max_sell_size, base, True, increasing_position
681+
)
726682
quantity = trading_personal_data.decimal_add_dusts_to_quantity_if_necessary(quantity, price,
727683
symbol_market,
728684
max_sell_size)
@@ -786,10 +742,9 @@ async def create_new_orders(self, symbol, final_note, state, **kwargs):
786742
return []
787743

788744
elif state == trading_enums.EvaluatorStates.LONG.value and not self.DISABLE_BUY_ORDERS:
789-
quantity = await self._get_buy_limit_quantity_from_risk(
790-
ctx, final_note, max_buy_size, base, increasing_position
791-
) \
792-
if user_volume == 0 else user_volume
745+
quantity = await self._get_limit_quantity_from_risk(
746+
ctx, final_note, max_buy_size, base, False, increasing_position
747+
) if user_volume == 0 else user_volume
793748
limit_price = user_stop_price if create_stop_only else trading_personal_data.decimal_adapt_price(
794749
symbol_market, user_price or (price * self._get_limit_price_from_risk(final_note))
795750
)

0 commit comments

Comments
 (0)