Skip to content

πŸ“ Ping MT5 Server (Ping)ΒΆ

Sugar method: Sends a ping to MT5 server to verify connection health and measure response time.

API Information:

  • Method: sugar.Ping()
  • Package: mt5 (MT5Sugar)
  • Underlying calls: account.Ping()
  • Timeout: 5 seconds

πŸ“‹ Method SignatureΒΆ

func (s *MT5Sugar) Ping() error

πŸ”½ InputΒΆ

No parameters


⬆️ OutputΒΆ

Return Type Description
error error nil if ping successful, error if connection problem

πŸ’¬ Just the EssentialsΒΆ

  • What it is: Sends a ping to MT5 server to test if it's reachable and responsive.
  • Why you need it: Verify connection health, measure latency, detect network issues.
  • Sanity check: If ping returns nil, connection is healthy.

🎯 Purpose¢

Use it for detailed connection testing:

  • Health check - Verify server is responsive
  • Latency measurement - Test connection speed
  • Network diagnostics - Detect connectivity issues
  • Pre-trading validation - Ensure stable connection
  • Monitoring - Track connection quality over time

🧩 Notes & Tips¢

  • Returns error - nil = success, error = problem
  • 5-second timeout - Fails if no response
  • Lighter than IsConnected - Just pings, no extra checks
  • Use for diagnostics - Better than IsConnected for troubleshooting
  • Measure latency - Time the call to measure round-trip
  • Network issues - Detects network problems quickly

πŸ”§ Under the HoodΒΆ

func (s *MT5Sugar) Ping() error {
    ctx, cancel := context.WithTimeout(s.ctx, 5*time.Second)
    defer cancel()

    return s.account.Ping(ctx)
}

What it does:

  • βœ… Simple ping - Sends ping, waits for pong
  • βœ… 5-second timeout - Doesn't hang forever
  • βœ… Clean error - nil = OK, error = problem

πŸ“Š Low-Level AlternativeΒΆ

WITHOUT sugar:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

err := account.Ping(ctx)

WITH sugar:

err := sugar.Ping()

Benefits:

  • βœ… One line vs three
  • βœ… Built-in timeout
  • βœ… Cleaner code

πŸ”— Usage ExamplesΒΆ

1) Basic pingΒΆ

err := sugar.Ping()
if err != nil {
    fmt.Printf("❌ Ping failed: %v\n", err)
    return
}

fmt.Println("βœ… Ping successful - server is responsive")

2) Measure latencyΒΆ

start := time.Now()
err := sugar.Ping()
latency := time.Since(start)

if err != nil {
    fmt.Printf("❌ Ping failed: %v\n", err)
    return
}

fmt.Printf("βœ… Ping successful\n")
fmt.Printf("   Latency: %v\n", latency)

if latency > 500*time.Millisecond {
    fmt.Println("   ⚠️  High latency detected!")
}

3) Connection quality checkΒΆ

func CheckConnectionQuality(sugar *mt5.MT5Sugar, samples int) {
    var totalLatency time.Duration
    failures := 0

    fmt.Printf("Testing connection (%d pings)...\n", samples)

    for i := 0; i < samples; i++ {
        start := time.Now()
        err := sugar.Ping()
        latency := time.Since(start)

        if err != nil {
            failures++
            fmt.Printf("  Ping %d: ❌ Failed\n", i+1)
        } else {
            totalLatency += latency
            fmt.Printf("  Ping %d: βœ… %v\n", i+1, latency)
        }

        time.Sleep(time.Second)
    }

    fmt.Println("─────────────────────────────────")
    fmt.Printf("Results:\n")
    fmt.Printf("  Successful: %d/%d (%.1f%%)\n",
        samples-failures, samples,
        float64(samples-failures)/float64(samples)*100)

    if failures < samples {
        avgLatency := totalLatency / time.Duration(samples-failures)
        fmt.Printf("  Avg latency: %v\n", avgLatency)
    }

    if failures > 0 {
        fmt.Printf("  ⚠️  %d ping(s) failed\n", failures)
    }
}

// Usage:
CheckConnectionQuality(sugar, 5)

4) Pre-trading connection testΒΆ

func ValidateConnectionForTrading(sugar *mt5.MT5Sugar) error {
    // Test with 3 pings
    failures := 0

    for i := 0; i < 3; i++ {
        err := sugar.Ping()
        if err != nil {
            failures++
        }
        time.Sleep(500 * time.Millisecond)
    }

    if failures >= 2 {
        return fmt.Errorf("connection unstable: %d/3 pings failed", failures)
    }

    return nil
}

