Buy Stop by Points (BuyStopPoints)ΒΆ
Sugar method: Places Buy Stop pending order using point-based offset from current Ask price - breakout entry made easy!
API Information:
- Extension method:
MT5Service.BuyStopPoints(...)(fromMT5ServiceExtensions) - Package: Part of
mt5_term_apilibrary - Region: [09] PENDING HELPERS (BY POINTS)
- Underlying calls:
SymbolInfoTickAsync()+SymbolInfoDoubleAsync()+NormalizePriceAsync()+OrderSendAsync()
Method SignatureΒΆ
public static async Task<OrderSendData> BuyStopPoints(
this MT5Service svc,
string symbol,
double volume,
double priceOffsetPoints,
double? slPoints = null,
double? tpPoints = null,
string? comment = null,
int deviationPoints = 0,
int timeoutSec = 15,
CancellationToken ct = default)
π½ InputΒΆ
| Parameter | Type | Description |
|---|---|---|
svc |
MT5Service |
MT5Service instance (extension method) |
symbol |
string |
Symbol name (e.g., "EURUSD", "XAUUSD") |
volume |
double |
Volume in lots (e.g., 0.01, 0.1, 1.0) |
priceOffsetPoints |
double |
Distance in points above current Ask (always positive) |
slPoints |
double? |
Optional stop-loss distance in points below entry price |
tpPoints |
double? |
Optional take-profit distance in points above entry price |
comment |
string? |
Optional order comment |
deviationPoints |
int |
Maximum price deviation in points (default: 0) |
timeoutSec |
int |
RPC timeout in seconds (default: 15) |
ct |
CancellationToken |
Cancellation token |
β¬οΈ OutputΒΆ
| Type | Description |
|---|---|
Task<OrderSendData> |
Order send result with ticket number and execution details |
Key fields:
Order- Order ticket number (ulong)ReturnedCode- MT5 return code (10009 = success)Comment- Server response comment
π¬ Just the essentialsΒΆ
- What it is: Buy Stop helper - places order ABOVE current Ask using point-based offset. Triggers when price breaks UP.
- Why you need it: Perfect for breakout strategies! No manual price calculation - just specify distance above current price.
- Sanity check: Buy Stop = buy ABOVE current price (chase momentum). Order executes when price rises to trigger level.
π― PurposeΒΆ
Use it for:
- Breakout entries - Buy when price breaks resistance
- Momentum trading - Chase upward price movement
- Trend continuation - Enter long when uptrend confirmed
- Stop and reverse - Exit short + enter long simultaneously
- Triggered limit orders - Activate buy after confirmation
π§ Under the HoodΒΆ
// Step 1: Get current market quote
var tick = await svc.SymbolInfoTickAsync(symbol, deadline, ct);
var point = await svc.SymbolInfoDoubleAsync(symbol, SymbolPoint, deadline, ct);
// Step 2: Calculate entry price (ABOVE Ask for Buy Stop)
var rawPrice = tick.Ask + Math.Abs(priceOffsetPoints) * point;
var price = await svc.NormalizePriceAsync(symbol, rawPrice, timeoutSec, ct);
// Step 3: Calculate SL/TP from entry price
double sl = slPoints.HasValue ? price - slPoints.Value * point : 0;
double tp = tpPoints.HasValue ? price + tpPoints.Value * point : 0;
// Step 4: Build and send pending order request (operationCode: 4 = BuyStop)
var req = BuildPendingRequest(symbol, volume, price, sl, tp, comment, deviationPoints, 4);
return await svc.OrderSendAsync(req, deadline, ct);
What it improves:
- Auto price calculation - converts points to absolute price
- Auto Bid/Ask selection - uses Ask as base for Buy orders
- Auto normalization - price rounded to tick size
- Point-based SL/TP - distances from entry, not from current price
π Usage ExamplesΒΆ
Example 1: Basic Buy Stop 50 Points AboveΒΆ
// Buy Stop 50 points above current Ask
var result = await svc.BuyStopPoints(
symbol: "EURUSD",
volume: 0.01,
priceOffsetPoints: 50);
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"β
Buy Stop placed: Ticket #{result.Order}");
Console.WriteLine($" Will trigger 50 points above current Ask");
}
Example 2: Buy Stop with SL and TPΒΆ
// Buy Stop 30 points above with 20-point SL and 60-point TP
var result = await svc.BuyStopPoints(
symbol: "EURUSD",
volume: 0.05,
priceOffsetPoints: 30,
slPoints: 20, // 20 points below entry
tpPoints: 60); // 60 points above entry
Console.WriteLine($"β
Order #{result.Order}");
Console.WriteLine($" Trigger: 30 points above Ask");
Console.WriteLine($" SL: 20 points, TP: 60 points");
Example 3: Resistance Breakout EntryΒΆ
public async Task PlaceBuyStopAtResistance(
MT5Service svc,
string symbol,
double resistanceLevel)
{
// Get current Ask
var tick = await svc.SymbolInfoTickAsync(symbol);
double point = await svc.GetPointAsync(symbol);
// Calculate offset from current Ask to resistance breakout
double offsetPrice = resistanceLevel - tick.Ask;
double offsetPoints = offsetPrice / point;
if (offsetPoints > 0) // Resistance is above current price
{
// Place Buy Stop just above resistance
var result = await svc.BuyStopPoints(
symbol,
0.01,
priceOffsetPoints: offsetPoints + 10, // 10 points above resistance
slPoints: 50,
tpPoints: 150,
comment: "ResistanceBreakout");
Console.WriteLine($"β
Buy Stop at {resistanceLevel:F5} + 10pts");
Console.WriteLine($" Ticket: #{result.Order}");
}
else
{
Console.WriteLine($"β οΈ Resistance {resistanceLevel:F5} is below current Ask!");
}
}
// Usage:
await PlaceBuyStopAtResistance(svc, "EURUSD", resistanceLevel: 1.0950);
Example 4: ATR-Based BreakoutΒΆ
// Use ATR for dynamic breakout threshold
double atr = 0.0015; // ATR value for EURUSD
double point = await svc.GetPointAsync("EURUSD");
// Convert ATR to points
double atrPoints = atr / point;
// Place Buy Stop at 1x ATR above (strong breakout)
var result = await svc.BuyStopPoints(
"EURUSD",
0.01,
priceOffsetPoints: atrPoints * 1.0,
slPoints: atrPoints * 0.5, // Tight stop (already in momentum)
tpPoints: atrPoints * 2.0); // 2x ATR target
Console.WriteLine($"ATR-based Buy Stop: {atrPoints:F0} points above");
Console.WriteLine($" SL: {atrPoints * 0.5:F0}pts, TP: {atrPoints * 2.0:F0}pts");
Example 5: Multiple Buy Stops (Scaling In)ΒΆ
// Place multiple Buy Stops at different levels
// (scaling into position as momentum builds)
int[] offsets = { 30, 60, 90 };
double[] volumes = { 0.01, 0.02, 0.03 }; // Pyramid up
Console.WriteLine("Placing Buy Stop pyramid:");
for (int i = 0; i < offsets.Length; i++)
{
var result = await svc.BuyStopPoints(
"EURUSD",
volumes[i],
priceOffsetPoints: offsets[i],
slPoints: 40,
tpPoints: 120);
if (result.ReturnedCode == 10009)
{
Console.WriteLine($" β
{offsets[i]}pts above: {volumes[i]} lots - Ticket #{result.Order}");
}
}
// Output:
// Placing Buy Stop pyramid:
// β
30pts above: 0.01 lots - Ticket #12355
// β
60pts above: 0.02 lots - Ticket #12356
// β
90pts above: 0.03 lots - Ticket #12357
Example 6: Round Number BreakoutΒΆ
public async Task PlaceBuyStopAtRoundNumber(
MT5Service svc,
string symbol,
double roundNumber)
{
var tick = await svc.SymbolInfoTickAsync(symbol);
double point = await svc.GetPointAsync(symbol);
// Calculate offset to round number
double offsetPrice = roundNumber - tick.Ask;
double offsetPoints = offsetPrice / point;
if (offsetPoints > 5) // Only if round number is at least 5 points away
{
var result = await svc.BuyStopPoints(
symbol,
0.01,
priceOffsetPoints: offsetPoints,
slPoints: 30,
tpPoints: 100,
comment: $"RoundBreak_{roundNumber}");
Console.WriteLine($"β
Buy Stop at {roundNumber:F5}");
Console.WriteLine($" Offset: {offsetPoints:F0} points above Ask");
}
}
// Usage - wait for break above 1.1000
await PlaceBuyStopAtRoundNumber(svc, "EURUSD", roundNumber: 1.1000);
Example 7: With Order CommentΒΆ
// Buy Stop with strategy identifier
var result = await svc.BuyStopPoints(
symbol: "GBPUSD",
volume: 0.02,
priceOffsetPoints: 50,
slPoints: 30,
tpPoints: 100,
comment: "Breakout_Strategy_v3");
Console.WriteLine($"β
Order #{result.Order} - Comment: Breakout_Strategy_v3");
Example 8: Error HandlingΒΆ
try
{
var result = await svc.BuyStopPoints(
"EURUSD",
0.01,
priceOffsetPoints: 50,
slPoints: 20,
tpPoints: 80);
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"β
Success: Ticket #{result.Order}");
}
else
{
Console.WriteLine($"β Order failed: {result.Comment}");
Console.WriteLine($" Return code: {result.ReturnedCode}");
}
}
catch (Exception ex)
{
Console.WriteLine($"β Exception: {ex.Message}");
}
Example 9: Risk-Based Volume with Buy StopΒΆ
// Calculate volume based on risk
double riskMoney = 100.0;
double slPoints = 30;
double volume = await svc.CalcVolumeForRiskAsync(
"EURUSD",
stopPoints: slPoints,
riskMoney: riskMoney);
// Place Buy Stop with calculated volume
var result = await svc.BuyStopPoints(
"EURUSD",
volume: volume,
priceOffsetPoints: 40,
slPoints: slPoints,
tpPoints: 120);
Console.WriteLine($"β
Risk-based Buy Stop placed:");
Console.WriteLine($" Volume: {volume} lots");
Console.WriteLine($" Risk: ${riskMoney} if SL hit");
Console.WriteLine($" Ticket: #{result.Order}");
Example 10: Calculate Trigger Price Before PlacingΒΆ
var tick = await svc.SymbolInfoTickAsync("EURUSD");
double point = await svc.GetPointAsync("EURUSD");
double offsetPoints = 50;
// Calculate what the trigger price will be
double triggerPrice = tick.Ask + offsetPoints * point;
Console.WriteLine($"Current Ask: {tick.Ask:F5}");
Console.WriteLine($"Trigger will be: {triggerPrice:F5} (50 points above)");
Console.WriteLine($"Placing Buy Stop...");
var result = await svc.BuyStopPoints(
"EURUSD",
0.01,
priceOffsetPoints: offsetPoints,
slPoints: 20,
tpPoints: 80);
Console.WriteLine($"β
Order #{result.Order} - triggers at ~{triggerPrice:F5}");
Console.WriteLine($" Waiting for breakout...");
π Related MethodsΒΆ
π¦ Methods used internally:
SymbolInfoTickAsync()- Gets current Bid/AskSymbolInfoDoubleAsync(SymbolPoint)- Gets point sizeNormalizePriceAsync()- Normalizes trigger priceOrderSendAsync()- Sends pending order request
π¬ Related Sugar methods:
SellStopPoints()- Sell Stop with point-based offsetBuyLimitPoints()- Buy Limit with point-based offsetSellLimitPoints()- Sell Limit with point-based offsetPlacePending()- Generic pending order (requires absolute price)PriceFromOffsetPointsAsync()- Calculate price only (no order placement)
π Alternative approaches:
PlacePending()- More flexible but requires manual price calculationPriceFromOffsetPointsAsync()+PlacePending()- Two-step approach
β οΈ Common PitfallsΒΆ
-
Confusing with Buy Limit:
// β CONFUSION: Buy Limit vs Buy Stop // Buy Limit = BELOW current price (buy cheaper) // Buy Stop = ABOVE current price (chase momentum) // β CORRECT usage: await svc.BuyLimitPoints("EURUSD", 0.01, 50); // 50 pts BELOW (pullback) await svc.BuyStopPoints("EURUSD", 0.01, 50); // 50 pts ABOVE (breakout) -
Negative offset (method handles it):
-
SL/TP direction confusion:
-
Using pips instead of points:
// β WRONG: Confusing pips with points await svc.BuyStopPoints("EURUSD", 0.01, priceOffsetPoints: 5); // For 5-digit broker, this is 0.5 pips, not 5 pips! // β CORRECT: Convert pips to points for 5-digit brokers double pips = 5; double points = pips * 10; // 1 pip = 10 points on 5-digit await svc.BuyStopPoints("EURUSD", 0.01, priceOffsetPoints: points); -
Offset too small (broker minimum distance):
-
Not understanding execution:
π‘ SummaryΒΆ
BuyStopPoints simplifies Buy Stop order placement:
- β Work in points, not absolute prices
- β Auto-calculates trigger price ABOVE Ask
- β SL/TP as point distances from entry
- β Auto-normalizes prices to tick size
- β Perfect for breakout strategies
// Instead of manual calculation:
var tick = await svc.SymbolInfoTickAsync("EURUSD");
double price = tick.Ask + 50 * 0.00001; // β Manual, error-prone
await svc.PlacePending("EURUSD", 0.01, ENUM_ORDER_TYPE.OrderTypeBuyStop, price, ...);
// Use one clean call:
await svc.BuyStopPoints("EURUSD", 0.01, priceOffsetPoints: 50); // β
Clean!
Chase the breakout with confidence! π