代码拉取完成,页面将自动刷新
//+------------------------------------------------------------------+
//| MyExpert.mq |
//| Copyright 2020-2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include "./database/PriceHistory.mqh"
#include "./components/AfterOpen.mqh"
#include "./components/BeforeOpen.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMyExpert : public CExpert
{
private:
datetime lastFiveMinutesExecution;
datetime lastHourExecution; // 存储上一次执行任务的时间戳
public:
CMyExpert(void);
virtual ~CMyExpert(void);
virtual bool Processing(void) override;
virtual void OnTimer(void) override;
virtual bool HourChanged(datetime currentTime);
virtual bool FiveMinutesPassed(datetime currentTime);
virtual bool CheckClose() override;
virtual bool OpenLong(double price,double sl,double tp) override;
virtual bool OpenShort(double price,double sl,double tp) override;
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CMyExpert::CMyExpert(void)
{
lastHourExecution = 0;
lastFiveMinutesExecution = 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CMyExpert::~CMyExpert(void)
{
}
//+------------------------------------------------------------------+
//| Custom processing method |
//+------------------------------------------------------------------+
bool CMyExpert::Processing(void)
{
ClosePositionsBasedOnStoch();
//--- calculate signal direction once
m_signal.SetDirection();
//--- check if open positions
if(SelectPosition())
{
if(CheckReverse())
{
return(true);
}
// 是否扛单
if(!CheckClose())
{
// 动态止盈止损
if(CheckTrailingStop())
{
return(true);
}
return(false);
}
}
// 重置马丁次数为 1
martinTimes = MathMax(1, martinTimes / 2);
if(CheckOpen())
return(true);
return(false);
}
//+------------------------------------------------------------------+
//| 每十秒执行一次 |
//+------------------------------------------------------------------+
void CMyExpert::OnTimer()
{
SavePriceHistory();
datetime currentTime = TimeCurrent(); // 获取当前时间
// 如果当前时间与上次执行时间不在同一个小时内
if(HourChanged(currentTime))
{
cleanPriceHistory(currentTime);
lastHourExecution = currentTime;
}
// 如果已经过去5分钟
if(FiveMinutesPassed(currentTime))
{
bool result = ClosePositionsBasedOnStoch();
if(result)
{
lastFiveMinutesExecution = currentTime; // 更新上次执行时间
}
}
return;
}
//+------------------------------------------------------------------+
//| 检查小时是否改变的辅助函数(简化版) |
//+------------------------------------------------------------------+
bool CMyExpert::HourChanged(datetime currentTime)
{
// 计算当前时间与上次执行时间的差值(以秒为单位)
int timeDifference = currentTime - lastHourExecution;
// 如果时间差超过或等于3600秒(1小时),则认为小时已改变
return timeDifference >= 3600;
}
//+------------------------------------------------------------------+
//| 检查是否已经过去5分钟的辅助函数 |
//+------------------------------------------------------------------+
bool CMyExpert::FiveMinutesPassed(datetime currentTime)
{
// 计算当前时间与上次执行时间的差值(以秒为单位)
int timeDifference = currentTime - lastFiveMinutesExecution;
// 如果时间差超过或等于5分钟(300秒),则返回true
return timeDifference >= 300;
}
//+------------------------------------------------------------------+
//| 查询持仓订单,如果目前是亏损则扛单 |
//| 采用马丁倍投策略扛单,扛 3 次 |
//| 每次都是比之前单存在差值,下单手数翻倍 |
//+------------------------------------------------------------------+
bool CMyExpert::CheckClose()
{
MY_ENUM_ORDER_TYPE orderType = doMartin();
if(orderType == MY_ENUM_ORDER_TYPE_UNKNOWN)
return(false);
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
{
return(false);
}
double sl, tp;
bool result = false;
if(orderType == MY_ENUM_ORDER_TYPE_BUY)
{
result = checkFilters(tick.ask, sl, tp, true);
if(result)
{
rejectionReason = StringFormat("马丁格尔倍投, 倍数 %d", martinTimes);
OpenLong(tick.ask, sl, tp);
}
SavePotentialOrder(tick.ask, true, true);
}
else
{
result = checkFilters(tick.ask, sl, tp, false);
if(result)
{
rejectionReason = StringFormat("马丁格尔倍投, 倍数 %d", martinTimes);
OpenShort(tick.bid, sl, tp);
}
SavePotentialOrder(tick.bid, false, true);
}
return(true);
}
//+------------------------------------------------------------------+
//| Long position open or limit/stop order set |
//+------------------------------------------------------------------+
bool CMyExpert::OpenLong(double price,double sl,double tp)
{
if(price==EMPTY_VALUE)
return(false);
//--- get lot for open
double lot=LotOpenLong(price,sl);
//--- check lot for open
lot=LotCheck(lot,price,ORDER_TYPE_BUY);
if(lot==0.0)
return(false);
//--- 在这里循环
for(int i = 0; i < baseLot * martinTimes; i++)
{
m_trade.Buy(lot,price,sl,tp);
}
return(true);
}
//+------------------------------------------------------------------+
//| Short position open or limit/stop order set |
//+------------------------------------------------------------------+
bool CMyExpert::OpenShort(double price,double sl,double tp)
{
if(price==EMPTY_VALUE)
return(false);
//--- get lot for open
double lot=LotOpenShort(price,sl);
//--- check lot for open
lot=LotCheck(lot,price,ORDER_TYPE_SELL);
if(lot==0.0)
return(false);
//---
for(int i = 0; i < baseLot * martinTimes; i++)
{
m_trade.Sell(lot,price,sl,tp);
}
return(true);
}
//+------------------------------------------------------------------+
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。