// Before trading
err := ValidateConnectionForTrading(sugar)
if err != nil {
    fmt.Printf("❌ %v\n", err)
    fmt.Println("   Trading not recommended")
    return
}

fmt.Println("βœ… Connection stable - safe to trade")

5) Continuous monitoringΒΆ

func MonitorConnectionHealth(sugar *mt5.MT5Sugar, interval time.Duration) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    consecutiveFailures := 0

    for range ticker.C {
        err := sugar.Ping()

        if err != nil {
            consecutiveFailures++
            fmt.Printf("⚠️  Ping failed (%d consecutive failures): %v\n",
                consecutiveFailures, err)

            if consecutiveFailures >= 3 {
                fmt.Println("🚨 CONNECTION LOST - Too many failures!")
                // Trigger reconnect or alert
            }
        } else {
            if consecutiveFailures > 0 {
                fmt.Println("βœ… Connection restored")
            }
            consecutiveFailures = 0
            fmt.Println("πŸ“‘ Ping OK")
        }
    }
}

// Run in background
go MonitorConnectionHealth(sugar, 30*time.Second)

6) Compare Ping vs IsConnectedΒΆ

fmt.Println("Testing connection methods:")

// Method 1: Ping
start := time.Now()
pingErr := sugar.Ping()
pingTime := time.Since(start)

// Method 2: IsConnected
start = time.Now()
connected := sugar.IsConnected()
connTime := time.Since(start)

fmt.Println("─────────────────────────────────")
fmt.Printf("Ping():        %v (%v)\n", pingErr == nil, pingTime)
fmt.Printf("IsConnected(): %v (%v)\n", connected, connTime)
fmt.Println("─────────────────────────────────")

// Output might be:
// Ping():        true (45ms)
// IsConnected(): true (48ms)

7) Retry logic with pingΒΆ

func ConnectWithPing(sugar *mt5.MT5Sugar, cluster string, maxRetries int) error {
    for i := 0; i < maxRetries; i++ {
        fmt.Printf("Connection attempt %d/%d...\n", i+1, maxRetries)

        // Connect
        err := sugar.QuickConnect(cluster)
        if err != nil {
            fmt.Printf("  Connect failed: %v\n", err)
            time.Sleep(3 * time.Second)
            continue
        }

        // Verify with ping
        err = sugar.Ping()
        if err != nil {
            fmt.Printf("  Ping failed: %v\n", err)
            time.Sleep(3 * time.Second)
            continue
        }

        fmt.Println("βœ… Connected and verified!")
        return nil
    }

    return fmt.Errorf("all %d connection attempts failed", maxRetries)
}

// Usage:
err := ConnectWithPing(sugar, "FxPro-MT5 Demo", 3)
if err != nil {
    fmt.Printf("❌ %v\n", err)
}

8) Benchmark connection speedΒΆ

func BenchmarkConnection(sugar *mt5.MT5Sugar, iterations int) {
    latencies := make([]time.Duration, 0, iterations)

    fmt.Printf("Benchmarking connection (%d pings)...\n", iterations)

    for i := 0; i < iterations; i++ {
        start := time.Now()
        err := sugar.Ping()
        latency := time.Since(start)

        if err == nil {
            latencies = append(latencies, latency)
        }

        time.Sleep(200 * time.Millisecond)
    }

    if len(latencies) == 0 {
        fmt.Println("❌ All pings failed")
        return
    }

    // Calculate statistics
    var total time.Duration
    min := latencies[0]
    max := latencies[0]

    for _, lat := range latencies {
        total += lat
        if lat < min {
            min = lat
        }
        if lat > max {
            max = lat
        }
    }

    avg := total / time.Duration(len(latencies))

    fmt.Println("═══════════════════════════════════")
    fmt.Println("  CONNECTION BENCHMARK RESULTS")
    fmt.Println("═══════════════════════════════════")
    fmt.Printf("Pings sent:    %d\n", iterations)
    fmt.Printf("Successful:    %d (%.1f%%)\n",
        len(latencies),
        float64(len(latencies))/float64(iterations)*100)
    fmt.Printf("Min latency:   %v\n", min)
    fmt.Printf("Avg latency:   %v\n", avg)
    fmt.Printf("Max latency:   %v\n", max)
}

// Usage:
BenchmarkConnection(sugar, 20)

