|
多单过滤条件:
1,macd15分钟周期(需要可以选择)都在零轴上
开单条件:rsi从下往上 上穿60 开多单
空单过滤条件:
1,macd15分钟周期(需要可以选择)都在零轴下
开单条件:rsi从下往上 上穿40 开多单
出场条件:
亏损5000个点清仓
盈利6000个点开始计算利润,开启移动止损,回撤利润的80%清仓,
源码:
//+------------------------------------------------------------------+
//| MACD_RSI_Pro.mq5 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.06"
#include <Trade\Trade.mqh>
CTrade Trade;
input group "MACD Settings"
input ENUM_TIMEFRAMES MACDTimeframe = PERIOD_M15; // MACD时间框架
input int FastEMA = 12; // 快速EMA周期
input int SlowEMA = 26; // 慢速EMA周期
input int SignalSMA = 9; // 信号线周期
input group "RSI Settings"
input int RSIPeriod = 14; // RSI周期
input ENUM_APPLIED_PRICE RSIPrice = PRICE_CLOSE; // RSI应用价格
input group "Trading Rules"
input double Lots = 0.1; // 交易手数
input int RSIOverbought = 60; // RSI超买水平
input int RSIOversold = 40; // RSI超卖水平
input group "Risk Management"
input int StopLossPoints = 5000; // 止损点数
input int TakeProfitPoints = 6000; // 移动止损启动点数
input double TrailingPercent = 80; // 利润回撤百分比
struct TrailingData {
ulong ticket;
double highest;
double lowest;
};
TrailingData trailArray[];
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(StopLossPoints <= 0 || TakeProfitPoints <= 0 || TrailingPercent <= 0 || TrailingPercent >= 100) {
Alert("参数错误: 请检查止损/止盈/回撤参数!");
return(INIT_PARAMETERS_INCORRECT);
}
Trade.SetExpertMagicNumber(12345);
Trade.SetDeviationInPoints(50);
ArraySetAsSeries(trailArray, true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 追踪止损管理函数 |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket=PositionGetTicket(i);
if(ticket==0 || !PositionSelectByTicket(ticket)) continue;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// 寻找或创建追踪记录
int idx = -1;
for(int j=0; j<ArraySize(trailArray); j++) {
if(trailArray[j].ticket == ticket) {
idx = j;
break;
}
}
// 初始化追踪数据:当价格差达到TakeProfitPoints时
if(idx == -1)
{
double priceDiff;
if(posType == POSITION_TYPE_BUY) {
priceDiff = currentPrice - openPrice;
} else {
priceDiff = openPrice - currentPrice;
}
if(priceDiff >= TakeProfitPoints * _Point)
{
ArrayResize(trailArray, ArraySize(trailArray)+1);
idx = ArraySize(trailArray)-1;
trailArray[idx].ticket = ticket;
trailArray[idx].highest = (posType == POSITION_TYPE_BUY) ? currentPrice : 0;
trailArray[idx].lowest = (posType == POSITION_TYPE_SELL) ? currentPrice : DBL_MAX;
}
}
// 更新价格轨迹并检查止损
if(idx != -1)
{
if(posType == POSITION_TYPE_BUY)
{
trailArray[idx].highest = MathMax(trailArray[idx].highest, currentPrice);
double stopLevel = trailArray[idx].highest - (trailArray[idx].highest - openPrice) * (TrailingPercent / 100.0);
stopLevel = NormalizeDouble(stopLevel, _Digits);
if(currentPrice <= stopLevel)
{
Trade.PositionClose(ticket);
ArrayRemove(trailArray, idx, 1);
}
}
else
{
trailArray[idx].lowest = MathMin(trailArray[idx].lowest, currentPrice);
double stopLevel = trailArray[idx].lowest + (openPrice - trailArray[idx].lowest) * (TrailingPercent / 100.0);
stopLevel = NormalizeDouble(stopLevel, _Digits);
if(currentPrice >= stopLevel)
{
Trade.PositionClose(ticket);
ArrayRemove(trailArray, idx, 1);
}
}
}
}
}
//+------------------------------------------------------------------+
//| 开单条件检查函数 |
//+------------------------------------------------------------------+
void CheckForOpen()
{
// 获取MACD指标
int macdHandle = iMACD(_Symbol, MACDTimeframe, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE);
double macdMain[2];
CopyBuffer(macdHandle, MAIN_LINE, 0, 2, macdMain);
// 获取RSI指标
int rsiHandle = iRSI(_Symbol, MACDTimeframe, RSIPeriod, RSIPrice);
double rsi[2];
CopyBuffer(rsiHandle, 0, 0, 2, rsi);
// 多单条件:MACD双线在零轴上方且RSI上穿60
if(macdMain[0] > 0 && macdMain[1] > 0 && rsi[0] > RSIOverbought && rsi[1] <= RSIOverbought)
{
if(!PositionExist()) {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = NormalizeDouble(ask - StopLossPoints*_Point, _Digits);
Trade.Buy(Lots, _Symbol, ask, sl, 0, "MACD_RSI_Buy");
}
}
// 空单条件:MACD双线在零轴下方且RSI下穿40
if(macdMain[0] < 0 && macdMain[1] < 0 && rsi[0] < RSIOversold && rsi[1] >= RSIOversold)
{
if(!PositionExist()) {
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = NormalizeDouble(bid + StopLossPoints*_Point, _Digits);
Trade.Sell(Lots, _Symbol, bid, sl, 0, "MACD_RSI_Sell");
}
}
}
//+------------------------------------------------------------------+
//| 仓位存在检查函数 |
//+------------------------------------------------------------------+
bool PositionExist()
{
for(int i=0; i<PositionsTotal(); i++) {
ulong ticket=PositionGetTicket(i);
if(ticket>0 && PositionSelectByTicket(ticket)) {
if(PositionGetString(POSITION_SYMBOL) == _Symbol) {
return true;
}
}
}
return false;
}
//+------------------------------------------------------------------+
//| 主执行函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 环境检查
if(!TerminalInfoInteger(TERMINAL_CONNECTED)) return;
if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
if(SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_FULL) return;
ManageTrailingStop();
CheckForOpen();
}
|
|