Merge pull request 'Shtoto' (#23) from Alex/stcs:devel into stable
Reviewed-on: #23
This commit is contained in:
32
alembic/versions/0ee52ab23e66_added_column_current_series.py
Normal file
32
alembic/versions/0ee52ab23e66_added_column_current_series.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"""Added column current_series
|
||||||
|
|
||||||
|
Revision ID: 0ee52ab23e66
|
||||||
|
Revises: e5d612e44563
|
||||||
|
Create Date: 2025-10-26 11:48:48.055031
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = '0ee52ab23e66'
|
||||||
|
down_revision: Union[str, Sequence[str], None] = 'e5d612e44563'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('user_deals', sa.Column('current_series', sa.Integer(), nullable=True))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('user_deals', 'current_series')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
"""Added column commission_place
|
||||||
|
|
||||||
|
Revision ID: adf3d2991896
|
||||||
|
Revises: 0ee52ab23e66
|
||||||
|
Create Date: 2025-10-26 13:37:33.662318
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = 'adf3d2991896'
|
||||||
|
down_revision: Union[str, Sequence[str], None] = '0ee52ab23e66'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
bind = op.get_bind()
|
||||||
|
inspector = inspect(bind)
|
||||||
|
columns_user_deals = [col['name'] for col in inspector.get_columns('user_deals')]
|
||||||
|
if 'commission_fee' not in columns_user_deals:
|
||||||
|
op.add_column('user_deals', sa.Column('commission_fee', sa.String(), server_default='', nullable=True))
|
||||||
|
if 'commission_place' not in columns_user_deals:
|
||||||
|
op.add_column('user_deals', sa.Column('commission_place', sa.String(), server_default='', nullable=True))
|
||||||
|
|
||||||
|
columns_user_risk_mgmt = [col['name'] for col in inspector.get_columns('user_risk_management')]
|
||||||
|
if 'commission_place' not in columns_user_risk_mgmt:
|
||||||
|
op.add_column('user_risk_management',
|
||||||
|
sa.Column('commission_place', sa.String(), server_default='', nullable=False))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('user_risk_management', 'commission_place')
|
||||||
|
op.drop_column('user_deals', 'commission_place')
|
||||||
|
op.drop_column('user_deals', 'commission_fee')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -39,7 +39,8 @@ async def start_trading_cycle(
|
|||||||
max_bets_in_series = additional_data.max_bets_in_series
|
max_bets_in_series = additional_data.max_bets_in_series
|
||||||
take_profit_percent = risk_management_data.take_profit_percent
|
take_profit_percent = risk_management_data.take_profit_percent
|
||||||
stop_loss_percent = risk_management_data.stop_loss_percent
|
stop_loss_percent = risk_management_data.stop_loss_percent
|
||||||
total_commission = 0
|
commission_fee = risk_management_data.commission_fee
|
||||||
|
commission_place = risk_management_data.commission_place
|
||||||
|
|
||||||
if trade_mode == "Switch":
|
if trade_mode == "Switch":
|
||||||
side = side
|
side = side
|
||||||
@@ -70,7 +71,6 @@ async def start_trading_cycle(
|
|||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
commission_fee_percent=total_commission
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if res == "OK":
|
if res == "OK":
|
||||||
@@ -78,6 +78,7 @@ async def start_trading_cycle(
|
|||||||
tg_id=tg_id,
|
tg_id=tg_id,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
current_step=1,
|
current_step=1,
|
||||||
|
current_series=1,
|
||||||
trade_mode=trade_mode,
|
trade_mode=trade_mode,
|
||||||
side_mode=switch_side,
|
side_mode=switch_side,
|
||||||
margin_type=margin_type,
|
margin_type=margin_type,
|
||||||
@@ -88,7 +89,9 @@ async def start_trading_cycle(
|
|||||||
max_bets_in_series=max_bets_in_series,
|
max_bets_in_series=max_bets_in_series,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
base_quantity=order_quantity
|
base_quantity=order_quantity,
|
||||||
|
commission_fee=commission_fee,
|
||||||
|
commission_place=commission_place
|
||||||
)
|
)
|
||||||
return "OK"
|
return "OK"
|
||||||
return (
|
return (
|
||||||
@@ -119,8 +122,6 @@ async def trading_cycle_profit(
|
|||||||
tg_id: int, symbol: str, side: str) -> str | None:
|
tg_id: int, symbol: str, side: str) -> str | None:
|
||||||
try:
|
try:
|
||||||
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
|
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
|
||||||
user_auto_trading_data = await rq.get_user_auto_trading(tg_id=tg_id, symbol=symbol)
|
|
||||||
total_fee = user_auto_trading_data.total_fee
|
|
||||||
trade_mode = user_deals_data.trade_mode
|
trade_mode = user_deals_data.trade_mode
|
||||||
margin_type = user_deals_data.margin_type
|
margin_type = user_deals_data.margin_type
|
||||||
leverage = user_deals_data.leverage
|
leverage = user_deals_data.leverage
|
||||||
@@ -131,6 +132,9 @@ async def trading_cycle_profit(
|
|||||||
martingale_factor = user_deals_data.martingale_factor
|
martingale_factor = user_deals_data.martingale_factor
|
||||||
side_mode = user_deals_data.side_mode
|
side_mode = user_deals_data.side_mode
|
||||||
base_quantity = user_deals_data.base_quantity
|
base_quantity = user_deals_data.base_quantity
|
||||||
|
current_series = user_deals_data.current_series
|
||||||
|
commission_fee = user_deals_data.commission_fee
|
||||||
|
commission_place = user_deals_data.commission_place
|
||||||
|
|
||||||
await set_margin_mode(tg_id=tg_id, margin_mode=margin_type)
|
await set_margin_mode(tg_id=tg_id, margin_mode=margin_type)
|
||||||
await set_leverage(
|
await set_leverage(
|
||||||
@@ -139,7 +143,6 @@ async def trading_cycle_profit(
|
|||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if trade_mode == "Switch":
|
if trade_mode == "Switch":
|
||||||
if side_mode == "Противоположно":
|
if side_mode == "Противоположно":
|
||||||
s_side = "Sell" if side == "Buy" else "Buy"
|
s_side = "Sell" if side == "Buy" else "Buy"
|
||||||
@@ -148,6 +151,8 @@ async def trading_cycle_profit(
|
|||||||
else:
|
else:
|
||||||
s_side = side
|
s_side = side
|
||||||
|
|
||||||
|
next_series = current_series + 1
|
||||||
|
|
||||||
res = await open_positions(
|
res = await open_positions(
|
||||||
tg_id=tg_id,
|
tg_id=tg_id,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
@@ -158,7 +163,6 @@ async def trading_cycle_profit(
|
|||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
commission_fee_percent=total_fee
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if res == "OK":
|
if res == "OK":
|
||||||
@@ -166,6 +170,7 @@ async def trading_cycle_profit(
|
|||||||
tg_id=tg_id,
|
tg_id=tg_id,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
current_step=1,
|
current_step=1,
|
||||||
|
current_series=next_series,
|
||||||
trade_mode=trade_mode,
|
trade_mode=trade_mode,
|
||||||
side_mode=side_mode,
|
side_mode=side_mode,
|
||||||
margin_type=margin_type,
|
margin_type=margin_type,
|
||||||
@@ -176,7 +181,9 @@ async def trading_cycle_profit(
|
|||||||
max_bets_in_series=max_bets_in_series,
|
max_bets_in_series=max_bets_in_series,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
base_quantity=base_quantity
|
base_quantity=base_quantity,
|
||||||
|
commission_fee=commission_fee,
|
||||||
|
commission_place=commission_place
|
||||||
)
|
)
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
@@ -202,8 +209,8 @@ async def trading_cycle(
|
|||||||
try:
|
try:
|
||||||
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
|
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
|
||||||
user_auto_trading_data = await rq.get_user_auto_trading(tg_id=tg_id, symbol=symbol)
|
user_auto_trading_data = await rq.get_user_auto_trading(tg_id=tg_id, symbol=symbol)
|
||||||
user_risk_management_data = await rq.get_user_risk_management(tg_id=tg_id)
|
commission_fee = user_deals_data.commission_fee
|
||||||
commission_fee = user_risk_management_data.commission_fee
|
commission_place = user_deals_data.commission_place
|
||||||
total_fee = user_auto_trading_data.total_fee
|
total_fee = user_auto_trading_data.total_fee
|
||||||
trade_mode = user_deals_data.trade_mode
|
trade_mode = user_deals_data.trade_mode
|
||||||
margin_type = user_deals_data.margin_type
|
margin_type = user_deals_data.margin_type
|
||||||
@@ -217,6 +224,7 @@ async def trading_cycle(
|
|||||||
order_quantity = user_deals_data.order_quantity
|
order_quantity = user_deals_data.order_quantity
|
||||||
base_quantity = user_deals_data.base_quantity
|
base_quantity = user_deals_data.base_quantity
|
||||||
side_mode = user_deals_data.side_mode
|
side_mode = user_deals_data.side_mode
|
||||||
|
current_series = user_deals_data.current_series
|
||||||
|
|
||||||
next_quantity = safe_float(order_quantity) * (
|
next_quantity = safe_float(order_quantity) * (
|
||||||
safe_float(martingale_factor)
|
safe_float(martingale_factor)
|
||||||
@@ -232,10 +240,10 @@ async def trading_cycle(
|
|||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
)
|
)
|
||||||
|
total_quantity = next_quantity
|
||||||
if commission_fee == "Yes_commission_fee":
|
if commission_fee == "Yes_commission_fee":
|
||||||
total_fee = total_fee
|
if commission_place == "Commission_for_qty":
|
||||||
else:
|
total_quantity = next_quantity + total_fee
|
||||||
total_fee = 0
|
|
||||||
|
|
||||||
if trade_mode == "Switch":
|
if trade_mode == "Switch":
|
||||||
if side == "Buy":
|
if side == "Buy":
|
||||||
@@ -249,13 +257,12 @@ async def trading_cycle(
|
|||||||
tg_id=tg_id,
|
tg_id=tg_id,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
side=r_side,
|
side=r_side,
|
||||||
order_quantity=next_quantity,
|
order_quantity=total_quantity,
|
||||||
trigger_price=trigger_price,
|
trigger_price=trigger_price,
|
||||||
margin_type=margin_type,
|
margin_type=margin_type,
|
||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
commission_fee_percent=total_fee
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if res == "OK":
|
if res == "OK":
|
||||||
@@ -263,6 +270,7 @@ async def trading_cycle(
|
|||||||
tg_id=tg_id,
|
tg_id=tg_id,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
current_step=current_step,
|
current_step=current_step,
|
||||||
|
current_series=current_series,
|
||||||
trade_mode=trade_mode,
|
trade_mode=trade_mode,
|
||||||
side_mode=side_mode,
|
side_mode=side_mode,
|
||||||
margin_type=margin_type,
|
margin_type=margin_type,
|
||||||
@@ -273,7 +281,9 @@ async def trading_cycle(
|
|||||||
max_bets_in_series=max_bets_in_series,
|
max_bets_in_series=max_bets_in_series,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
base_quantity=base_quantity
|
base_quantity=base_quantity,
|
||||||
|
commission_fee=commission_fee,
|
||||||
|
commission_place=commission_place
|
||||||
)
|
)
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
@@ -303,11 +313,15 @@ async def open_positions(
|
|||||||
margin_type: str,
|
margin_type: str,
|
||||||
leverage: str,
|
leverage: str,
|
||||||
take_profit_percent: float,
|
take_profit_percent: float,
|
||||||
stop_loss_percent: float,
|
stop_loss_percent: float
|
||||||
commission_fee_percent: float
|
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
try:
|
try:
|
||||||
client = await get_bybit_client(tg_id=tg_id)
|
client = await get_bybit_client(tg_id=tg_id)
|
||||||
|
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
|
||||||
|
commission_fee = user_deals_data.commission_fee
|
||||||
|
commission_place = user_deals_data.commission_place
|
||||||
|
user_auto_trading_data = await rq.get_user_auto_trading(tg_id=tg_id, symbol=symbol)
|
||||||
|
total_fee = user_auto_trading_data.total_fee
|
||||||
get_ticker = await get_tickers(tg_id, symbol=symbol)
|
get_ticker = await get_tickers(tg_id, symbol=symbol)
|
||||||
price_symbol = safe_float(get_ticker.get("lastPrice")) or 0
|
price_symbol = safe_float(get_ticker.get("lastPrice")) or 0
|
||||||
instruments_info = await get_instruments_info(tg_id=tg_id, symbol=symbol)
|
instruments_info = await get_instruments_info(tg_id=tg_id, symbol=symbol)
|
||||||
@@ -315,8 +329,8 @@ async def open_positions(
|
|||||||
qty_step = safe_float(qty_step_str)
|
qty_step = safe_float(qty_step_str)
|
||||||
qty = (safe_float(order_quantity) * safe_float(leverage)) / safe_float(price_symbol)
|
qty = (safe_float(order_quantity) * safe_float(leverage)) / safe_float(price_symbol)
|
||||||
decimals = abs(int(round(math.log10(qty_step))))
|
decimals = abs(int(round(math.log10(qty_step))))
|
||||||
qty_formatted = math.floor(qty / qty_step) * qty_step
|
qty_format = math.floor(qty / qty_step) * qty_step
|
||||||
qty_formatted = round(qty_formatted, decimals)
|
qty_formatted = round(qty_format, decimals)
|
||||||
|
|
||||||
if trigger_price > 0:
|
if trigger_price > 0:
|
||||||
po_trigger_price = str(trigger_price)
|
po_trigger_price = str(trigger_price)
|
||||||
@@ -330,23 +344,28 @@ async def open_positions(
|
|||||||
if qty_formatted <= 0:
|
if qty_formatted <= 0:
|
||||||
return "Order does not meet minimum order value"
|
return "Order does not meet minimum order value"
|
||||||
|
|
||||||
|
total_commission = 0
|
||||||
|
if commission_fee == "Yes_commission_fee":
|
||||||
|
if commission_place == "Commission_for_tp":
|
||||||
|
total_commission = safe_float(total_fee) / qty_formatted
|
||||||
|
|
||||||
if margin_type == "ISOLATED_MARGIN":
|
if margin_type == "ISOLATED_MARGIN":
|
||||||
if side == "Buy":
|
if side == "Buy":
|
||||||
take_profit_price = price_for_cals * (
|
take_profit_price = price_for_cals * (
|
||||||
1 + take_profit_percent / 100) + commission_fee_percent / qty_formatted
|
1 + take_profit_percent / 100) + total_commission
|
||||||
stop_loss_price = None
|
stop_loss_price = None
|
||||||
else:
|
else:
|
||||||
take_profit_price = price_for_cals * (
|
take_profit_price = price_for_cals * (
|
||||||
1 - take_profit_percent / 100) - commission_fee_percent / qty_formatted
|
1 - take_profit_percent / 100) - total_commission
|
||||||
stop_loss_price = None
|
stop_loss_price = None
|
||||||
else:
|
else:
|
||||||
if side == "Buy":
|
if side == "Buy":
|
||||||
take_profit_price = price_for_cals * (
|
take_profit_price = price_for_cals * (
|
||||||
1 + take_profit_percent / 100) + commission_fee_percent / qty_formatted
|
1 + take_profit_percent / 100) + total_commission
|
||||||
stop_loss_price = price_for_cals * (1 - stop_loss_percent / 100)
|
stop_loss_price = price_for_cals * (1 - stop_loss_percent / 100)
|
||||||
else:
|
else:
|
||||||
take_profit_price = price_for_cals * (
|
take_profit_price = price_for_cals * (
|
||||||
1 - take_profit_percent / 100) - commission_fee_percent / qty_formatted
|
1 - take_profit_percent / 100) - total_commission
|
||||||
stop_loss_price = price_for_cals * (1 + stop_loss_percent / 100)
|
stop_loss_price = price_for_cals * (1 + stop_loss_percent / 100)
|
||||||
|
|
||||||
take_profit_price = max(take_profit_price, 0)
|
take_profit_price = max(take_profit_price, 0)
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class TelegramMessageHandler:
|
|||||||
|
|
||||||
exec_pnl = format_value(execution.get("execPnl"))
|
exec_pnl = format_value(execution.get("execPnl"))
|
||||||
total_pnl = safe_float(exec_pnl) - safe_float(exec_fee) - fee
|
total_pnl = safe_float(exec_pnl) - safe_float(exec_fee) - fee
|
||||||
|
|
||||||
header = (
|
header = (
|
||||||
"Сделка закрыта:" if safe_float(closed_size) > 0 else "Сделка открыта:"
|
"Сделка закрыта:" if safe_float(closed_size) > 0 else "Сделка открыта:"
|
||||||
)
|
)
|
||||||
@@ -129,11 +130,26 @@ class TelegramMessageHandler:
|
|||||||
user_deals_data = await rq.get_user_deal_by_symbol(
|
user_deals_data = await rq.get_user_deal_by_symbol(
|
||||||
tg_id=tg_id, symbol=symbol
|
tg_id=tg_id, symbol=symbol
|
||||||
)
|
)
|
||||||
if user_deals_data is not None and auto_trading:
|
commission_fee = user_deals_data.commission_fee
|
||||||
|
commission_place = user_deals_data.commission_place
|
||||||
|
|
||||||
|
if commission_fee == "Yes_commission_fee":
|
||||||
|
if commission_place == "Commission_for_qty":
|
||||||
|
total_quantity = safe_float(user_deals_data.order_quantity) + safe_float(
|
||||||
|
total_fee
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
total_quantity = safe_float(user_deals_data.order_quantity)
|
||||||
|
else:
|
||||||
|
total_quantity = safe_float(user_deals_data.order_quantity)
|
||||||
|
|
||||||
|
if user_deals_data is not None and auto_trading and safe_float(closed_size) == 0:
|
||||||
await rq.set_total_fee_user_auto_trading(
|
await rq.set_total_fee_user_auto_trading(
|
||||||
tg_id=tg_id, symbol=symbol, total_fee=total_fee
|
tg_id=tg_id, symbol=symbol, total_fee=total_fee
|
||||||
)
|
)
|
||||||
text += f"Текущая ставка: {user_deals_data.order_quantity} USDT\n"
|
text += f"Текущая ставка: {total_quantity:.2f} USDT\n"
|
||||||
|
text += f"Серия №: {user_deals_data.current_series}\n"
|
||||||
|
text += f"Сделка №: {user_deals_data.current_step}\n"
|
||||||
|
|
||||||
text += (
|
text += (
|
||||||
f"Цена исполнения: {exec_price}\n"
|
f"Цена исполнения: {exec_price}\n"
|
||||||
|
|||||||
@@ -341,3 +341,83 @@ async def set_commission_fee(callback_query: CallbackQuery, state: FSMContext) -
|
|||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
await state.clear()
|
await state.clear()
|
||||||
|
|
||||||
|
|
||||||
|
@router_risk_management.callback_query(F.data == "compensation_commission")
|
||||||
|
async def compensation_commission(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||||
|
"""
|
||||||
|
Handles the 'compensation_commission' callback query.
|
||||||
|
|
||||||
|
Clears the current FSM state, edits the message text to display the compensation commission options,
|
||||||
|
and shows an inline keyboard for selection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback_query (CallbackQuery): Incoming callback query from Telegram inline keyboard.
|
||||||
|
state (FSMContext): Finite State Machine context for the current user session.
|
||||||
|
|
||||||
|
Logs:
|
||||||
|
Success or error messages with user identification.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
await state.clear()
|
||||||
|
msg = await callback_query.message.edit_text(
|
||||||
|
text="Выберите за счет чего будет происходить компенсация комиссии: ",
|
||||||
|
reply_markup=kbi.commission_place,
|
||||||
|
)
|
||||||
|
await state.update_data(prompt_message_id=msg.message_id)
|
||||||
|
logger.debug(
|
||||||
|
"Command compensation_commission processed successfully for user: %s",
|
||||||
|
callback_query.from_user.id,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
await callback_query.answer(
|
||||||
|
text="Произошла ошибка. Пожалуйста, попробуйте позже."
|
||||||
|
)
|
||||||
|
logger.error(
|
||||||
|
"Error processing command compensation_commission for user %s: %s",
|
||||||
|
callback_query.from_user.id,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router_risk_management.callback_query(
|
||||||
|
lambda c: c.data in ["Commission_for_qty", "Commission_for_tp"]
|
||||||
|
)
|
||||||
|
async def set_compensation_commission(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||||
|
"""
|
||||||
|
Handles user input for setting the compensation commission.
|
||||||
|
|
||||||
|
Updates FSM context with the selected option and persists the choice in database.
|
||||||
|
Sends an acknowledgement to user and clears FSM state afterward.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback_query (CallbackQuery): Incoming callback query from Telegram inline keyboard.
|
||||||
|
state (FSMContext): Finite State Machine context for the current user session.
|
||||||
|
|
||||||
|
Logs:
|
||||||
|
Success or error messages with user identification.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
|
||||||
|
req = await rq.set_commission_place(
|
||||||
|
tg_id=callback_query.from_user.id, commission_place=callback_query.data
|
||||||
|
)
|
||||||
|
|
||||||
|
if not req:
|
||||||
|
await callback_query.answer(
|
||||||
|
text="Произошла ошибка при установке компенсации комиссии. Пожалуйста, попробуйте позже."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if callback_query.data == "Commission_for_qty":
|
||||||
|
await callback_query.answer(text="Комиссия компенсируется по ставке.")
|
||||||
|
else:
|
||||||
|
await callback_query.answer(text="Комиссия компенсируется по тейк-профиту.")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
"Error processing command compensation_commission for user %s: %s",
|
||||||
|
callback_query.from_user.id,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
await state.clear()
|
||||||
@@ -130,12 +130,17 @@ async def risk_management(callback_query: CallbackQuery, state: FSMContext) -> N
|
|||||||
commission_fee_rus = (
|
commission_fee_rus = (
|
||||||
"Да" if commission_fee == "Yes_commission_fee" else "Нет"
|
"Да" if commission_fee == "Yes_commission_fee" else "Нет"
|
||||||
)
|
)
|
||||||
|
commission_place = risk_management_data.commission_place
|
||||||
|
commission_place_rus = (
|
||||||
|
"Ставке" if commission_place == "Commission_for_qty" else "Тейк-профиту"
|
||||||
|
)
|
||||||
|
|
||||||
await callback_query.message.edit_text(
|
await callback_query.message.edit_text(
|
||||||
text=f"Риск-менеджмент:\n\n"
|
text=f"Риск-менеджмент:\n\n"
|
||||||
f"- Процент изменения цены для фиксации прибыли: {take_profit_percent:.2f}%\n"
|
f"- Процент изменения цены для фиксации прибыли: {take_profit_percent:.2f}%\n"
|
||||||
f"- Процент изменения цены для фиксации убытка: {stop_loss_percent:.2f}%\n\n"
|
f"- Процент изменения цены для фиксации убытка: {stop_loss_percent:.2f}%\n\n"
|
||||||
f"- Комиссия биржи для расчета прибыли: {commission_fee_rus}\n\n",
|
f"- Комиссия биржи для расчета прибыли: {commission_fee_rus}\n\n"
|
||||||
|
f"- Компенсация комиссии по: {commission_place_rus}",
|
||||||
reply_markup=kbi.risk_management,
|
reply_markup=kbi.risk_management,
|
||||||
)
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
@@ -174,7 +179,7 @@ async def conditions(callback_query: CallbackQuery, state: FSMContext) -> None:
|
|||||||
start_timer = conditional_settings_data.timer_start or 0
|
start_timer = conditional_settings_data.timer_start or 0
|
||||||
await callback_query.message.edit_text(
|
await callback_query.message.edit_text(
|
||||||
text="Условия торговли:\n\n"
|
text="Условия торговли:\n\n"
|
||||||
f"- Таймер для старта: {start_timer} мин.\n",
|
f"- Таймер для старта: {start_timer} мин.\n",
|
||||||
reply_markup=kbi.conditions,
|
reply_markup=kbi.conditions,
|
||||||
)
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ risk_management = InlineKeyboardMarkup(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
[InlineKeyboardButton(text="Комиссия биржи", callback_data="commission_fee")],
|
[InlineKeyboardButton(text="Комиссия биржи", callback_data="commission_fee")],
|
||||||
|
[InlineKeyboardButton(text="Компенсация комиссии", callback_data="compensation_commission")],
|
||||||
[
|
[
|
||||||
InlineKeyboardButton(text="Назад", callback_data="main_settings"),
|
InlineKeyboardButton(text="Назад", callback_data="main_settings"),
|
||||||
InlineKeyboardButton(text="На главную", callback_data="profile_bybit"),
|
InlineKeyboardButton(text="На главную", callback_data="profile_bybit"),
|
||||||
@@ -239,6 +240,20 @@ commission_fee = InlineKeyboardMarkup(
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
commission_place = InlineKeyboardMarkup(
|
||||||
|
inline_keyboard=[
|
||||||
|
[
|
||||||
|
InlineKeyboardButton(text="По ставке", callback_data="Commission_for_qty"),
|
||||||
|
InlineKeyboardButton(text="По тейк-профиту", callback_data="Commission_for_tp"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
InlineKeyboardButton(text="Назад", callback_data="risk_management"),
|
||||||
|
InlineKeyboardButton(text="На главную", callback_data="profile_bybit"),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# conditions
|
# conditions
|
||||||
conditions = InlineKeyboardMarkup(
|
conditions = InlineKeyboardMarkup(
|
||||||
inline_keyboard=[
|
inline_keyboard=[
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class UserRiskManagement(Base):
|
|||||||
take_profit_percent = Column(Float, nullable=False, default=1)
|
take_profit_percent = Column(Float, nullable=False, default=1)
|
||||||
stop_loss_percent = Column(Float, nullable=False, default=1)
|
stop_loss_percent = Column(Float, nullable=False, default=1)
|
||||||
commission_fee = Column(String, nullable=False, default="Yes_commission_fee")
|
commission_fee = Column(String, nullable=False, default="Yes_commission_fee")
|
||||||
|
commission_place = Column(String, nullable=False, default="Commission_for_qty")
|
||||||
|
|
||||||
user = relationship("User", back_populates="user_risk_management")
|
user = relationship("User", back_populates="user_risk_management")
|
||||||
|
|
||||||
@@ -156,6 +157,9 @@ class UserDeals(Base):
|
|||||||
take_profit_percent = Column(Integer, nullable=True)
|
take_profit_percent = Column(Integer, nullable=True)
|
||||||
stop_loss_percent = Column(Integer, nullable=True)
|
stop_loss_percent = Column(Integer, nullable=True)
|
||||||
trigger_price = Column(Float, nullable=True)
|
trigger_price = Column(Float, nullable=True)
|
||||||
|
current_series = Column(Integer, nullable=True)
|
||||||
|
commission_fee = Column(String, nullable=True)
|
||||||
|
commission_place = Column(String, nullable=True)
|
||||||
|
|
||||||
user = relationship("User", back_populates="user_deals")
|
user = relationship("User", back_populates="user_deals")
|
||||||
|
|
||||||
|
|||||||
@@ -629,6 +629,7 @@ async def create_user_risk_management(tg_id: int) -> None:
|
|||||||
take_profit_percent=1.0,
|
take_profit_percent=1.0,
|
||||||
stop_loss_percent=1.0,
|
stop_loss_percent=1.0,
|
||||||
commission_fee="Yes_commission_fee",
|
commission_fee="Yes_commission_fee",
|
||||||
|
commission_place="Commission_for_qty"
|
||||||
)
|
)
|
||||||
session.add(user_risk_management)
|
session.add(user_risk_management)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
@@ -788,6 +789,47 @@ async def set_commission_fee(tg_id: int, commission_fee: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
async def set_commission_place(tg_id: int, commission_place: str) -> bool:
|
||||||
|
"""
|
||||||
|
Set commission place for a user in the database.
|
||||||
|
:param tg_id: Telegram user ID
|
||||||
|
:param commission_place: Commission place
|
||||||
|
:return: True if successful, False otherwise
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
async with async_session() as session:
|
||||||
|
result = await session.execute(
|
||||||
|
select(User)
|
||||||
|
.options(joinedload(User.user_risk_management))
|
||||||
|
.filter_by(tg_id=tg_id)
|
||||||
|
)
|
||||||
|
user = result.scalars().first()
|
||||||
|
|
||||||
|
if user:
|
||||||
|
if user.user_risk_management:
|
||||||
|
# Updating existing record
|
||||||
|
user.user_risk_management.commission_place = commission_place
|
||||||
|
else:
|
||||||
|
# Creating new record
|
||||||
|
user_risk_management = UserRiskManagement(
|
||||||
|
commission_place=commission_place,
|
||||||
|
user=user,
|
||||||
|
)
|
||||||
|
session.add(user_risk_management)
|
||||||
|
|
||||||
|
await session.commit()
|
||||||
|
logger.info("User commission place updated for user: %s", tg_id)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error("User not found with tg_id: %s", tg_id)
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
"Error adding/updating user commission place for user %s: %s", tg_id, e
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# USER CONDITIONAL SETTINGS
|
# USER CONDITIONAL SETTINGS
|
||||||
|
|
||||||
|
|
||||||
@@ -935,6 +977,7 @@ async def set_user_deal(
|
|||||||
tg_id: int,
|
tg_id: int,
|
||||||
symbol: str,
|
symbol: str,
|
||||||
current_step: int,
|
current_step: int,
|
||||||
|
current_series: int,
|
||||||
trade_mode: str,
|
trade_mode: str,
|
||||||
side_mode: str,
|
side_mode: str,
|
||||||
margin_type: str,
|
margin_type: str,
|
||||||
@@ -945,13 +988,16 @@ async def set_user_deal(
|
|||||||
max_bets_in_series: int,
|
max_bets_in_series: int,
|
||||||
take_profit_percent: int,
|
take_profit_percent: int,
|
||||||
stop_loss_percent: int,
|
stop_loss_percent: int,
|
||||||
base_quantity: float
|
base_quantity: float,
|
||||||
|
commission_fee: str,
|
||||||
|
commission_place: str
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Set the user deal in the database.
|
Set the user deal in the database.
|
||||||
:param tg_id: Telegram user ID
|
:param tg_id: Telegram user ID
|
||||||
:param symbol: Symbol
|
:param symbol: Symbol
|
||||||
:param current_step: Current step
|
:param current_step: Current step
|
||||||
|
:param current_series: Current series
|
||||||
:param trade_mode: Trade mode
|
:param trade_mode: Trade mode
|
||||||
:param side_mode: Side mode
|
:param side_mode: Side mode
|
||||||
:param margin_type: Margin type
|
:param margin_type: Margin type
|
||||||
@@ -963,6 +1009,8 @@ async def set_user_deal(
|
|||||||
:param take_profit_percent: Take profit percent
|
:param take_profit_percent: Take profit percent
|
||||||
:param stop_loss_percent: Stop loss percent
|
:param stop_loss_percent: Stop loss percent
|
||||||
:param base_quantity: Base quantity
|
:param base_quantity: Base quantity
|
||||||
|
:param commission_fee: Commission fee
|
||||||
|
:param commission_place: Commission place
|
||||||
:return: bool
|
:return: bool
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@@ -981,6 +1029,7 @@ async def set_user_deal(
|
|||||||
if deal:
|
if deal:
|
||||||
# Updating existing record
|
# Updating existing record
|
||||||
deal.current_step = current_step
|
deal.current_step = current_step
|
||||||
|
deal.current_series = current_series
|
||||||
deal.trade_mode = trade_mode
|
deal.trade_mode = trade_mode
|
||||||
deal.side_mode = side_mode
|
deal.side_mode = side_mode
|
||||||
deal.margin_type = margin_type
|
deal.margin_type = margin_type
|
||||||
@@ -992,12 +1041,15 @@ async def set_user_deal(
|
|||||||
deal.take_profit_percent = take_profit_percent
|
deal.take_profit_percent = take_profit_percent
|
||||||
deal.stop_loss_percent = stop_loss_percent
|
deal.stop_loss_percent = stop_loss_percent
|
||||||
deal.base_quantity = base_quantity
|
deal.base_quantity = base_quantity
|
||||||
|
deal.commission_fee = commission_fee
|
||||||
|
deal.commission_place = commission_place
|
||||||
else:
|
else:
|
||||||
# Creating new record
|
# Creating new record
|
||||||
new_deal = UserDeals(
|
new_deal = UserDeals(
|
||||||
user=user,
|
user=user,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
current_step=current_step,
|
current_step=current_step,
|
||||||
|
current_series=current_series,
|
||||||
trade_mode=trade_mode,
|
trade_mode=trade_mode,
|
||||||
side_mode=side_mode,
|
side_mode=side_mode,
|
||||||
margin_type=margin_type,
|
margin_type=margin_type,
|
||||||
@@ -1008,7 +1060,9 @@ async def set_user_deal(
|
|||||||
max_bets_in_series=max_bets_in_series,
|
max_bets_in_series=max_bets_in_series,
|
||||||
take_profit_percent=take_profit_percent,
|
take_profit_percent=take_profit_percent,
|
||||||
stop_loss_percent=stop_loss_percent,
|
stop_loss_percent=stop_loss_percent,
|
||||||
base_quantity=base_quantity
|
base_quantity=base_quantity,
|
||||||
|
commission_fee=commission_fee,
|
||||||
|
commission_place=commission_place
|
||||||
)
|
)
|
||||||
session.add(new_deal)
|
session.add(new_deal)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user