MQL4 Current Price — วิธีดึงราคาปัจจุบันใน MQL4
MQL4 (MetaQuotes Language 4) เป็นภาษาโปรแกรมมิ่งสำหรับเขียน Expert Advisors (EA), Custom Indicators และ Scripts บน MetaTrader 4 การดึงราคาปัจจุบัน (Current Price) เป็นพื้นฐานสำคัญที่สุดในการเขียนโปรแกรมเทรด Forex ทุก EA ต้องรู้ราคาปัจจุบันเพื่อตัดสินใจซื้อขาย บทความนี้อธิบายวิธีดึงราคาใน MQL4 ครบทุกรูปแบบ พร้อมตัวอย่างโค้ดและ Python tools เสริม
วิธีดึงราคาปัจจุบันใน MQL4
// current_price.mq4 — Get current price in MQL4
// === Method 1: Predefined Variables ===
// Bid — ราคาขาย (sell price)
// Ask — ราคาซื้อ (buy price)
void OnTick()
{
double currentBid = Bid; // ราคา Bid ปัจจุบัน
double currentAsk = Ask; // ราคา Ask ปัจจุบัน
double spread = Ask - Bid; // Spread
Print("Bid: ", currentBid);
Print("Ask: ", currentAsk);
Print("Spread: ", spread / Point, " points");
}
// === Method 2: MarketInfo() ===
// ดึงราคาของ symbol ใดก็ได้ (ไม่จำกัดแค่ chart ปัจจุบัน)
double GetPrice(string symbol)
{
double bid = MarketInfo(symbol, MODE_BID);
double ask = MarketInfo(symbol, MODE_ASK);
double point = MarketInfo(symbol, MODE_POINT);
double spread = MarketInfo(symbol, MODE_SPREAD);
Print(symbol, " Bid: ", bid, " Ask: ", ask, " Spread: ", spread);
return bid;
}
// === Method 3: SymbolInfoDouble() (MQL4 build 600+) ===
// Modern function — แนะนำใช้อันนี้
double GetCurrentPrice(string symbol)
{
double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
double last = SymbolInfoDouble(symbol, SYMBOL_LAST);
return bid;
}
// === Method 4: iClose() — ราคาปิดของ bar ===
// ดึงราคาปิดของ bar ล่าสุด (bar 0 = current, bar 1 = previous)
double GetClosePrice(string symbol, int timeframe, int bar)
{
return iClose(symbol, timeframe, bar);
}
// Usage:
// double currentClose = iClose(Symbol(), PERIOD_H1, 0); // H1 current bar close
// double previousClose = iClose(Symbol(), PERIOD_H1, 1); // H1 previous bar close
// double dailyClose = iClose("EURUSD", PERIOD_D1, 1); // EURUSD yesterday close
Price Functions ทั้งหมด
// price_functions.mq4 — All price-related functions
// === OHLCV Functions ===
// iOpen() — ราคาเปิด
// iHigh() — ราคาสูงสุด
// iLow() — ราคาต่ำสุด
// iClose() — ราคาปิด
// iVolume() — Volume
void ShowAllPrices()
{
string sym = Symbol();
int tf = PERIOD_H1;
// Current bar (bar 0)
double open0 = iOpen(sym, tf, 0);
double high0 = iHigh(sym, tf, 0);
double low0 = iLow(sym, tf, 0);
double close0 = iClose(sym, tf, 0);
long vol0 = iVolume(sym, tf, 0);
Print("Current H1 Bar:");
Print(" Open: ", open0);
Print(" High: ", high0);
Print(" Low: ", low0);
Print(" Close: ", close0);
Print(" Volume: ", vol0);
// Previous bar (bar 1)
double close1 = iClose(sym, tf, 1);
Print("Previous H1 Close: ", close1);
// Price change
double change = close0 - close1;
double changePct = (change / close1) * 100;
Print("Change: ", change, " (", changePct, "%)");
}
// === Predefined Price Arrays ===
// Open[] — array of open prices
// High[] — array of high prices
// Low[] — array of low prices
// Close[] — array of close prices
// Volume[] — array of volumes
// Time[] — array of bar times
void ShowArrayPrices()
{
// bar 0 = current (newest)
Print("Close[0] = ", Close[0]); // = Bid (approximately)
Print("Close[1] = ", Close[1]); // previous bar close
Print("High[0] = ", High[0]);
Print("Low[0] = ", Low[0]);
// หาราคาสูงสุดใน 20 bars
double highest = High[iHighest(NULL, 0, MODE_HIGH, 20, 0)];
double lowest = Low[iLowest(NULL, 0, MODE_LOW, 20, 0)];
Print("20-bar High: ", highest);
Print("20-bar Low: ", lowest);
}
ตัวอย่าง EA ใช้ราคาปัจจุบัน
// simple_ea.mq4 — Simple EA using current price
// Input parameters
input double LotSize = 0.01;
input int SlPips = 50;
input int TpPips = 100;
input int MaPeriod = 200;
void OnTick()
{
// ตรวจสอบว่ามี order อยู่หรือไม่
if (OrdersTotal() > 0) return;
// ดึงราคาปัจจุบัน
double bid = Bid;
double ask = Ask;
double point = Point;
// คำนวณ Moving Average
double ma = iMA(Symbol(), PERIOD_H1, MaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
// Signal: Price above MA = Buy, below = Sell
if (bid > ma)
{
// Buy signal
double sl = ask - SlPips * point;
double tp = ask + TpPips * point;
int ticket = OrderSend(
Symbol(), // symbol
OP_BUY, // operation
LotSize, // lot size
ask, // price (ใช้ Ask สำหรับ Buy)
3, // slippage
sl, // stop loss
tp, // take profit
"MA Buy", // comment
12345, // magic number
0, // expiration
clrGreen // color
);
if (ticket > 0)
Print("Buy order opened at ", ask);
else
Print("Error: ", GetLastError());
}
else if (bid < ma)
{
// Sell signal
double sl = bid + SlPips * point;
double tp = bid - TpPips * point;
int ticket = OrderSend(
Symbol(),
OP_SELL,
LotSize,
bid, // price (ใช้ Bid สำหรับ Sell)
3,
sl,
tp,
"MA Sell",
12345,
0,
clrRed
);
if (ticket > 0)
Print("Sell order opened at ", bid);
else
Print("Error: ", GetLastError());
}
}
// === Helper: Normalize Price ===
double NormalizePrice(double price)
{
return NormalizeDouble(price, Digits);
}
Python Price Monitor
# price_monitor.py — Python price monitoring tools
import json
class PriceMonitor:
CODE = """
# mt4_price_monitor.py — Monitor MT4 prices via Python
import json
import time
from datetime import datetime
from pathlib import Path
class MT4PriceMonitor:
def __init__(self, mt4_data_dir):
'''Read prices from MT4 file sharing'''
self.data_dir = Path(mt4_data_dir)
self.price_file = self.data_dir / "prices.csv"
def read_prices(self):
'''Read current prices from shared file'''
if not self.price_file.exists():
return None
prices = {}
with open(self.price_file) as f:
for line in f:
parts = line.strip().split(',')
if len(parts) >= 3:
symbol = parts[0]
bid = float(parts[1])
ask = float(parts[2])
prices[symbol] = {
'bid': bid,
'ask': ask,
'spread': round(ask - bid, 5),
'mid': round((bid + ask) / 2, 5),
}
return prices
def price_alert(self, symbol, target_price, direction='above'):
'''Monitor price and alert'''
while True:
prices = self.read_prices()
if prices and symbol in prices:
current = prices[symbol]['bid']
if direction == 'above' and current > target_price:
return {'alert': True, 'price': current, 'target': target_price}
elif direction == 'below' and current < target_price:
return {'alert': True, 'price': current, 'target': target_price}
print(f"{symbol}: {current} (target: {target_price})")
time.sleep(1)
def calculate_pip_value(self, symbol, lot_size=1.0, account_currency='USD'):
'''Calculate pip value'''
prices = self.read_prices()
if not prices or symbol not in prices:
return None
bid = prices[symbol]['bid']
# Standard lot = 100,000 units
units = lot_size * 100000
if symbol.endswith('USD'):
pip_value = units * 0.0001
elif symbol.startswith('USD'):
pip_value = units * 0.0001 / bid
else:
pip_value = units * 0.0001 # approximate
return {
'symbol': symbol,
'lot_size': lot_size,
'pip_value_usd': round(pip_value, 2),
'bid': bid,
}
# monitor = MT4PriceMonitor("C:/Users/user/AppData/Roaming/MetaQuotes/Terminal/data")
# prices = monitor.read_prices()
# pip_val = monitor.calculate_pip_value("EURUSD", 0.1)
"""
def show_code(self):
print("=== Python Price Monitor ===")
print(self.CODE[:600])
monitor = PriceMonitor()
monitor.show_code()
Common Mistakes
# mistakes.py — Common mistakes with MQL4 prices
import json
class CommonMistakes:
MISTAKES = {
"bid_ask_confusion": {
"mistake": "ใช้ Bid สำหรับ Buy order หรือ Ask สำหรับ Sell order",
"correct": "Buy ใช้ Ask (ราคาที่ broker ขายให้เรา), Sell ใช้ Bid (ราคาที่ broker ซื้อจากเรา)",
"code": "OrderSend(Symbol(), OP_BUY, lot, Ask, ...); OrderSend(Symbol(), OP_SELL, lot, Bid, ...);",
},
"not_normalizing": {
"mistake": "ไม่ normalize price ก่อนส่ง order",
"correct": "ใช้ NormalizeDouble(price, Digits) เสมอ",
"code": "double sl = NormalizeDouble(Ask - 50*Point, Digits);",
},
"stale_price": {
"mistake": "ใช้ราคาเก่าที่ cache ไว้ — ไม่ refresh",
"correct": "ดึงราคาใหม่ทุกครั้งก่อน send order — RefreshRates()",
"code": "RefreshRates(); double price = Ask; // fresh price",
},
"wrong_point": {
"mistake": "ใช้ Point ผิดสำหรับ 5-digit broker (EURUSD = 1.12345)",
"correct": "ตรวจสอบ Digits: ถ้า 5 digits → 1 pip = 10 * Point",
"code": "double pip = (Digits == 5 || Digits == 3) ? 10 * Point : Point;",
},
"multi_symbol": {
"mistake": "ใช้ Bid/Ask สำหรับ symbol อื่นที่ไม่ใช่ chart ปัจจุบัน",
"correct": "ใช้ MarketInfo() หรือ SymbolInfoDouble() สำหรับ symbol อื่น",
"code": "double eurusd_bid = MarketInfo('EURUSD', MODE_BID);",
},
}
def show_mistakes(self):
print("=== Common Mistakes ===\n")
for key, m in self.MISTAKES.items():
print(f"[{key}]")
print(f" Mistake: {m['mistake']}")
print(f" Correct: {m['correct']}")
print()
mistakes = CommonMistakes()
mistakes.show_mistakes()
FAQ - คำถามที่พบบ่อย
Q: Bid กับ Ask ต่างกันอย่างไร?
A: Bid: ราคาที่ broker ซื้อจากเรา → ใช้เมื่อ Sell Ask: ราคาที่ broker ขายให้เรา → ใช้เมื่อ Buy Ask > Bid เสมอ — ส่วนต่างคือ Spread (ค่าธรรมเนียม broker) ตัวอย่าง: EURUSD Bid = 1.08500, Ask = 1.08520 → Spread = 2 pips
Q: RefreshRates() จำเป็นไหม?
A: จำเป็นเมื่อ: EA ทำงานนานใน OnTick() — ราคาอาจเปลี่ยนระหว่างคำนวณ ก่อนส่ง order: เรียก RefreshRates() → อ่าน Bid/Ask ใหม่ → ส่ง order ไม่จำเป็นเมื่อ: OnTick() ทำงานเร็ว (< 100ms) — ราคายังไม่เปลี่ยน MQL5: ไม่ต้องใช้ RefreshRates() — SymbolInfoDouble() ให้ราคาล่าสุดเสมอ
Q: MQL4 กับ MQL5 ต่างกันตรงไหนเรื่องราคา?
A: MQL4: ใช้ Bid/Ask predefined variables + MarketInfo() + iClose() MQL5: ใช้ SymbolInfoDouble() + CopyRates() + MqlTick structure MQL5 ดีกว่า: มี tick data ละเอียดกว่า, ไม่ต้อง RefreshRates() MQL4 ง่ายกว่า: Bid/Ask เรียกใช้ได้เลย ไม่ต้อง function call
Q: ดึงราคาข้าม timeframe ได้ไหม?
A: ได้ — ใช้ iClose(Symbol(), PERIOD_H4, 0) สำหรับ current bar, iClose(Symbol(), PERIOD_D1, 1) สำหรับราคาปิดเมื่อวาน Timeframes: PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 ระวัง: bar 0 ของ timeframe ใหญ่อาจยังไม่ปิด — ใช้ bar 1 สำหรับราคาปิดที่ confirmed แล้ว
