Order Management¶
📝 async modify_sl_tp_by_pips(ticket, *, sl_pips=None, tp_pips=None)¶
What it does: Modifies an existing order or position by setting SL/TP in pips relative to the entry price.
Used in:
- Quickly adjusting protective levels without manually converting to price.
- Moving stop loss to breakeven after reaching profit targets.
- Tightening stops as price moves favorably.
- Extending take profit targets in trending markets.
Parameters:
ticket- Order ticket number to modifysl_pips- (Optional) Stop Loss distance in pips from entry pricetp_pips- (Optional) Take Profit distance in pips from entry price
Important notes:
- Pips are calculated from the entry price, not current price
- Pass
Noneto keep existing SL or TP unchanged - Pass
0to remove SL or TP completely - Method automatically handles buy vs sell direction
Related to: order_modify.md, opened_orders_tickets.md
Example 1: Move to breakeven
# Move SL to breakeven (0 pips from entry)
await sugar.modify_sl_tp_by_pips(ticket=123456, sl_pips=0)
Example 2: Tighten both SL and TP
await sugar.modify_sl_tp_by_pips(ticket=123456, sl_pips=20, tp_pips=40)
Example 3: Only modify SL, keep TP unchanged
# Only change SL, TP remains as is
await sugar.modify_sl_tp_by_pips(ticket=123456, sl_pips=30)
Example 4: Progressive stop tightening
# Open position
ticket = await sugar.buy_market("EURUSD", lots=0.1, sl_pips=50, tp_pips=100)
# After 20 pips profit, tighten to 30 pips
await asyncio.sleep(60)
await sugar.modify_sl_tp_by_pips(ticket=ticket, sl_pips=30)
# After 40 pips profit, tighten to 15 pips
await asyncio.sleep(60)
await sugar.modify_sl_tp_by_pips(ticket=ticket, sl_pips=15)
# After 60 pips profit, move to breakeven
await asyncio.sleep(60)
await sugar.modify_sl_tp_by_pips(ticket=ticket, sl_pips=0)
Example 5: Remove TP to let position run
# Remove TP, keep SL
await sugar.modify_sl_tp_by_pips(ticket=123456, sl_pips=20, tp_pips=0)
📝 async modify_sl_tp_by_price(ticket, *, sl_price=None, tp_price=None)¶
What it does: Modifies SL/TP by specifying exact price levels.
Used in:
- Precise SL/TP placement from external calculations or strategy logic.
- Setting stops at specific support/resistance levels.
- Aligning stops with technical indicators (e.g., moving averages).
Parameters:
ticket- Order ticket number to modifysl_price- (Optional) Exact Stop Loss price leveltp_price- (Optional) Exact Take Profit price level
Important notes:
- Prices must be valid for the order direction (SL below entry for buy, above for sell)
- Pass
Noneto keep existing SL or TP unchanged - Pass
0to remove SL or TP
Related to: order_modify.md
Example 1: Set to specific levels
await sugar.modify_sl_tp_by_price(ticket=123456, sl_price=1.0925, tp_price=1.1010)
Example 2: Set SL to previous day's low
# Get yesterday's bars
bars = await sugar.bars("EURUSD", timeframe="D1", count=2)
yesterday_low = bars[-2]["low"]
# Set SL at yesterday's low
await sugar.modify_sl_tp_by_price(ticket=ticket, sl_price=yesterday_low)
Example 3: Set SL at moving average
# Calculate 20 EMA
bars = await sugar.bars("EURUSD", timeframe="H1", count=20)
closes = [b["close"] for b in bars]
ema_20 = sum(closes) / len(closes) # Simplified
# Set SL at EMA
await sugar.modify_sl_tp_by_price(ticket=ticket, sl_price=ema_20)
❌ async close(ticket)¶
What it does: Closes a specific order or position by ticket.
Used in:
- Manual or automated close actions triggered by strategy conditions.
- Taking profit at predetermined levels.
- Emergency exits based on news or market conditions.
Parameters:
ticket- Order ticket number to close
Important notes:
- Closes the entire position
- For partial closes, use
close_partial() - Works for both market positions and pending orders (pending orders are deleted)
Related to: order_close_delete.md
Example 1: Simple close
await sugar.close(123456)
Example 2: Close on signal reversal
# Monitor for exit signal
while True:
if exit_signal_detected():
logger.info("Exit signal - closing position")
await sugar.close(ticket)
break
await asyncio.sleep(5)
Example 3: Time-based exit
import asyncio
# Open position
ticket = await sugar.buy_market("EURUSD", lots=0.1)
# Close after 1 hour
await asyncio.sleep(3600)
await sugar.close(ticket)
✂️ async close_partial(ticket, lots)¶
What it does: Partially closes a position by the specified lot size.
Used in:
- Taking partial profit or reducing exposure while keeping trade open.
- Scaling out of positions as profit targets are reached.
- Risk reduction while maintaining market exposure.
Parameters:
ticket- Order ticket numberlots- Amount of lots to close (must be less than position size)
Important notes:
- Remaining position keeps the same ticket number (in MT4)
- Closed portion creates a new history entry
- Useful for pyramiding strategies
Related to: order_close_delete.md
Example 1: Close half the position
await sugar.close_partial(ticket=123456, lots=0.05)
Example 2: Scale out at multiple profit levels
# Open 0.3 lot position
ticket = await sugar.buy_market("EURUSD", lots=0.3, sl_pips=30)
# Take 1/3 profit at 20 pips
await sugar.wait_price("EURUSD", target=entry + 0.0020, direction=">=")
await sugar.close_partial(ticket=ticket, lots=0.1)
# Take another 1/3 at 40 pips
await sugar.wait_price("EURUSD", target=entry + 0.0040, direction=">=")
await sugar.close_partial(ticket=ticket, lots=0.1)
# Let final 1/3 run with trailing stop
await sugar.set_trailing_stop(ticket=ticket, distance_pips=20)
Example 3: Reduce exposure on high volatility
# Monitor spread
spread = await sugar.spread_pips("EURUSD")
if spread > 5.0:
# High spread - reduce exposure by 50%
logger.warning("High spread - reducing position")
await sugar.close_partial(ticket=ticket, lots=0.05)
🔁 async close_by(ticket_a, ticket_b)¶
What it does: Closes position ticket_a by opposite position ticket_b (Close By).
Used in:
- Reducing commission and swap by netting opposite trades.
- Hedging strategies where you want to close offsetting positions.
- Avoiding spread costs when closing opposite positions.
Parameters:
ticket_a- First position ticketticket_b- Opposite position ticket (must be opposite direction on same symbol)
Important notes:
- Both positions must be on the same symbol
- Positions must be opposite directions (one buy, one sell)
- Saves spread costs compared to closing each separately
- If positions are different sizes, smaller one closes completely, larger one is reduced
Related to: order_close_by.md
Example 1: Close hedged positions
await sugar.close_by(ticket_a=111111, ticket_b=222222)
Example 2: Hedge and close strategy
# Open long position
long_ticket = await sugar.buy_market("EURUSD", lots=0.1)
# Market turns against us - hedge with short
short_ticket = await sugar.sell_market("EURUSD", lots=0.1)
# Wait for favorable conditions
await asyncio.sleep(300)
# Close both positions by netting
await sugar.close_by(ticket_a=long_ticket, ticket_b=short_ticket)
🧹 async close_all(*, symbol=None, magic=None, only_profit=None)¶
What it does: Closes multiple open positions filtered by symbol/magic.
If only_profit is True/False, closes only profitable or losing positions.
Used in:
- Emergency flattening, portfolio resets, strategy exits.
- End-of-day position closure.
- Closing all positions before major news events.
Parameters:
symbol- (Optional) Filter by specific symbolmagic- (Optional) Filter by magic numberonly_profit- (Optional)True=only profitable,False=only losing,None=all
Important notes:
- If no filters provided, closes all positions in the account
- Use filters carefully to avoid closing unintended positions
- Pending orders are not affected (use
cancel_pendings()for those)
Related to: opened_orders.md, order_close_delete.md
Example 1: Close all profitable positions for specific symbol
# Close all profitable EURUSD with given magic
await sugar.close_all(symbol="EURUSD", magic=1001, only_profit=True)
Example 2: Emergency flatten all positions
# Major news event - close everything
logger.warning("Major news event - closing all positions")
await sugar.close_all()
Example 3: End of day routine
# Close all positions at end of trading day
if is_end_of_day():
await sugar.close_all(magic=1001)
logger.info("All positions closed for end of day")
Example 4: Close only losing positions
# Cut all losses before weekend
if is_friday_evening():
await sugar.close_all(only_profit=False)
logger.info("All losing positions closed before weekend")
🗑️ async cancel_pendings(*, symbol=None, magic=None)¶
What it does: Cancels pending orders filtered by symbol and magic.
Used in:
- Cleaning up hanging limit/stop orders before context change.
- Removing unfilled orders after strategy change.
- Canceling breakout orders when range-bound conditions detected.
Parameters:
symbol- (Optional) Filter by specific symbolmagic- (Optional) Filter by magic number
Important notes:
- Only affects pending orders (buy/sell limit/stop)
- Does not close market positions (use
close_all()for that) - If no filters provided, cancels all pending orders
Related to: order_close_delete.md
Example 1: Cancel symbol-specific pendings
await sugar.cancel_pendings(symbol="GBPUSD", magic=2002)
Example 2: Clean up before strategy switch
# Switching from breakout to range strategy
logger.info("Switching strategy - canceling all pending orders")
await sugar.cancel_pendings(magic=1001)
# Now place new range-bound orders
await sugar.buy_limit("EURUSD", lots=0.1, price=1.0900)
await sugar.sell_limit("EURUSD", lots=0.1, price=1.1100)
Example 3: Cancel unfilled orders after timeout
# Place limit orders
tickets = []
for price in [1.0900, 1.0850, 1.0800]:
ticket = await sugar.buy_limit("EURUSD", lots=0.1, price=price)
tickets.append(ticket)
# Wait 1 hour
await asyncio.sleep(3600)
# Cancel any unfilled orders
await sugar.cancel_pendings(symbol="EURUSD", magic=1001)