187 lines
4.2 KiB
Plaintext
187 lines
4.2 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| MarketData.mqh - Market data wrapper |
|
|
//| Handles bid/ask, spread, symbol info, new bar detection |
|
|
//+------------------------------------------------------------------+
|
|
|
|
#ifndef __MARKETDATA_MQH__
|
|
#define __MARKETDATA_MQH__
|
|
|
|
#include "Config.mqh"
|
|
#include "Logger.mqh"
|
|
#include "Utilities.mqh"
|
|
|
|
class CMarketData
|
|
{
|
|
private:
|
|
string m_symbol;
|
|
CLogger *mp_logger;
|
|
datetime m_last_bar_time;
|
|
int m_digits;
|
|
double m_point;
|
|
|
|
public:
|
|
// Constructor
|
|
CMarketData(const string symbol, CLogger *logger)
|
|
{
|
|
m_symbol = symbol;
|
|
mp_logger = logger;
|
|
m_last_bar_time = 0;
|
|
m_digits = CUtilities::GetDigits(symbol);
|
|
m_point = CUtilities::GetPoint(symbol);
|
|
}
|
|
|
|
// Get current bid price
|
|
double GetBid() const
|
|
{
|
|
return SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
|
}
|
|
|
|
// Get current ask price
|
|
double GetAsk() const
|
|
{
|
|
return SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
|
}
|
|
|
|
// Get current spread in points
|
|
int GetSpreadPoints() const
|
|
{
|
|
double spread_price = GetAsk() - GetBid();
|
|
return CUtilities::PriceToPoints(m_symbol, spread_price);
|
|
}
|
|
|
|
// Get current spread in price
|
|
double GetSpreadPrice() const
|
|
{
|
|
return GetAsk() - GetBid();
|
|
}
|
|
|
|
// Check if spread is acceptable
|
|
bool IsSpreadAcceptable(int max_spread_points) const
|
|
{
|
|
int current_spread = GetSpreadPoints();
|
|
if(current_spread > max_spread_points)
|
|
{
|
|
if(mp_logger)
|
|
{
|
|
// Build message without using variadic StringFormat to avoid parser issues
|
|
string msg = "Spread too wide: ";
|
|
msg += IntegerToString(current_spread);
|
|
msg += " > ";
|
|
msg += IntegerToString(max_spread_points);
|
|
mp_logger.Warning(msg);
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Detect new bar on current timeframe
|
|
bool IsNewBar()
|
|
{
|
|
datetime bar_time = iTime(m_symbol, PERIOD_CURRENT, 0);
|
|
|
|
if(m_last_bar_time == 0)
|
|
{
|
|
m_last_bar_time = bar_time;
|
|
return true;
|
|
}
|
|
|
|
if(bar_time != m_last_bar_time)
|
|
{
|
|
m_last_bar_time = bar_time;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Get current close price
|
|
double GetClose() const
|
|
{
|
|
return iClose(m_symbol, PERIOD_CURRENT, 0);
|
|
}
|
|
|
|
// Get current open price
|
|
double GetOpen() const
|
|
{
|
|
return iOpen(m_symbol, PERIOD_CURRENT, 0);
|
|
}
|
|
|
|
// Get current high price
|
|
double GetHigh() const
|
|
{
|
|
return iHigh(m_symbol, PERIOD_CURRENT, 0);
|
|
}
|
|
|
|
// Get current low price
|
|
double GetLow() const
|
|
{
|
|
return iLow(m_symbol, PERIOD_CURRENT, 0);
|
|
}
|
|
|
|
// Get close price of bar N bars ago
|
|
double GetCloseAt(int shift) const
|
|
{
|
|
return iClose(m_symbol, PERIOD_CURRENT, shift);
|
|
}
|
|
|
|
// Get open price of bar N bars ago
|
|
double GetOpenAt(int shift) const
|
|
{
|
|
return iOpen(m_symbol, PERIOD_CURRENT, shift);
|
|
}
|
|
|
|
// Get symbol digits
|
|
int GetDigits() const
|
|
{
|
|
return m_digits;
|
|
}
|
|
|
|
// Get symbol point
|
|
double GetPoint() const
|
|
{
|
|
return m_point;
|
|
}
|
|
|
|
// Check if trading is allowed for this symbol
|
|
bool IsTradingAllowed() const
|
|
{
|
|
// Ensure symbol allows trading (full trade mode)
|
|
long trade_mode = (long)SymbolInfoInteger(m_symbol, SYMBOL_TRADE_MODE);
|
|
if(trade_mode != SYMBOL_TRADE_MODE_FULL)
|
|
return false;
|
|
|
|
// Basic check: ensure symbol is tradeable (has non-zero point and digits)
|
|
if(SymbolInfoDouble(m_symbol, SYMBOL_POINT) <= 0.0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Get symbol name
|
|
string GetSymbol() const
|
|
{
|
|
return m_symbol;
|
|
}
|
|
|
|
// Get minimum volume
|
|
double GetMinVolume() const
|
|
{
|
|
return SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MIN);
|
|
}
|
|
|
|
// Get maximum volume
|
|
double GetMaxVolume() const
|
|
{
|
|
return SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MAX);
|
|
}
|
|
|
|
// Get volume step
|
|
double GetVolumeStep() const
|
|
{
|
|
return SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_STEP);
|
|
}
|
|
};
|
|
|
|
#endif //__MARKETDATA_MQH__
|