π Buy at Market with SL/TP in Pips (BuyMarketWithPips)ΒΆ
Sugar method: Opens a BUY position with Stop Loss and Take Profit specified as distances in points (not price! - and despite the method name, not pips). More intuitive than price-based methods - you specify risk/reward as distances and it calculates exact prices automatically.
API Information:
- Method:
sugar.BuyMarketWithPips(symbol, volume, stopLossPips, takeProfitPips) - Package:
mt5(MT5Sugar) - Underlying calls:
CalculateSLTP(),BuyMarketWithSLTP() - Timeout: 30 seconds for the order (
BuyMarketWithSLTP); before thatCalculateSLTPqueriesGetSymbolInfo(10 s) andGetAsk(3 s)
π Method SignatureΒΆ
func (s *MT5Sugar) BuyMarketWithPips(
symbol string,
volume float64,
stopLossPips float64,
takeProfitPips float64,
) (uint64, error)
π½ InputΒΆ
| Parameter | Type | Description |
|---|---|---|
symbol |
string |
Trading symbol (e.g., "EURUSD", "GBPUSD", "XAUUSD") |
volume |
float64 |
Lot size (e.g., 0.1, 0.01, 1.0) |
stopLossPips |
float64 |
Stop Loss distance in POINTS from entry despite the name (e.g., 500 = 50 pips on 5-digit EURUSD) |
takeProfitPips |
float64 |
Take Profit distance in POINTS from entry despite the name (e.g., 1000 = 100 pips on 5-digit EURUSD) |
Important: SL/TP are distances in points (multiplied by the symbol's Point: 0.00001 on 5-digit EURUSD, 0.001 on 3-digit USDJPY), not price and not pips! On 5- and 3-digit symbols 10 points = 1 pip, so pass 500 for a 50-pip stop.
β¬οΈ OutputΒΆ
| Return | Type | Description |
|---|---|---|
ticket |
uint64 |
Order ticket (result.Order); for a market order MT5 uses it as the position ticket (use for tracking/closing) |
error |
error |
The CalculateSLTP error (symbol/price query failed), order rejected, code: N, comment: ... if the return code is not 10009 (TRADE_RETCODE_DONE), or BuyMarketWithSLTP failed: ... |
π¬ Just the EssentialsΒΆ
- What it is: Opens BUY at market with SL/TP specified as point distances instead of price.
- Why you need it: Much easier than calculating SL/TP prices manually. Just specify "500 points stop, 1000 points profit" and you're done.
- Sanity check: If EURUSD (5 digits) Ask is 1.08500, SL=500, TP=1000 (points) β SL will be at 1.08000, TP at 1.09500.
π― PurposeΒΆ
Use it for intuitive market orders:
- Think in distances, not prices - More natural for traders
- Consistent R:R ratios - Easy to maintain 1:2 or 1:3 R:R
- Quick market entries - Specify SL/TP in one line
- Auto price calculation - No manual math needed
- Works across all symbols - Uses each symbol's
Pointsize
π’ How It WorksΒΆ
Entry Price = Current ASK
Stop Loss = ASK - (stopLossPips Γ point)
Take Profit = ASK + (takeProfitPips Γ point)
Where:
point = symbol's minimal price change (e.g., 0.00001 for EURUSD)
SL and TP are rounded to the symbol's digits.
Example:
EURUSD ASK = 1.08500
SL = 500 points β 1.08500 - (500 Γ 0.00001) = 1.08500 - 0.00500 = 1.08000
TP = 1000 points β 1.08500 + (1000 Γ 0.00001) = 1.08500 + 0.01000 = 1.09500
BUY at 1.08500, SL at 1.08000, TP at 1.09500
π§© Notes & TipsΒΆ
- Points, not price! - 500 means "500 points" (= 50 pips on 5-digit EURUSD), not "price 500.00"
- For BUY - SL is BELOW entry, TP is ABOVE entry
- Current market price - Uses current ASK for entry
- Auto-calculation - Handles different symbol digits automatically
- Do NOT pass 0 to skip SL/TP - a 0 distance puts SL/TP exactly at the entry (Ask) price, which the broker will normally reject; use
BuyMarket()to open without SL/TP - Rounding - SL/TP prices are rounded to the symbol's
Digits; the volume is sent as given (not normalized toVolumeStep) - Order timeout 30 s - An order that times out on the client side may still have been executed: check
GetOpenPositions()before retrying - Market execution - Order fills at current market price
- Slippage possible - Actual entry might differ slightly; SL/TP are calculated from the Ask read before the order is sent
π§ Under the HoodΒΆ
func (s *MT5Sugar) BuyMarketWithPips(symbol string, volume, stopLossPips, takeProfitPips float64) (uint64, error) {
// Calculate SL/TP prices
sl, tp, err := s.CalculateSLTP(symbol, "BUY", 0, stopLossPips, takeProfitPips)
if err != nil {
return 0, err
}
// Use existing BuyMarketWithSLTP
return s.BuyMarketWithSLTP(symbol, volume, sl, tp)
}
What it improves:
- β Distance-based input - Think in points, not prices
- β Auto price calculation - No manual math
- β
Symbol-aware - Uses the symbol's
Point(5-digit vs 3-digit quotes) - β One method call - Instead of three separate steps
π Low-Level AlternativeΒΆ
WITHOUT sugar (manual calculation):
// Get symbol info
info, _ := sugar.GetSymbolInfo("EURUSD")
// Get current ASK
ask, _ := sugar.GetAsk("EURUSD")
// Calculate SL/TP manually (and round to the symbol's digits)
scale := math.Pow(10, float64(info.Digits))
sl := math.Round((ask-500*info.Point)*scale) / scale // 500 points below
tp := math.Round((ask+1000*info.Point)*scale) / scale // 1000 points above
// Open position
ticket, _ := sugar.BuyMarketWithSLTP("EURUSD", 0.1, sl, tp)
WITH sugar:
Benefits:
- β One line vs 5 lines
- β No point calculation needed
- β No symbol info lookup
- β Clearer intent - "500 and 1000 points" is obvious
π Usage ExamplesΒΆ
1) Basic market BUY with 1:2 R:RΒΆ
// Open BUY: 0.1 lots, 500 point SL, 1000 point TP (1:2 R:R)
ticket, err := sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)
if err != nil {
fmt.Printf("Order failed: %v\n", err)
return
}
fmt.Printf("β
BUY order #%d opened\n", ticket)
fmt.Printf(" SL: 500 points, TP: 1000 points (1:2 R:R)\n")
2) Complete risk-managed tradeΒΆ
symbol := "EURUSD"
riskPercent := 2.0
stopLossPips := 500.0
takeProfitPips := 1000.0
// Step 1: Calculate position size based on risk
lotSize, err := sugar.CalculatePositionSize(symbol, riskPercent, stopLossPips)
if err != nil {
fmt.Printf("Position size calculation failed: %v\n", err)
return
}
// Step 2: Validate we can open
canOpen, reason, _ := sugar.CanOpenPosition(symbol, lotSize)
if !canOpen {
fmt.Printf("Cannot open: %s\n", reason)
return
}
// Step 3: Open position with calculated size
ticket, err := sugar.BuyMarketWithPips(symbol, lotSize, stopLossPips, takeProfitPips)
if err != nil {
fmt.Printf("Order failed: %v\n", err)
return
}
fmt.Printf("β
Trade opened successfully!\n")
fmt.Printf(" Ticket: #%d\n", ticket)
fmt.Printf(" Lot size: %.2f (risk: %.1f%%)\n", lotSize, riskPercent)
fmt.Printf(" Stop Loss: %.0f points\n", stopLossPips)
fmt.Printf(" Take Profit: %.0f points\n", takeProfitPips)
3) Different risk/reward ratiosΒΆ
symbol := "EURUSD"
volume := 0.1
// Conservative: 1:1.5 R:R
ticket1, _ := sugar.BuyMarketWithPips(symbol, volume, 500, 750)
fmt.Println("Conservative: 500 point SL, 750 point TP (1:1.5)")
// Moderate: 1:2 R:R (most common)
ticket2, _ := sugar.BuyMarketWithPips(symbol, volume, 500, 1000)
fmt.Println("Moderate: 500 point SL, 1000 point TP (1:2)")
// Aggressive: 1:3 R:R
ticket3, _ := sugar.BuyMarketWithPips(symbol, volume, 500, 1500)
fmt.Println("Aggressive: 500 point SL, 1500 point TP (1:3)")
// Output:
// Conservative: 500 point SL, 750 point TP (1:1.5)
// Moderate: 500 point SL, 1000 point TP (1:2)
// Aggressive: 500 point SL, 1500 point TP (1:3)
4) Tight stop vs wide stopΒΆ
symbol := "GBPUSD"
volume := 0.1
// Scalping: tight stop, tight target
ticket1, _ := sugar.BuyMarketWithPips(symbol, volume, 150, 300)
fmt.Println("Scalp: 150 point SL, 300 point TP")
// Day trading: normal stop
ticket2, _ := sugar.BuyMarketWithPips(symbol, volume, 500, 1000)
fmt.Println("Day: 500 point SL, 1000 point TP")
// Swing trading: wide stop
ticket3, _ := sugar.BuyMarketWithPips(symbol, volume, 1500, 3000)
fmt.Println("Swing: 1500 point SL, 3000 point TP")
5) Show entry, SL, TP pricesΒΆ
symbol := "EURUSD"
volume := 0.1
slPips := 500.0
tpPips := 1000.0
// Get current price
ask, _ := sugar.GetAsk(symbol)
// Calculate what SL/TP prices will be
sl, tp, _ := sugar.CalculateSLTP(symbol, "BUY", ask, slPips, tpPips)
fmt.Printf("βββββββββββββββββββββββββββββββββββββββ\n")
fmt.Printf(" BUY ORDER PREVIEW\n")
fmt.Printf("βββββββββββββββββββββββββββββββββββββββ\n")
fmt.Printf("Symbol: %s\n", symbol)
fmt.Printf("Entry (ASK): %.5f\n", ask)
fmt.Printf("Stop Loss: %.5f (-%.0f points)\n", sl, slPips)
fmt.Printf("Take Profit: %.5f (+%.0f points)\n", tp, tpPips)
fmt.Printf("Risk/Reward: 1:%.1f\n", tpPips/slPips)
fmt.Printf("βββββββββββββββββββββββββββββββββββββββ\n")
// Open position
ticket, _ := sugar.BuyMarketWithPips(symbol, volume, slPips, tpPips)
fmt.Printf("β
Order #%d opened\n", ticket)
// Output:
// βββββββββββββββββββββββββββββββββββββββ
// BUY ORDER PREVIEW
// βββββββββββββββββββββββββββββββββββββββ
// Symbol: EURUSD
// Entry (ASK): 1.08500
// Stop Loss: 1.08000 (-500 points)
// Take Profit: 1.09500 (+1000 points)
// Risk/Reward: 1:2.0
// βββββββββββββββββββββββββββββββββββββββ
// β
Order #44444 opened
6) Multiple positions with same parametersΒΆ
symbols := []string{"EURUSD", "GBPUSD", "USDJPY"}
volume := 0.1
slPips := 500.0
tpPips := 1000.0
fmt.Println("Opening BUY positions on multiple pairs:")
fmt.Println("βββββββββββββββββββββββββββββββββββββββββ")
for _, symbol := range symbols {
ticket, err := sugar.BuyMarketWithPips(symbol, volume, slPips, tpPips)
if err != nil {
fmt.Printf("β %s: Failed - %v\n", symbol, err)
continue
}
fmt.Printf("β
%s: Ticket #%d\n", symbol, ticket)
}
// Output:
// Opening BUY positions on multiple pairs:
// βββββββββββββββββββββββββββββββββββββββββ
// β
EURUSD: Ticket #44444
// β
GBPUSD: Ticket #44445
// β
USDJPY: Ticket #44446
7) Open without SL/TP, then set SLΒΆ
// Open without SL/TP: use BuyMarket.
// (BuyMarketWithPips(..., 0, 0) would NOT do this - it would send SL = TP = Ask.)
ticket, err := sugar.BuyMarket("EURUSD", 0.1)
if err != nil {
fmt.Printf("Order failed: %v\n", err)
return
}
fmt.Println("β οΈ Order opened WITHOUT Stop Loss or Take Profit")
fmt.Printf(" Ticket: #%d\n", ticket)
fmt.Println(" π¨ DANGEROUS - Manually set SL immediately!")
// Immediately set stop loss
sl, _, _ := sugar.CalculateSLTP("EURUSD", "BUY", 0, 500, 0)
sugar.ModifyPositionSL(ticket, sl)
fmt.Println("β
Stop Loss set to 500 points")
8) Move SL to breakeven after profitΒΆ
symbol := "EURUSD"
volume := 0.1
slPips := 500.0
tpPips := 1000.0
// Open position
ticket, _ := sugar.BuyMarketWithPips(symbol, volume, slPips, tpPips)
fmt.Printf("Position #%d opened\n", ticket)
// Monitor and trail
time.Sleep(10 * time.Second) // Wait for price to move
// Get current position (an error if it is no longer open, e.g. SL/TP hit)
pos, err := sugar.GetPositionByTicket(ticket)
if err != nil {
fmt.Printf("Position not open: %v\n", err)
return
}
if pos.Profit > 0 {
// Price moved in our favor - move SL to breakeven
fmt.Println("β
Position in profit - moving SL to breakeven")
// Calculate breakeven price
info, _ := sugar.GetSymbolInfo(symbol)
breakeven := pos.PriceOpen + (50 * info.Point) // BE + 50 points
sugar.ModifyPositionSL(ticket, breakeven)
fmt.Printf(" SL moved to %.5f (breakeven + 50 points)\n", breakeven)
}
9) Partial close at TP1, let rest run to TP2ΒΆ
symbol := "EURUSD"
volume := 0.2 // Total position size
slPips := 500.0
tp1Pips := 500.0 // First target
tp2Pips := 1500.0 // Final target
// Open position
ticket, _ := sugar.BuyMarketWithPips(symbol, volume, slPips, tp1Pips)
fmt.Printf("Position #%d opened: %.2f lots\n", ticket, volume)
fmt.Printf(" SL: %.0f points\n", slPips)
fmt.Printf(" TP1: %.0f points (will close 50%%)\n", tp1Pips)
fmt.Printf(" TP2: %.0f points (remaining 50%%)\n", tp2Pips)
// ... Later, when price reaches TP1 ...
// Close half position
halfVolume := volume / 2
err := sugar.ClosePositionPartial(ticket, halfVolume)
if err == nil {
fmt.Println("β
Closed 50% at TP1")
// Move SL to breakeven on remaining position
pos, _ := sugar.GetPositionByTicket(ticket)
sugar.ModifyPositionSL(ticket, pos.PriceOpen)
// Set new TP to TP2
_, tp2, _ := sugar.CalculateSLTP(symbol, "BUY", 0, 0, tp2Pips)
sugar.ModifyPositionTP(ticket, tp2)
fmt.Println("β
SL moved to breakeven, TP set to TP2")
}
10) Validate symbol before tradingΒΆ
symbol := "XAUUSD"
volume := 0.1
slPips := 3000.0 // Gold needs wider stops
tpPips := 6000.0
// Check symbol availability
available, err := sugar.IsSymbolAvailable(symbol)
if err != nil || !available {
fmt.Printf("β %s is not available for trading\n", symbol)
return
}
// Get symbol info to show specifications
info, _ := sugar.GetSymbolInfo(symbol)
fmt.Printf("Symbol: %s\n", info.Name)
fmt.Printf(" Spread: %d points\n", info.Spread)
fmt.Printf(" Min volume: %.2f\n", info.VolumeMin)
fmt.Printf(" Max volume: %.2f\n", info.VolumeMax)
// Validate volume
if volume < info.VolumeMin {
fmt.Printf("β Volume %.2f below minimum %.2f\n", volume, info.VolumeMin)
return
}
// Open position
ticket, err := sugar.BuyMarketWithPips(symbol, volume, slPips, tpPips)
if err != nil {
fmt.Printf("β Order failed: %v\n", err)
return
}
fmt.Printf("β
%s BUY #%d opened\n", symbol, ticket)
π Related MethodsΒΆ
π¬ Complementary sugar methods:
SellMarketWithPips()- SELL version of this methodCalculatePositionSize()- Calculate lot size based on risk βCanOpenPosition()- Validate before trading βCalculateSLTP()- Calculate SL/TP prices from point distancesBuyMarketWithSLTP()- BUY with prices instead of distancesModifyPositionSLTP()- Change SL/TP after opening
π¦ Methods used internally:
CalculateSLTP()- Converts point distances to pricesBuyMarketWithSLTP()- Executes the actual order
Recommended workflow:
// 1. Calculate position size
lotSize, _ := sugar.CalculatePositionSize("EURUSD", 2.0, 500)
// 2. Validate
canOpen, _, _ := sugar.CanOpenPosition("EURUSD", lotSize)
if !canOpen { return }
// 3. Trade
ticket, _ := sugar.BuyMarketWithPips("EURUSD", lotSize, 500, 1000)
β οΈ Common PitfallsΒΆ
1) Confusing distance with priceΒΆ
// β WRONG - passing price as stop loss
slPrice := 1.08000
sugar.BuyMarketWithPips("EURUSD", 0.1, slPrice, 1000) // WRONG!
// β WRONG - passing pips: 50 is read as 50 POINTS (= 5 pips)
sugar.BuyMarketWithPips("EURUSD", 0.1, 50, 100)
// β
CORRECT - stop loss distance in points (500 points = 50 pips on EURUSD)
slPips := 500.0
sugar.BuyMarketWithPips("EURUSD", 0.1, slPips, 1000)
2) Using same distances for different symbolsΒΆ
// β WRONG - 500 points SL works for EURUSD but not XAUUSD
sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000) // OK
sugar.BuyMarketWithPips("XAUUSD", 0.1, 500, 1000) // Too tight!
// β
CORRECT - adjust distances based on symbol volatility
sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000) // Forex: 500 points
sugar.BuyMarketWithPips("XAUUSD", 0.1, 3000, 6000) // Gold: 3000 points
3) Not using risk-based position sizingΒΆ
// β WRONG - fixed lot size (ignores balance)
sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)
// β
CORRECT - calculate lot size based on risk
lotSize, _ := sugar.CalculatePositionSize("EURUSD", 2.0, 500)
sugar.BuyMarketWithPips("EURUSD", lotSize, 500, 1000)
4) Not validating before tradingΒΆ
// β WRONG - trading without validation
ticket, _ := sugar.BuyMarketWithPips("EURUSD", 10.0, 500, 1000) // Might fail!
// β
CORRECT - validate first
canOpen, reason, _ := sugar.CanOpenPosition("EURUSD", 10.0)
if !canOpen {
fmt.Println("Cannot trade:", reason)
return
}
sugar.BuyMarketWithPips("EURUSD", 10.0, 500, 1000)
5) Ignoring errorsΒΆ
// β WRONG - ignoring errors
ticket, _ := sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)
fmt.Printf("Order #%d opened\n", ticket) // Might be 0!
// β
CORRECT - check errors
ticket, err := sugar.BuyMarketWithPips("EURUSD", 0.1, 500, 1000)
if err != nil {
fmt.Printf("Order failed: %v\n", err)
return
}
fmt.Printf("Order #%d opened\n", ticket)
6) Unrealistic stops for the symbolΒΆ
// β WRONG - 50 point SL on volatile pair
sugar.BuyMarketWithPips("GBPJPY", 0.1, 50, 100) // Will get stopped immediately!
// β
CORRECT - use appropriate stop distance
sugar.BuyMarketWithPips("GBPJPY", 0.1, 800, 1600) // Realistic for volatility
π Pro TipsΒΆ
- Use 1:2 R:R minimum - Never trade with less than 1:2 risk/reward
- Adjust distances to symbol - Volatile pairs need wider stops
- Always calculate lot size - Use
CalculatePositionSize()first - Validate before trading - Use
CanOpenPosition() - Monitor spread - High spread = wider stops needed
- Think in distances, not price - This method makes it natural (distances are in points)
- Set realistic stops - Don't use super tight stops that always hit
See also: SellMarketWithPips.md, CalculatePositionSize.md, CanOpenPosition.md