Skip to content
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
147 changes: 51 additions & 96 deletions Trading/Mode/daily_trading_mode/daily_trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,95 +313,50 @@ def _get_stop_price_from_risk(self, is_long):
factor = max_percent - risk_difference if is_long else min_percent + risk_difference
return trading_modes.check_factor(min_percent, max_percent, factor)

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

async def _get_buy_limit_quantity_from_risk(self, ctx, eval_note, quantity, quote, increasing_position):
async def _get_limit_quantity_from_risk(self, ctx, eval_note, max_quantity, base, selling, increasing_position):
order_side = trading_enums.TradeOrderSide.SELL if selling else trading_enums.TradeOrderSide.BUY
# check all in orders
if increasing_position and self.BUY_WITH_MAXIMUM_SIZE_ORDERS:
return quantity
if increasing_position and (
(selling and self.SELL_WITH_MAXIMUM_SIZE_ORDERS) or (not selling and self.BUY_WITH_MAXIMUM_SIZE_ORDERS)
):
return max_quantity
# check configured quantity
max_amount_from_ratio = self._get_max_amount_from_max_ratio(
self.MAX_CURRENCY_RATIO, max_quantity, base, self.QUANTITY_MAX_PERCENT
) if increasing_position else max_quantity
if user_amount := trading_modes.get_user_selected_order_amount(
self.trading_mode,
self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE
if self.USE_TARGET_PROFIT_MODE else trading_enums.TradeOrderSide.BUY
if self.USE_TARGET_PROFIT_MODE else order_side
):
return await script_keywords.get_amount_from_input_amount(
user_input_amount = await script_keywords.get_amount_from_input_amount(
context=ctx,
input_amount=user_amount,
side=trading_enums.TradeOrderSide.BUY.value,
side=order_side.value,
reduce_only=False,
is_stop_order=False,
use_total_holding=False,
)
return min(user_input_amount, max_amount_from_ratio)
# get quantity from risk
max_amount = self._get_max_amount_from_max_ratio(
self.MAX_CURRENCY_RATIO, quantity, quote, self.QUANTITY_MAX_PERCENT
) if increasing_position else quantity
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
# consider buy quantity like a sell if quote is the reference market
if quote == self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market \
and increasing_position:
weighted_risk *= self.SELL_MULTIPLIER
if not increasing_position and self._get_ratio(quote) < self.FULL_SELL_MIN_RATIO:
return quantity
factor = self.QUANTITY_MIN_PERCENT + ((abs(eval_note) + weighted_risk) * self.QUANTITY_ATTENUATION)
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT,
factor)
holding_ratio = self._get_quantity_ratio(quote) if increasing_position else trading_constants.ONE
return min(checked_factor * quantity * holding_ratio, max_amount)

"""
Starting point : self.QUANTITY_MIN_PERCENT
abs(eval_note) --> confirmation level --> high : sell/buy more quantity
trader.risk --> high risk : sell / buy more quantity
use SELL_MULTIPLIER to increase sell volume relatively to risk
if currency holding < FULL_SELL_MIN_RATIO, sell everything to free up funds
abs(eval_note) + weighted_risk --> result between 0 and 1 + self.QUANTITY_RISK_WEIGHT --> self.MAX_SUM_RESULT
self.QUANTITY_ATTENUATION --> try to contains the result between self.QUANTITY_MIN_PERCENT
and self.QUANTITY_MAX_PERCENT
"""