9) Alert on connection issuesΒΆ

func MonitorWithAlerts(sugar *mt5.MT5Sugar) {
    ticker := time.NewTicker(10 * time.Second)
    defer ticker.Stop()

    lastStatus := true

    for range ticker.C {
        err := sugar.Ping()
        currentStatus := (err == nil)

        // Status changed
        if currentStatus != lastStatus {
            if currentStatus {
                fmt.Println("πŸ”” ALERT: Connection RESTORED")
                // Send notification (email, telegram, etc.)
            } else {
                fmt.Println("🚨 ALERT: Connection LOST")
                // Send urgent notification
            }
        }

        lastStatus = currentStatus
    }
}

// Run in background
go MonitorWithAlerts(sugar)

10) Connection diagnostics toolΒΆ

func DiagnoseConnection(sugar *mt5.MT5Sugar) {
    fmt.Println("╔═══════════════════════════════════════════════╗")
    fmt.Println("β•‘       CONNECTION DIAGNOSTICS                  β•‘")
    fmt.Println("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•")
    fmt.Println()

    // Test 1: Ping
    fmt.Println("Test 1: Server Ping")
    start := time.Now()
    pingErr := sugar.Ping()
    pingLatency := time.Since(start)

    if pingErr != nil {
        fmt.Printf("  ❌ FAILED: %v\n", pingErr)
    } else {
        fmt.Printf("  βœ… SUCCESS (Latency: %v)\n", pingLatency)
    }
    fmt.Println()

    // Test 2: IsConnected
    fmt.Println("Test 2: Connection Status")
    connected := sugar.IsConnected()
    if connected {
        fmt.Println("  βœ… CONNECTED")
    } else {
        fmt.Println("  ❌ NOT CONNECTED")
    }
    fmt.Println()

    // Test 3: Get Balance (actual operation)
    fmt.Println("Test 3: Sample Operation (GetBalance)")
    balance, balErr := sugar.GetBalance()
    if balErr != nil {
        fmt.Printf("  ❌ FAILED: %v\n", balErr)
    } else {
        fmt.Printf("  βœ… SUCCESS (Balance: %.2f)\n", balance)
    }
    fmt.Println()

    // Summary
    fmt.Println("═══════════════════════════════════════════════")
    allPassed := (pingErr == nil && connected && balErr == nil)
    if allPassed {
        fmt.Println("βœ… ALL TESTS PASSED - Connection is healthy")
    } else {
        fmt.Println("❌ SOME TESTS FAILED - Connection has issues")
    }
}

// Usage:
DiagnoseConnection(sugar)

🍬 Connection methods:

  • QuickConnect() - Connect to MT5 Terminal
  • IsConnected() - Check if connected

πŸ“– Typical diagnostic pattern:

// 1. Check with IsConnected
connected, _ := sugar.IsConnected()

// 2. If issues, use Ping for details
if !connected {
    err := sugar.Ping()
    fmt.Printf("Ping error: %v\n", err)
}

⚠️ Common Pitfalls¢

1) Confusing nil with successΒΆ

// ❌ WRONG - checking for non-nil (backwards!)
if sugar.Ping() != nil {
    fmt.Println("Connection OK") // WRONG!
}

// βœ… CORRECT - nil means success
if sugar.Ping() == nil {
    fmt.Println("Connection OK")
}

2) Not handling timeoutΒΆ

// ❌ WRONG - might hang for 5 seconds
sugar.Ping() // Blocked for up to 5 seconds!

// βœ… CORRECT - be aware of timeout
fmt.Println("Pinging...")
err := sugar.Ping() // Max 5 seconds
if err != nil {
    fmt.Println("Ping failed or timed out")
}

3) Pinging too frequentlyΒΆ

// ❌ WRONG - excessive pinging
for {
    sugar.Ping() // Every loop iteration!
    time.Sleep(100 * time.Millisecond)
}

// βœ… CORRECT - reasonable interval
for {
    sugar.Ping()
    time.Sleep(30 * time.Second) // Every 30 seconds
}

πŸ’Ž Pro TipsΒΆ

  1. Use for diagnostics - Better than IsConnected for troubleshooting
  2. Measure latency - Time the call to measure connection speed
  3. Reasonable intervals - Don't ping more than once per 10-30 seconds
  4. Before critical ops - Ping before important trading operations
  5. Combine with monitoring - Track latency trends over time
  6. Network issues - Ping failures often indicate network problems

See also: QuickConnect.md, IsConnected.md