Tick_Forge/tools/TF_DemoEA.mq5
80 라인
3.4 KiB
MQL5
//+------------------------------------------------------------------+
//| TF_DemoEA.mq5 - a deliberately simple demo Expert for Tick Forge. |
//| It exists only to show what the audit set exposes. MIT licence. |
//| |
//| Rule (both modes): on weekdays, at InpHour server time, buy if |
//| yesterday closed up, sell if it closed down; hold InpHoldHours. |
//| InpMode 0 = LOGIC trades every weekday by that rule. |
//| InpMode 1 = DATE LIST same rule, but ONLY on the dates listed |
//| in InpDates (a stand-in for a fitted, memorised |
//| schedule). |
//+------------------------------------------------------------------+
#property strict
#property version "1.00"
input int InpMode = 0; // 0 = logic, 1 = only on the dates in InpDates
input int InpHour = 10; // entry hour (server time)
input int InpHoldHours = 3; // hours to hold
input double InpLots = 0.10; // volume
input string InpDates = ""; // YYYY.MM.DD,YYYY.MM.DD,... (mode 1)
ulong g_ticket = 0;
datetime g_opened = 0;
string g_dates = "";
int g_last_day = -1;
int OnInit()
{
g_dates = "," + InpDates + ",";
PrintFormat("TF_DemoEA v1.00 | mode=%d hour=%d hold=%d", InpMode, InpHour, InpHoldHours);
return INIT_SUCCEEDED;
}
ENUM_ORDER_TYPE_FILLING Filling()
{
const long m = SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);
if((m & SYMBOL_FILLING_FOK) != 0) return ORDER_FILLING_FOK;
if((m & SYMBOL_FILLING_IOC) != 0) return ORDER_FILLING_IOC;
return ORDER_FILLING_RETURN;
}
bool AllowedToday(const datetime t)
{
if(InpMode == 0) return true;
return StringFind(g_dates, "," + TimeToString(t, TIME_DATE) + ",") >= 0;
}
void OnTick()
{
const datetime now = TimeCurrent();
MqlDateTime dt; TimeToStruct(now, dt);
if(PositionSelect(_Symbol))
{
if(now - g_opened >= InpHoldHours * 3600)
{
MqlTradeRequest r; MqlTradeResult s; ZeroMemory(r); ZeroMemory(s);
r.action = TRADE_ACTION_DEAL; r.symbol = _Symbol; r.volume = PositionGetDouble(POSITION_VOLUME);
const bool buy = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY);
r.type = buy ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
r.price = SymbolInfoDouble(_Symbol, buy ? SYMBOL_BID : SYMBOL_ASK);
r.position = PositionGetInteger(POSITION_TICKET);
r.type_filling = Filling(); r.deviation = 50;
if(!OrderSend(r, s)) Print("TF_DemoEA close failed: ", s.retcode);
}
return;
}
if(dt.day_of_week == 0 || dt.day_of_week == 6) return;
if(dt.hour != InpHour || dt.day_of_year == g_last_day) return;
if(!AllowedToday(now)) return;
MqlRates d[];
if(CopyRates(_Symbol, PERIOD_D1, 1, 1, d) != 1) return;
MqlTradeRequest r; MqlTradeResult s; ZeroMemory(r); ZeroMemory(s);
const bool buy = (d[0].close >= d[0].open);
r.action = TRADE_ACTION_DEAL; r.symbol = _Symbol; r.volume = InpLots;
r.type = buy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
r.price = SymbolInfoDouble(_Symbol, buy ? SYMBOL_ASK : SYMBOL_BID);
r.type_filling = Filling(); r.deviation = 50;
if(OrderSend(r, s) && (s.retcode == TRADE_RETCODE_DONE || s.retcode == TRADE_RETCODE_PLACED))
{ g_opened = now; g_last_day = dt.day_of_year; }
}
//+------------------------------------------------------------------+