async def _get_sell_limit_quantity_from_risk(self, ctx, eval_note, quantity, quote, increasing_position):
# check all in orders
if not increasing_position and self.SELL_WITH_MAXIMUM_SIZE_ORDERS:
return quantity
if user_amount := trading_modes.get_user_selected_order_amount(
self.trading_mode,
self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE
if self.USE_TARGET_PROFIT_MODE else trading_enums.TradeOrderSide.SELL
if (
# consider sell quantity like a buy if base is the reference market
selling and base != self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
and not increasing_position
) or (
# consider buy quantity like a sell if quote is the reference market
not selling and base == self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
and increasing_position
):
return await script_keywords.get_amount_from_input_amount(
context=ctx,
input_amount=user_amount,
side=trading_enums.TradeOrderSide.SELL.value,
reduce_only=False,
is_stop_order=False,
use_total_holding=False,
)
# check configured quantity
# get quantity from risk
max_amount = self._get_max_amount_from_max_ratio(
self.MAX_CURRENCY_RATIO, quantity, quote, self.QUANTITY_MAX_PERCENT
) if increasing_position else quantity
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
# consider sell quantity like a buy if base is the reference market
if quote != self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market \
and not increasing_position:
weighted_risk *= self.SELL_MULTIPLIER
if not increasing_position and self._get_ratio(quote) < self.FULL_SELL_MIN_RATIO:
return quantity
if not increasing_position and self._get_ratio(base) < self.FULL_SELL_MIN_RATIO:
return max_quantity
factor = self.QUANTITY_MIN_PERCENT + ((abs(eval_note) + weighted_risk) * self.QUANTITY_ATTENUATION)
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT,
factor)
holding_ratio = self._get_quantity_ratio(quote) if increasing_position else trading_constants.ONE
return min(checked_factor * quantity * holding_ratio, max_amount)
checked_factor = trading_modes.check_factor(self.QUANTITY_MIN_PERCENT, self.QUANTITY_MAX_PERCENT, factor)
holding_ratio = self._get_quantity_ratio(base) if increasing_position else trading_constants.ONE
return min(checked_factor * max_quantity * holding_ratio, max_amount_from_ratio)

"""
Starting point : self.QUANTITY_MARKET_MIN_PERCENT
Expand All @@ -413,35 +368,37 @@ async def _get_sell_limit_quantity_from_risk(self, ctx, eval_note, quantity, quo
and self.QUANTITY_MARKET_MAX_PERCENT
"""

