β³ Wait For Valid Price (WaitForPrice)ΒΆ
Sugar method: Waits until symbol has valid price data (useful after connection or market open).
API Information:
- Method:
sugar.WaitForPrice(symbol, timeout) - Timeout: Custom (you specify)
- Returns:
*PriceInfowhen valid price received
π Method SignatureΒΆ
π¬ Just the EssentialsΒΆ
- What it is: Blocks until symbol has valid price (BID > 0 and ASK > 0) or timeout expires.
- Why you need it: After connection or during market open, prices might not be available yet.
- Sanity check: Returns first valid PriceInfo or error on timeout.
π― When to UseΒΆ
β After connection - Wait for first tick after connecting
β Market open - Wait for market to start publishing prices
β Symbol switch - Ensure new symbol is ready
β Weekend/gap handling - Wait for market to resume
π Usage ExamplesΒΆ
1) Basic usage - wait after connectionΒΆ
sugar, _ := mt5.NewMT5Sugar(591129415, "password", "mt5.mrpc.pro:443")
sugar.QuickConnect("FxPro-MT5 Demo")
// Wait for price to be available
symbol := "EURUSD"
priceInfo, err := sugar.WaitForPrice(symbol, 10*time.Second)
if err != nil {
fmt.Printf("Timeout waiting for price: %v\n", err)
return
}
fmt.Printf("β
%s price ready!\n", symbol)
fmt.Printf(" BID: %.5f\n", priceInfo.Bid)
fmt.Printf(" ASK: %.5f\n", priceInfo.Ask)
2) Robust connection sequenceΒΆ
func ConnectAndWaitForPrice(login uint64, password, server, cluster, symbol string) error {
// Step 1: Create Sugar
sugar, err := mt5.NewMT5Sugar(login, password, server)
if err != nil {
return fmt.Errorf("failed to create Sugar: %w", err)
}
// Step 2: Connect
fmt.Println("π Connecting to MT5...")
err = sugar.QuickConnect(cluster)
if err != nil {
return fmt.Errorf("connection failed: %w", err)
}
// Step 3: Wait for price
fmt.Printf("β³ Waiting for %s price...\n", symbol)
priceInfo, err := sugar.WaitForPrice(symbol, 15*time.Second)
if err != nil {
return fmt.Errorf("price timeout: %w", err)
}
fmt.Printf("β
Ready to trade!\n")
fmt.Printf(" %s BID: %.5f ASK: %.5f\n",
symbol, priceInfo.Bid, priceInfo.Ask)
return nil
}
// Usage:
err := ConnectAndWaitForPrice(
591129415,
"password",
"mt5.mrpc.pro:443",
"FxPro-MT5 Demo",
"EURUSD")
3) Wait for multiple symbolsΒΆ
symbols := []string{"EURUSD", "GBPUSD", "USDJPY"}
fmt.Println("Waiting for prices on all symbols...")
for _, symbol := range symbols {
priceInfo, err := sugar.WaitForPrice(symbol, 10*time.Second)
if err != nil {
fmt.Printf("β %s: Timeout - %v\n", symbol, err)
continue
}
fmt.Printf("β
%s: BID=%.5f ASK=%.5f\n",
symbol, priceInfo.Bid, priceInfo.Ask)
}
4) Market open detectorΒΆ
func WaitForMarketOpen(sugar *mt5.MT5Sugar, symbol string) {
fmt.Printf("β° Waiting for %s market to open...\n", symbol)
startTime := time.Now()
priceInfo, err := sugar.WaitForPrice(symbol, 2*time.Hour)
if err != nil {
fmt.Printf("β Market didn't open within 2 hours\n")
return
}
elapsed := time.Since(startTime)
fmt.Printf("β
Market OPEN!\n")
fmt.Printf(" Waited: %v\n", elapsed.Round(time.Second))
fmt.Printf(" First price: BID=%.5f ASK=%.5f\n",
priceInfo.Bid, priceInfo.Ask)
fmt.Printf(" Server time: %s\n", priceInfo.Time.Format("15:04:05"))
}
// Usage on Monday morning
WaitForMarketOpen(sugar, "EURUSD")
5) Retry with increasing timeoutΒΆ
func WaitForPriceWithRetry(sugar *mt5.MT5Sugar, symbol string, maxAttempts int) (*PriceInfo, error) {
for attempt := 1; attempt <= maxAttempts; attempt++ {
timeout := time.Duration(attempt) * 5 * time.Second
fmt.Printf("Attempt %d/%d: Waiting %v for %s price...\n",
attempt, maxAttempts, timeout, symbol)
priceInfo, err := sugar.WaitForPrice(symbol, timeout)
if err == nil {
fmt.Printf("β
Got price on attempt %d\n", attempt)
return priceInfo, nil
}
fmt.Printf("β Attempt %d failed: %v\n", attempt, err)
if attempt < maxAttempts {
fmt.Println(" Retrying...")
time.Sleep(2 * time.Second)
}
}
return nil, fmt.Errorf("all %d attempts failed", maxAttempts)
}
// Usage:
priceInfo, err := WaitForPriceWithRetry(sugar, "EURUSD", 3)
6) Weekend gap handlerΒΆ
func HandleWeekendGap(sugar *mt5.MT5Sugar, symbol string) {
fmt.Printf("π
Weekend ended - waiting for %s to resume...\n", symbol)
// Long timeout for weekend β Monday transition
priceInfo, err := sugar.WaitForPrice(symbol, 30*time.Minute)
if err != nil {
fmt.Printf("β Market didn't resume: %v\n", err)
return
}
// Check for gap
// You'd need to compare with Friday's close price
fmt.Printf("β
Market resumed!\n")
fmt.Printf(" Monday open: BID=%.5f\n", priceInfo.Bid)
fmt.Printf(" Server time: %s\n", priceInfo.Time.Format("Mon 15:04:05"))
// Could add gap detection logic here
}
7) Trading bot startup sequenceΒΆ
func StartTradingBot(sugar *mt5.MT5Sugar, symbols []string) error {
fmt.Println("βββββββββββββββββββββββββββββββββββββββββ")
fmt.Println("β TRADING BOT STARTUP β")
fmt.Println("βββββββββββββββββββββββββββββββββββββββββ")
// Check connection
fmt.Println("\n1. Checking connection...")
if !sugar.IsConnected() {
return fmt.Errorf("not connected to MT5")
}
fmt.Println(" β
Connected")
// Wait for prices on all symbols
fmt.Println("\n2. Waiting for price feeds...")
for i, symbol := range symbols {
fmt.Printf(" [%d/%d] %s... ", i+1, len(symbols), symbol)
priceInfo, err := sugar.WaitForPrice(symbol, 15*time.Second)
if err != nil {
fmt.Printf("β TIMEOUT\n")
return fmt.Errorf("%s price not available", symbol)
}
fmt.Printf("β
%.5f\n", priceInfo.Bid)
}
fmt.Println("\nβ
BOT READY TO TRADE")
return nil
}
// Usage:
symbols := []string{"EURUSD", "GBPUSD", "USDJPY"}
err := StartTradingBot(sugar, symbols)
if err != nil {
fmt.Printf("Startup failed: %v\n", err)
}
8) Price feed validatorΒΆ
func ValidatePriceFeed(sugar *mt5.MT5Sugar, symbol string) bool {
fmt.Printf("Validating %s price feed...\n", symbol)
// Try to get price within reasonable time
priceInfo, err := sugar.WaitForPrice(symbol, 5*time.Second)
if err != nil {
fmt.Printf("β Price feed INVALID: %v\n", err)
return false
}
// Validate price values
if priceInfo.Bid <= 0 || priceInfo.Ask <= 0 {
fmt.Printf("β Price feed INVALID: Invalid price values\n")
return false
}
if priceInfo.Ask <= priceInfo.Bid {
fmt.Printf("β Price feed INVALID: ASK <= BID\n")
return false
}
// Check timestamp freshness
age := time.Since(priceInfo.Time)
if age > 10*time.Second {
fmt.Printf("β Price feed STALE: %v old\n", age)
return false
}
fmt.Printf("β
Price feed VALID\n")
fmt.Printf(" BID: %.5f, ASK: %.5f\n", priceInfo.Bid, priceInfo.Ask)
fmt.Printf(" Age: %.1f seconds\n", age.Seconds())
return true
}
9) Emergency reconnectionΒΆ
func EmergencyReconnect(sugar *mt5.MT5Sugar, cluster, symbol string) error {
fmt.Println("π¨ Emergency reconnection initiated...")
// Reconnect
err := sugar.QuickConnect(cluster)
if err != nil {
return fmt.Errorf("reconnect failed: %w", err)
}
fmt.Println("β
Reconnected - waiting for price feed...")
// Wait for price to confirm connection is working
_, err = sugar.WaitForPrice(symbol, 30*time.Second)
if err != nil {
return fmt.Errorf("price feed not restored: %w", err)
}
fmt.Println("β
Connection fully restored!")
return nil
}
// Usage during connection loss
if !sugar.IsConnected() {
err := EmergencyReconnect(sugar, "FxPro-MT5 Demo", "EURUSD")
if err != nil {
fmt.Printf("Recovery failed: %v\n", err)
}
}
10) Symbol availability checkerΒΆ
func CheckSymbolAvailability(sugar *mt5.MT5Sugar, symbols []string) {
fmt.Println("Checking symbol availability:")
fmt.Println("βββββββββββββββββββββββββββββββββββββ")
available := []string{}
unavailable := []string{}
for _, symbol := range symbols {
fmt.Printf("%-10s ... ", symbol)
priceInfo, err := sugar.WaitForPrice(symbol, 3*time.Second)
if err != nil {
fmt.Println("β NOT AVAILABLE")
unavailable = append(unavailable, symbol)
} else {
fmt.Printf("β
BID=%.5f\n", priceInfo.Bid)
available = append(available, symbol)
}
}
fmt.Println("\nβββββββββββββββββββββββββββββββββββββββ")
fmt.Printf("Available: %d symbols\n", len(available))
fmt.Printf("Unavailable: %d symbols\n", len(unavailable))
if len(unavailable) > 0 {
fmt.Println("\nUnavailable symbols:")
for _, s := range unavailable {
fmt.Printf(" - %s\n", s)
}
}
}
// Usage:
symbols := []string{"EURUSD", "GBPUSD", "XAUUSD", "INVALID", "BTCUSD"}
CheckSymbolAvailability(sugar, symbols)
π Related MethodsΒΆ
GetPriceInfo()- Get price immediately (no waiting)IsSymbolAvailable()- Check if symbol existsQuickConnect()- Connect to MT5
β οΈ Common PitfallsΒΆ
1) Timeout too shortΒΆ
// β WRONG - might timeout during slow connection
priceInfo, _ := sugar.WaitForPrice("EURUSD", 1*time.Second)
// β
CORRECT - reasonable timeout
priceInfo, _ := sugar.WaitForPrice("EURUSD", 10*time.Second)
2) Not checking for errorΒΆ
// β WRONG - ignoring timeout error
priceInfo, _ := sugar.WaitForPrice("EURUSD", 5*time.Second)
fmt.Printf("Price: %.5f\n", priceInfo.Bid) // Might panic if timeout!
// β
CORRECT - handle timeout
priceInfo, err := sugar.WaitForPrice("EURUSD", 5*time.Second)
if err != nil {
fmt.Printf("Timeout: %v\n", err)
return
}
π Pro TipsΒΆ
- Use after connection - Always wait for price before trading
- Reasonable timeout - 10-15 seconds is usually enough
- Multiple symbols - Check all symbols before starting bot
- Weekend handling - Use longer timeout (30min) on Monday
- Fallback plan - Have reconnection logic if timeout occurs
See also: GetPriceInfo.md, QuickConnect.md