//+------------------------------------------------------------------+
//| ea_06.mq4 |
//| Copyright 2023, 100w123 |
//| https://100w123.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, 100w123"
#property link "https://100w123.com"
#property version "1.00"
#property strict
#define SPDLOG
#include <cactus/cactus_common.mqh>
#include <cactus/cactus_log.mqh>
input string C0 = "---- 基本设置 ----";
input int MAGIC = 123456;
input int Slippage = 3; // Slippage(Pips)
input int MaxPosition = 1;
input double BaseLots = 0.01;
input int takeprofit = 0;
input int stoploss = 0;
double Lots;
input string C1 = "双均线交叉策略";
int TimeScale1 = 0;
int Entry1 = 1; // 在前一根 Bar 上形成的信号
//---
input int MA1_1 = 5;
input ENUM_MA_METHOD MaType1_1 = MODE_SMA;
input ENUM_APPLIED_PRICE PriceType1_1 = PRICE_CLOSE;
//---
input int MA1_2 = 20;
input ENUM_MA_METHOD MaType1_2 = MODE_SMA;
input ENUM_APPLIED_PRICE PriceType1_2 = PRICE_CLOSE;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double AdjustPoint(string Currency) {
int Symbol_Digits = (int)MarketInfo(Currency, MODE_DIGITS);
double Calculated_Point = 0;
if (Symbol_Digits == 2 || Symbol_Digits == 3) {
Calculated_Point = 0.01;
} else if (Symbol_Digits == 4 || Symbol_Digits == 5) {
Calculated_Point = 0.0001;
} else if (Symbol_Digits == 1) {
Calculated_Point = 0.1;
} else if (Symbol_Digits == 0) {
Calculated_Point = 1;
}
return (Calculated_Point);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int AdjustSlippage(string Currency, int Slippage_pips) {
int Calculated_Slippage = 0;
int Symbol_Digits = (int)MarketInfo(Currency, MODE_DIGITS);
if (Symbol_Digits == 2 || Symbol_Digits == 3) {
Calculated_Slippage = Slippage_pips;
} else if (Symbol_Digits == 4 || Symbol_Digits == 5) {
Calculated_Slippage = Slippage_pips * 10;
}
return (Calculated_Slippage);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int LongPosition() {
int buys = 0;
for (int i = 0; i < OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true && OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC) {
if (OrderType() == OP_BUY)
buys++;
}
}
return (buys);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int ShortPosition() {
int sells = 0;
for (int i = 0; i < OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true && OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC) {
if (OrderType() == OP_SELL)
sells++;
}
}
return (sells);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OpenOrder(int EntryPosition) {
int res;
bool Modified;
double SL;
double TP;
int SLP = AdjustSlippage(Symbol(), Slippage);
Lots = BaseLots;
if (EntryPosition == 1) {
res = OrderSend(Symbol(), OP_BUY, Lots, Ask, SLP, 0, 0, "test002", MAGIC, 0, Red);
if (res < 0) {
S_LOG_ERROR("OrderSend failed with error #" + GetLastError());
}
if (OrderSelect(res, SELECT_BY_TICKET) == true) {
if (stoploss != 0)
SL = OrderOpenPrice() - stoploss * AdjustPoint(Symbol());
if (takeprofit != 0)
TP = OrderOpenPrice() + takeprofit * AdjustPoint(Symbol());
}
if (SL != 0 || TP != 0)
Modified = OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, Red);
} else if (EntryPosition == -1) {
res = OrderSend(Symbol(), OP_SELL, Lots, Bid, SLP, 0, 0, "test002", MAGIC, 0, White);
if (res < 0) {
S_LOG_ERROR("OrderSend failed with error #" + GetLastError());
}
if (OrderSelect(res, SELECT_BY_TICKET) == true) {
if (stoploss != 0)
SL = OrderOpenPrice() + stoploss * AdjustPoint(Symbol());
if (takeprofit != 0)
TP = OrderOpenPrice() - takeprofit * AdjustPoint(Symbol());
}
if (SL != 0 || TP != 0)
Modified = OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, White);
}
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseOrder(int ClosePosition) {
for (int i = OrdersTotal() - 1; i >= 0; i--) {
int res;
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true) {
if (OrderMagicNumber() == MAGIC && OrderSymbol() == Symbol()) {
if (OrderType() == OP_SELL && (ClosePosition == -1 || ClosePosition == 0)) {
res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10, Silver);
} else if (OrderType() == OP_BUY && (ClosePosition == 1 || ClosePosition == 0)) {
res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10, Silver);
}
}
}
}
}
int Indicator1_19(int i, int TimeScale, int MaPer1, int LineType1, int PType1, int MaPer2, int LineType2, int PType2) {
double Ma1 = iMA(NULL, TimeScale, MaPer1, 0, LineType1, PType1, i);
double Ma2 = iMA(NULL, TimeScale, MaPer2, 0, LineType2, PType2, i);
double Ma1_1 = iMA(NULL, TimeScale, MaPer1, 0, LineType1, PType1, i + 1);
double Ma2_1 = iMA(NULL, TimeScale, MaPer2, 0, LineType2, PType2, i + 1);
int ret = 0;
if (Ma1 > Ma2 && Ma1_1 < Ma2_1) {
ret = 1;
} else if (Ma1 < Ma2 && Ma1_1 > Ma2_1) {
ret = -1;
}
return (ret);
}
int OnInit() {
CONSOLE_CLS();
S_LOG_INIT();
HideTestIndicators(true);
return (INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {
}
void OnTick() {
static datetime bartime = Time[0];
if (Time[0] == bartime)
return;
bartime = Time[0];
int EntryBuy = 0;
int EntrySell = 0;
int ExitBuy = 0;
int ExitSell = 0;
int LongNum = LongPosition();
int ShortNum = ShortPosition();
// 平仓策略
int CloseStrtagy1 = Indicator1_19(1, TimeScale1, MA1_1, MaType1_1, PriceType1_1, MA1_2, MaType1_2, PriceType1_2);
if (LongNum != 0 && (CloseStrtagy1 == -1)) {
ExitBuy = 1;
LongNum = 0;
S_LOG_INFO("%s 平多单", TimeToString(Time[0], TIME_DATE | TIME_MINUTES));
CloseOrder(1);
} else if (ShortNum != 0 && (CloseStrtagy1 == 1)) {
ExitSell = 1;
ShortNum = 0;
S_LOG_INFO("%s 平空单", TimeToString(Time[0], TIME_DATE | TIME_MINUTES));
CloseOrder(-1);
}
// 开仓策略
int Strtagy1 = Indicator1_19(Entry1, TimeScale1, MA1_1, MaType1_1, PriceType1_1, MA1_2, MaType1_2, PriceType1_2);
int TotalNum = ShortNum + LongNum;
if ((TotalNum < MaxPosition && Strtagy1 == 1)) {
EntryBuy = 1;
} else if ((TotalNum < MaxPosition && Strtagy1 == -1)) {
EntrySell = 1;
}
if (EntryBuy != 0) {
S_LOG_INFO("%s 开多单", TimeToString(Time[0], TIME_DATE | TIME_MINUTES));
OpenOrder(1);
}
if (EntrySell != 0) {
S_LOG_INFO("%s 开空单", TimeToString(Time[0], TIME_DATE | TIME_MINUTES));
OpenOrder(-1);
}
}
//+------------------------------------------------------------------+
暂无评论