async def _get_market_quantity_from_risk(self, ctx, eval_note, quantity, quote, selling, increasing_position):
async def _get_market_quantity_from_risk(self, ctx, eval_note, quantity, base, selling, increasing_position):
# check configured quantity
side = self.TARGET_PROFIT_MODE_ENTRY_QUANTITY_SIDE if self.USE_TARGET_PROFIT_MODE else (
trading_enums.TradeOrderSide.SELL if selling else trading_enums.TradeOrderSide.BUY
)
max_amount_from_ratio = (
self._get_max_amount_from_max_ratio(
self.MAX_CURRENCY_RATIO, quantity, base, self.QUANTITY_MARKET_MAX_PERCENT
) if increasing_position else quantity * self.QUANTITY_MARKET_MAX_PERCENT
)
if user_amount := trading_modes.get_user_selected_order_amount(self.trading_mode, side):
return await script_keywords.get_amount_from_input_amount(
user_input_amount = await script_keywords.get_amount_from_input_amount(
context=ctx,
input_amount=user_amount,
side=side.value,
reduce_only=False,
is_stop_order=False,
use_total_holding=False,
)
return min(user_input_amount, max_amount_from_ratio)
# get quantity from risk
max_amount = quantity * self.QUANTITY_MARKET_MAX_PERCENT if increasing_position \
else self._get_max_amount_from_max_ratio(self.MAX_CURRENCY_RATIO, quantity,
quote, self.QUANTITY_MARKET_MAX_PERCENT)
weighted_risk = self.trader.risk * self.QUANTITY_RISK_WEIGHT
ref_market = self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market
if (not increasing_position and quote != ref_market) or (increasing_position and quote == ref_market):
if (not increasing_position and base != ref_market) or (increasing_position and base == ref_market):
weighted_risk *= self.SELL_MULTIPLIER
factor = self.QUANTITY_MARKET_MIN_PERCENT + (
(abs(eval_note) + weighted_risk) * self.QUANTITY_MARKET_ATTENUATION)

checked_factor = trading_modes.check_factor(self.QUANTITY_MARKET_MIN_PERCENT,
self.QUANTITY_MARKET_MAX_PERCENT, factor)
holding_ratio = 1 if not increasing_position else self._get_quantity_ratio(quote)
return min(checked_factor * holding_ratio * quantity, max_amount)
factor = self.QUANTITY_MARKET_MIN_PERCENT + (abs(eval_note) + weighted_risk) * self.QUANTITY_MARKET_ATTENUATION
checked_factor = trading_modes.check_factor(
self.QUANTITY_MARKET_MIN_PERCENT, self.QUANTITY_MARKET_MAX_PERCENT, factor
)
holding_ratio = 1 if not increasing_position else self._get_quantity_ratio(base)
return min(checked_factor * holding_ratio * quantity, max_amount_from_ratio)

def _get_ratio(self, currency):
try:
Expand All @@ -461,21 +418,21 @@ def _get_quantity_ratio(self, currency):
else:
return 1

def _get_max_amount_from_max_ratio(self, max_ratio, quantity, quote, default_ratio):
def _get_max_amount_from_max_ratio(self, max_ratio, quantity, currency, default_ratio):
# TODO ratios in futures trading
# reduce max amount when self.MAX_CURRENCY_RATIO is defined
if self.MAX_CURRENCY_RATIO is None or max_ratio == trading_constants.ONE or self.exchange_manager.is_future:
return quantity * default_ratio
max_amount_ratio = max_ratio - self._get_ratio(quote)
max_amount_ratio = max_ratio - self._get_ratio(currency)
if max_amount_ratio > 0:
max_amount_in_ref_market = trading_api.get_current_portfolio_value(self.exchange_manager) * \
max_amount_ratio
try:
max_theoretical_amount = max_amount_in_ref_market / trading_api.get_current_crypto_currency_value(
self.exchange_manager, quote)
self.exchange_manager, currency)
return min(max_theoretical_amount, quantity)
except KeyError:
self.logger.error(f"Missing price information in reference market for {quote}. Skipping buy order "
self.logger.error(f"Missing price information in reference market for {currency}. Skipping buy order "
f"as is it required to ensure the maximum currency percent parameter. "
f"Set it to 100 to buy anyway.")
return trading_constants.ZERO
Expand Down Expand Up @@ -719,10 +676,9 @@ async def create_new_orders(self, symbol, final_note, state, **kwargs):
created_orders.append(current_order)

elif state == trading_enums.EvaluatorStates.SHORT.value and not self.DISABLE_SELL_ORDERS:
quantity = user_volume or \
await self._get_sell_limit_quantity_from_risk(
ctx, final_note, max_sell_size, base, increasing_position
)
quantity = user_volume or await self._get_limit_quantity_from_risk(
ctx, final_note, max_sell_size, base, True, increasing_position
)
quantity = trading_personal_data.decimal_add_dusts_to_quantity_if_necessary(quantity, price,
symbol_market,
max_sell_size)
Expand Down Expand Up @@ -786,10 +742,9 @@ async def create_new_orders(self, symbol, final_note, state, **kwargs):
return []

elif state == trading_enums.EvaluatorStates.LONG.value and not self.DISABLE_BUY_ORDERS:
quantity = await self._get_buy_limit_quantity_from_risk(
ctx, final_note, max_buy_size, base, increasing_position
) \
if user_volume == 0 else user_volume
quantity = await self._get_limit_quantity_from_risk(
ctx, final_note, max_buy_size, base, False, increasing_position
) if user_volume == 0 else user_volume
limit_price = user_stop_price if create_stop_only else trading_personal_data.decimal_adapt_price(
symbol_market, user_price or (price * self._get_limit_price_from_risk(final_note))
)
Expand Down
Loading