88 lines
3.2 KiB
MQL5
88 lines
3.2 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Grid.mqh – logika GRIDu (otevření, přidání úrovně, uzavření) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "TestRefactor"
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
#ifndef __GRID_MQH__
|
||
|
|
#define __GRID_MQH__
|
||
|
|
|
||
|
|
#include "Context.mqh"
|
||
|
|
#include "Positions.mqh"
|
||
|
|
#include "Logger.mqh"
|
||
|
|
#include <Trade/Trade.mqh>
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| CGrid – veškerá logika GRIDu uvnitř třídy |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
class CGrid {
|
||
|
|
private:
|
||
|
|
SContext m_ctx;
|
||
|
|
CPositions *m_positions;
|
||
|
|
CLogger *m_log;
|
||
|
|
CTrade *m_trade;
|
||
|
|
string m_symbol;
|
||
|
|
|
||
|
|
public:
|
||
|
|
CGrid() : m_positions(NULL), m_log(NULL), m_trade(NULL), m_symbol("") {}
|
||
|
|
|
||
|
|
void SetContext(const SContext &ctx) { m_ctx = ctx; }
|
||
|
|
void SetPositions(CPositions *pos) { m_positions = pos; }
|
||
|
|
void SetLogger(CLogger *log) { m_log = log; }
|
||
|
|
void SetTrade(CTrade *trade) { m_trade = trade; }
|
||
|
|
void SetSymbol(string symbol) { m_symbol = symbol; }
|
||
|
|
|
||
|
|
void CheckProfitTargetAndClose() {
|
||
|
|
if(m_ctx.tradeMode != TRADE_GRID || m_ctx.gridTargetProfitUSD <= 0 || !m_trade || !m_positions) return;
|
||
|
|
m_positions.Refresh();
|
||
|
|
double totalProfit = m_positions.GetTotalProfit();
|
||
|
|
if(totalProfit < m_ctx.gridTargetProfitUSD) return;
|
||
|
|
ulong tickets[];
|
||
|
|
m_positions.GetTickets(tickets);
|
||
|
|
int n = ArraySize(tickets);
|
||
|
|
if(n == 0) return;
|
||
|
|
for(int j = 0; j < n; j++)
|
||
|
|
m_trade.PositionClose(tickets[j]);
|
||
|
|
if(m_log) m_log.Info("GRID uzavřen se ziskem " + DoubleToString(totalProfit, 2) + " USD");
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnNewBar(bool buySignal, bool sellSignal, double volume, bool tfBuyValid = true, bool tfSellValid = true) {
|
||
|
|
if(m_ctx.tradeMode != TRADE_GRID || !m_trade || !m_positions || !m_log) return;
|
||
|
|
m_positions.Refresh();
|
||
|
|
|
||
|
|
bool canBuy = buySignal && tfBuyValid;
|
||
|
|
bool canSell = sellSignal && tfSellValid;
|
||
|
|
|
||
|
|
int nBuy = m_positions.CountBuy();
|
||
|
|
int nSell = m_positions.CountSell();
|
||
|
|
double ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
||
|
|
double bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
||
|
|
double gridDistPrice = m_ctx.gridDistancePoints * _Point;
|
||
|
|
|
||
|
|
if(m_positions.HasNoPositions()) {
|
||
|
|
if(canBuy) {
|
||
|
|
m_log.Info("GRID Buy – první úroveň");
|
||
|
|
m_trade.Buy(volume, m_symbol, ask, 0, 0, "Grid Buy");
|
||
|
|
} else if(canSell) {
|
||
|
|
m_log.Info("GRID Sell – první úroveň");
|
||
|
|
m_trade.Sell(volume, m_symbol, bid, 0, 0, "Grid Sell");
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(nBuy > 0 && nSell == 0 && nBuy < m_ctx.gridMaxLevels && gridDistPrice > 0 && canBuy) {
|
||
|
|
double minBuy = m_positions.GetMinOpenPriceBuy();
|
||
|
|
if(minBuy > 0 && ask <= minBuy - gridDistPrice) {
|
||
|
|
m_trade.Buy(volume, m_symbol, ask, 0, 0, "Grid Buy +");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(nSell > 0 && nBuy == 0 && nSell < m_ctx.gridMaxLevels && gridDistPrice > 0 && canSell) {
|
||
|
|
double maxSell = m_positions.GetMaxOpenPriceSell();
|
||
|
|
if(bid >= maxSell + gridDistPrice) {
|
||
|
|
m_trade.Sell(volume, m_symbol, bid, 0, 0, "Grid Sell +");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif
|