Add files using upload-large-folder tool
Browse files- MQL5 Folder/0_00-3_00 Range/Diversification.ipynb +340 -0
- MQL5 Folder/0_00-3_00 Range/Refined version.ipynb +0 -0
- MQL5 Folder/0_00-3_00 Range/attempts.ipynb +0 -0
- MQL5 Folder/0_00-3_00 Range/scratch.mql +237 -0
- MQL5 Folder/89RS MT5 version/89RS MT5 version.ipynb +174 -0
- MQL5 Folder/ADX Filter/First candle highlighter with adx.ipynb +178 -0
- MQL5 Folder/ADX Filter/template with 1st candle highlighter.mq5 +86 -0
- MQL5 Folder/Dec25_Volume Profile based breakout momentuim strategy/codeclaude.c++ +445 -0
- MQL5 Folder/Dec25_Volume Profile based breakout momentuim strategy/codegemini.c++ +382 -0
- MQL5 Folder/Dec29_6-8 range/strategy.ipynb +0 -0
- MQL5 Folder/Dec29_6-8 range/v1.c++ +273 -0
- MQL5 Folder/Dec29_6-8 range/v2.c++ +284 -0
- MQL5 Folder/Developing POC/developing POC line.ipynb +34 -0
- MQL5 Folder/H3 0 bar redbear bluebull (indicator)/1_version.mq5 +86 -0
- MQL5 Folder/H3 0 bar redbear bluebull (indicator)/H3 0 bar redbear bluebull (indicator).ipynb +322 -0
- MQL5 Folder/Revised 0-3/1_latestbest.mq5 +256 -0
- MQL5 Folder/Revised 0-3/2_latestbest.mq5 +262 -0
- MQL5 Folder/Revised 0-3/3_latestbest.mw5 +297 -0
- MQL5 Folder/Revised 0-3/4_latestbest.mq5 +294 -0
- MQL5 Folder/Revised 0-3/revised from very begining.ipynb +0 -0
MQL5 Folder/0_00-3_00 Range/Diversification.ipynb
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "54b64fc5",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"make it able to trade all {BTCUSDc\n",
|
| 9 |
+
"AUDCADc\n",
|
| 10 |
+
"AUDCHFc\n",
|
| 11 |
+
"AUDJPYc\n",
|
| 12 |
+
"AUDNZDc\n",
|
| 13 |
+
"AUDUSDc\n",
|
| 14 |
+
"CADJPYc\n",
|
| 15 |
+
"CHFJPYc\n",
|
| 16 |
+
"EURAUDc\n",
|
| 17 |
+
"EURCADc\n",
|
| 18 |
+
"EURCHFc \n",
|
| 19 |
+
"EURGBPc\n",
|
| 20 |
+
"EURJPYc \n",
|
| 21 |
+
"EURNZDc \n",
|
| 22 |
+
"EURUSDc \n",
|
| 23 |
+
"GBPAUDc \n",
|
| 24 |
+
"GBPCADc \n",
|
| 25 |
+
"GBPCHFc \n",
|
| 26 |
+
"GBPJPYc \n",
|
| 27 |
+
"GBPNZDc \n",
|
| 28 |
+
"GBPUSDc \n",
|
| 29 |
+
"NZDJPYc \n",
|
| 30 |
+
"NZDUSDc \n",
|
| 31 |
+
"USDCADc \n",
|
| 32 |
+
"USDCHFc\n",
|
| 33 |
+
"USDHKDc \n",
|
| 34 |
+
"USDJPYc \n",
|
| 35 |
+
"XAGUSDc \n",
|
| 36 |
+
"XAUUSDc }"
|
| 37 |
+
]
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"cell_type": "markdown",
|
| 41 |
+
"id": "794e17b1",
|
| 42 |
+
"metadata": {},
|
| 43 |
+
"source": [
|
| 44 |
+
"trade all of these assets with each 1% risk per trade {NZDUSDc, USDJPYc, XAGUSDc, XAUUSDc} for {#property strict\n",
|
| 45 |
+
"#include <Trade/Trade.mqh>\n",
|
| 46 |
+
"\n",
|
| 47 |
+
"CTrade trade;\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"// =====================\n",
|
| 50 |
+
"// INPUTS\n",
|
| 51 |
+
"// =====================\n",
|
| 52 |
+
"input double RiskPercent = 1.0; // 1% risk per trade\n",
|
| 53 |
+
"input int TimerSec = 5; // timer interval in seconds\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"// =====================\n",
|
| 56 |
+
"// GLOBALS\n",
|
| 57 |
+
"// =====================\n",
|
| 58 |
+
"string TradeSymbol;\n",
|
| 59 |
+
"datetime lastEntryBarTime = 0; // track last entry bar time\n",
|
| 60 |
+
"datetime lastTrailBarTime = 0; // track last trailing bar time\n",
|
| 61 |
+
"\n",
|
| 62 |
+
"double BuyInitialSL = 0.0; // store initial BUY SL\n",
|
| 63 |
+
"double SellInitialSL = 0.0; // store initial SELL SL\n",
|
| 64 |
+
"\n",
|
| 65 |
+
"// =====================\n",
|
| 66 |
+
"// INIT\n",
|
| 67 |
+
"// =====================\n",
|
| 68 |
+
"int OnInit()\n",
|
| 69 |
+
"{\n",
|
| 70 |
+
" TradeSymbol = _Symbol;\n",
|
| 71 |
+
" if(!SymbolSelect(TradeSymbol, true))\n",
|
| 72 |
+
" return INIT_FAILED;\n",
|
| 73 |
+
"\n",
|
| 74 |
+
" EventSetTimer(TimerSec);\n",
|
| 75 |
+
" return INIT_SUCCEEDED;\n",
|
| 76 |
+
"}\n",
|
| 77 |
+
"\n",
|
| 78 |
+
"// =====================\n",
|
| 79 |
+
"void OnDeinit(const int reason)\n",
|
| 80 |
+
"{\n",
|
| 81 |
+
" EventKillTimer();\n",
|
| 82 |
+
"}\n",
|
| 83 |
+
"\n",
|
| 84 |
+
"// =====================\n",
|
| 85 |
+
"void OnTimer()\n",
|
| 86 |
+
"{\n",
|
| 87 |
+
" HandleEntry();\n",
|
| 88 |
+
" HandleReversal();\n",
|
| 89 |
+
" HandleTrailing();\n",
|
| 90 |
+
"}\n",
|
| 91 |
+
"\n",
|
| 92 |
+
"// ============================================================\n",
|
| 93 |
+
"// ENTRY LOGIC\n",
|
| 94 |
+
"// ============================================================\n",
|
| 95 |
+
"void HandleEntry()\n",
|
| 96 |
+
"{\n",
|
| 97 |
+
" // Only one position at a time\n",
|
| 98 |
+
" if(PositionSelect(TradeSymbol))\n",
|
| 99 |
+
" return;\n",
|
| 100 |
+
"\n",
|
| 101 |
+
" // Get the last closed H3 candle\n",
|
| 102 |
+
" datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);\n",
|
| 103 |
+
" if(barTime == 0 || barTime == lastEntryBarTime)\n",
|
| 104 |
+
" return;\n",
|
| 105 |
+
"\n",
|
| 106 |
+
" lastEntryBarTime = barTime;\n",
|
| 107 |
+
"\n",
|
| 108 |
+
" // Confirm this is the 00:00 H3 candle close\n",
|
| 109 |
+
" MqlDateTime t;\n",
|
| 110 |
+
" TimeToStruct(barTime, t);\n",
|
| 111 |
+
" if(t.hour != 0)\n",
|
| 112 |
+
" return;\n",
|
| 113 |
+
"\n",
|
| 114 |
+
" double open = iOpen(TradeSymbol, PERIOD_H3, 1);\n",
|
| 115 |
+
" double close = iClose(TradeSymbol, PERIOD_H3, 1);\n",
|
| 116 |
+
" double low = iLow(TradeSymbol, PERIOD_H3, 1);\n",
|
| 117 |
+
" double high = iHigh(TradeSymbol, PERIOD_H3, 1);\n",
|
| 118 |
+
"\n",
|
| 119 |
+
" trade.SetDeviationInPoints(20);\n",
|
| 120 |
+
" trade.SetTypeFillingBySymbol(TradeSymbol);\n",
|
| 121 |
+
"\n",
|
| 122 |
+
" // ---------------- BUY ----------------\n",
|
| 123 |
+
" if(close > open)\n",
|
| 124 |
+
" {\n",
|
| 125 |
+
" double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);\n",
|
| 126 |
+
" double sl = low;\n",
|
| 127 |
+
" double vol = CalculateRiskVolume(entry, sl);\n",
|
| 128 |
+
" if(vol > 0)\n",
|
| 129 |
+
" {\n",
|
| 130 |
+
" if(trade.Buy(vol, TradeSymbol, entry, sl, 0.0))\n",
|
| 131 |
+
" BuyInitialSL = sl; // store initial SL\n",
|
| 132 |
+
" }\n",
|
| 133 |
+
" }\n",
|
| 134 |
+
"\n",
|
| 135 |
+
" // ---------------- SELL ----------------\n",
|
| 136 |
+
" if(close < open)\n",
|
| 137 |
+
" {\n",
|
| 138 |
+
" double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);\n",
|
| 139 |
+
" double sl = high;\n",
|
| 140 |
+
" double vol = CalculateRiskVolume(entry, sl);\n",
|
| 141 |
+
" if(vol > 0)\n",
|
| 142 |
+
" {\n",
|
| 143 |
+
" if(trade.Sell(vol, TradeSymbol, entry, sl, 0.0))\n",
|
| 144 |
+
" SellInitialSL = sl; // store initial SL\n",
|
| 145 |
+
" }\n",
|
| 146 |
+
" }\n",
|
| 147 |
+
"}\n",
|
| 148 |
+
"\n",
|
| 149 |
+
"// ============================================================\n",
|
| 150 |
+
"// REVERSAL LOGIC (APPLY SPREAD × 10 RULE)\n",
|
| 151 |
+
"// ============================================================\n",
|
| 152 |
+
"void HandleReversal()\n",
|
| 153 |
+
"{\n",
|
| 154 |
+
" double bid = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);\n",
|
| 155 |
+
" double ask = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);\n",
|
| 156 |
+
"\n",
|
| 157 |
+
" // ---------- BUY Reversal ----------\n",
|
| 158 |
+
" if(BuyInitialSL > 0 && !PositionSelect(TradeSymbol))\n",
|
| 159 |
+
" {\n",
|
| 160 |
+
" if(bid <= BuyInitialSL) // BUY SL hit\n",
|
| 161 |
+
" {\n",
|
| 162 |
+
" datetime firstBullishBarTime = FindFirstBullishH3From0();\n",
|
| 163 |
+
" if(firstBullishBarTime > 0)\n",
|
| 164 |
+
" {\n",
|
| 165 |
+
" int shift = iBarShift(TradeSymbol, PERIOD_H3, firstBullishBarTime);\n",
|
| 166 |
+
" double sl = iHigh(TradeSymbol, PERIOD_H3, shift);\n",
|
| 167 |
+
"\n",
|
| 168 |
+
" // check spread x 10 rule\n",
|
| 169 |
+
" double vol = CalculateRiskVolume(bid, sl);\n",
|
| 170 |
+
" if(vol > 0)\n",
|
| 171 |
+
" {\n",
|
| 172 |
+
" if(trade.Sell(vol, TradeSymbol, bid, sl, 0.0))\n",
|
| 173 |
+
" BuyInitialSL = 0.0; // reset\n",
|
| 174 |
+
" }\n",
|
| 175 |
+
" }\n",
|
| 176 |
+
" }\n",
|
| 177 |
+
" }\n",
|
| 178 |
+
"\n",
|
| 179 |
+
" // ---------- SELL Reversal ----------\n",
|
| 180 |
+
" if(SellInitialSL > 0 && !PositionSelect(TradeSymbol))\n",
|
| 181 |
+
" {\n",
|
| 182 |
+
" if(ask >= SellInitialSL) // SELL SL hit\n",
|
| 183 |
+
" {\n",
|
| 184 |
+
" datetime firstBearishBarTime = FindFirstBearishH3From0();\n",
|
| 185 |
+
" if(firstBearishBarTime > 0)\n",
|
| 186 |
+
" {\n",
|
| 187 |
+
" int shift = iBarShift(TradeSymbol, PERIOD_H3, firstBearishBarTime);\n",
|
| 188 |
+
" double sl = iLow(TradeSymbol, PERIOD_H3, shift);\n",
|
| 189 |
+
"\n",
|
| 190 |
+
" // check spread x 10 rule\n",
|
| 191 |
+
" double vol = CalculateRiskVolume(ask, sl);\n",
|
| 192 |
+
" if(vol > 0)\n",
|
| 193 |
+
" {\n",
|
| 194 |
+
" if(trade.Buy(vol, TradeSymbol, ask, sl, 0.0))\n",
|
| 195 |
+
" SellInitialSL = 0.0; // reset\n",
|
| 196 |
+
" }\n",
|
| 197 |
+
" }\n",
|
| 198 |
+
" }\n",
|
| 199 |
+
" }\n",
|
| 200 |
+
"}\n",
|
| 201 |
+
"\n",
|
| 202 |
+
"// ============================================================\n",
|
| 203 |
+
"// TRAILING LOGIC (STRICT RULES)\n",
|
| 204 |
+
"// ============================================================\n",
|
| 205 |
+
"void HandleTrailing()\n",
|
| 206 |
+
"{\n",
|
| 207 |
+
" if(!PositionSelect(TradeSymbol))\n",
|
| 208 |
+
" return;\n",
|
| 209 |
+
"\n",
|
| 210 |
+
" // Trailing only after H3 candle closes\n",
|
| 211 |
+
" datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);\n",
|
| 212 |
+
" if(barTime == 0 || barTime == lastTrailBarTime)\n",
|
| 213 |
+
" return;\n",
|
| 214 |
+
"\n",
|
| 215 |
+
" lastTrailBarTime = barTime;\n",
|
| 216 |
+
"\n",
|
| 217 |
+
" long type = PositionGetInteger(POSITION_TYPE);\n",
|
| 218 |
+
" double currentSL = PositionGetDouble(POSITION_SL);\n",
|
| 219 |
+
"\n",
|
| 220 |
+
" double open = iOpen(TradeSymbol, PERIOD_H3, 1);\n",
|
| 221 |
+
" double close = iClose(TradeSymbol, PERIOD_H3, 1);\n",
|
| 222 |
+
" double low = iLow(TradeSymbol, PERIOD_H3, 1);\n",
|
| 223 |
+
" double high = iHigh(TradeSymbol, PERIOD_H3, 1);\n",
|
| 224 |
+
"\n",
|
| 225 |
+
" // ---------------- BUY ----------------\n",
|
| 226 |
+
" if(type == POSITION_TYPE_BUY)\n",
|
| 227 |
+
" {\n",
|
| 228 |
+
" if(close > open && low > currentSL)\n",
|
| 229 |
+
" trade.PositionModify(TradeSymbol, low, 0.0);\n",
|
| 230 |
+
" }\n",
|
| 231 |
+
"\n",
|
| 232 |
+
" // ---------------- SELL ----------------\n",
|
| 233 |
+
" if(type == POSITION_TYPE_SELL)\n",
|
| 234 |
+
" {\n",
|
| 235 |
+
" if(close < open && high < currentSL)\n",
|
| 236 |
+
" trade.PositionModify(TradeSymbol, high, 0.0);\n",
|
| 237 |
+
" }\n",
|
| 238 |
+
"}\n",
|
| 239 |
+
"\n",
|
| 240 |
+
"// ============================================================\n",
|
| 241 |
+
"// RISK-BASED LOT CALCULATION (APPLY SPREAD × 10 RULE)\n",
|
| 242 |
+
"// ============================================================\n",
|
| 243 |
+
"double CalculateRiskVolume(double entry, double stop)\n",
|
| 244 |
+
"{\n",
|
| 245 |
+
" double distance = MathAbs(entry - stop);\n",
|
| 246 |
+
" if(distance <= 0)\n",
|
| 247 |
+
" return 0;\n",
|
| 248 |
+
"\n",
|
| 249 |
+
" // spread x 10 rule\n",
|
| 250 |
+
" int spread_points = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD);\n",
|
| 251 |
+
" double spread = spread_points * SymbolInfoDouble(TradeSymbol, SYMBOL_POINT);\n",
|
| 252 |
+
" if(distance < spread * 10)\n",
|
| 253 |
+
" return 0;\n",
|
| 254 |
+
"\n",
|
| 255 |
+
" double balance = AccountInfoDouble(ACCOUNT_BALANCE);\n",
|
| 256 |
+
" double riskAmt = balance * (RiskPercent / 100.0);\n",
|
| 257 |
+
"\n",
|
| 258 |
+
" double tickSize = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_SIZE);\n",
|
| 259 |
+
" double tickValue = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_VALUE);\n",
|
| 260 |
+
"\n",
|
| 261 |
+
" double costPerLot = (distance / tickSize) * tickValue;\n",
|
| 262 |
+
" if(costPerLot <= 0)\n",
|
| 263 |
+
" return 0;\n",
|
| 264 |
+
"\n",
|
| 265 |
+
" double volume = riskAmt / costPerLot;\n",
|
| 266 |
+
"\n",
|
| 267 |
+
" double minLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MIN);\n",
|
| 268 |
+
" double maxLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MAX);\n",
|
| 269 |
+
" double stepLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_STEP);\n",
|
| 270 |
+
"\n",
|
| 271 |
+
" volume = MathFloor(volume / stepLot) * stepLot;\n",
|
| 272 |
+
" volume = MathMax(volume, minLot);\n",
|
| 273 |
+
" volume = MathMin(volume, maxLot);\n",
|
| 274 |
+
"\n",
|
| 275 |
+
" return volume;\n",
|
| 276 |
+
"}\n",
|
| 277 |
+
"\n",
|
| 278 |
+
"// ============================================================\n",
|
| 279 |
+
"// HELPER FUNCTIONS TO FIND FIRST H3 BULLISH/BEARISH BAR FROM 0:00\n",
|
| 280 |
+
"// ============================================================\n",
|
| 281 |
+
"datetime FindFirstBullishH3From0()\n",
|
| 282 |
+
"{\n",
|
| 283 |
+
" MqlDateTime t;\n",
|
| 284 |
+
" datetime today = iTime(TradeSymbol, PERIOD_D1, 0);\n",
|
| 285 |
+
" TimeToStruct(today, t);\n",
|
| 286 |
+
" datetime start = StructToTime(t);\n",
|
| 287 |
+
"\n",
|
| 288 |
+
" for(int i=0; i<50; i++)\n",
|
| 289 |
+
" {\n",
|
| 290 |
+
" datetime bar = iTime(TradeSymbol, PERIOD_H3, i);\n",
|
| 291 |
+
" if(bar < start) break;\n",
|
| 292 |
+
" double open = iOpen(TradeSymbol, PERIOD_H3, i);\n",
|
| 293 |
+
" double close = iClose(TradeSymbol, PERIOD_H3, i);\n",
|
| 294 |
+
" if(close > open) return bar;\n",
|
| 295 |
+
" }\n",
|
| 296 |
+
" return 0;\n",
|
| 297 |
+
"}\n",
|
| 298 |
+
"\n",
|
| 299 |
+
"datetime FindFirstBearishH3From0()\n",
|
| 300 |
+
"{\n",
|
| 301 |
+
" MqlDateTime t;\n",
|
| 302 |
+
" datetime today = iTime(TradeSymbol, PERIOD_D1, 0);\n",
|
| 303 |
+
" TimeToStruct(today, t);\n",
|
| 304 |
+
" datetime start = StructToTime(t);\n",
|
| 305 |
+
"\n",
|
| 306 |
+
" for(int i=0; i<50; i++)\n",
|
| 307 |
+
" {\n",
|
| 308 |
+
" datetime bar = iTime(TradeSymbol, PERIOD_H3, i);\n",
|
| 309 |
+
" if(bar < start) break;\n",
|
| 310 |
+
" double open = iOpen(TradeSymbol, PERIOD_H3, i);\n",
|
| 311 |
+
" double close = iClose(TradeSymbol, PERIOD_H3, i);\n",
|
| 312 |
+
" if(close < open) return bar;\n",
|
| 313 |
+
" }\n",
|
| 314 |
+
" return 0;\n",
|
| 315 |
+
"}\n",
|
| 316 |
+
"}"
|
| 317 |
+
]
|
| 318 |
+
},
|
| 319 |
+
{
|
| 320 |
+
"attachments": {
|
| 321 |
+
"image.png": {
|
| 322 |
+
"image/png": "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"
|
| 323 |
+
}
|
| 324 |
+
},
|
| 325 |
+
"cell_type": "markdown",
|
| 326 |
+
"id": "33da4df1",
|
| 327 |
+
"metadata": {},
|
| 328 |
+
"source": [
|
| 329 |
+
""
|
| 330 |
+
]
|
| 331 |
+
}
|
| 332 |
+
],
|
| 333 |
+
"metadata": {
|
| 334 |
+
"language_info": {
|
| 335 |
+
"name": "python"
|
| 336 |
+
}
|
| 337 |
+
},
|
| 338 |
+
"nbformat": 4,
|
| 339 |
+
"nbformat_minor": 5
|
| 340 |
+
}
|
MQL5 Folder/0_00-3_00 Range/Refined version.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
MQL5 Folder/0_00-3_00 Range/attempts.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
MQL5 Folder/0_00-3_00 Range/scratch.mql
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property strict
|
| 2 |
+
#include <Trade/Trade.mqh>
|
| 3 |
+
|
| 4 |
+
CTrade trade;
|
| 5 |
+
|
| 6 |
+
// =====================
|
| 7 |
+
// INPUTS
|
| 8 |
+
// =====================
|
| 9 |
+
input double RiskPercent = 1.0;
|
| 10 |
+
input int TimerSec = 5;
|
| 11 |
+
|
| 12 |
+
// =====================
|
| 13 |
+
// SYMBOLS
|
| 14 |
+
// =====================
|
| 15 |
+
string TradeSymbols[] =
|
| 16 |
+
{
|
| 17 |
+
"NZDUSDc",
|
| 18 |
+
"USDJPYc",
|
| 19 |
+
"XAGUSDc",
|
| 20 |
+
"XAUUSDc"
|
| 21 |
+
};
|
| 22 |
+
#define SYM_COUNT 4
|
| 23 |
+
|
| 24 |
+
// =====================
|
| 25 |
+
// PER-SYMBOL STATE
|
| 26 |
+
// =====================
|
| 27 |
+
datetime lastEntryBar[SYM_COUNT];
|
| 28 |
+
datetime lastTrailBar[SYM_COUNT];
|
| 29 |
+
|
| 30 |
+
double lastBuySL[SYM_COUNT];
|
| 31 |
+
double lastSellSL[SYM_COUNT];
|
| 32 |
+
|
| 33 |
+
bool buyStoppedLoss[SYM_COUNT];
|
| 34 |
+
bool sellStoppedLoss[SYM_COUNT];
|
| 35 |
+
|
| 36 |
+
// =====================
|
| 37 |
+
// INIT
|
| 38 |
+
// =====================
|
| 39 |
+
int OnInit()
|
| 40 |
+
{
|
| 41 |
+
for(int i=0;i<SYM_COUNT;i++)
|
| 42 |
+
{
|
| 43 |
+
SymbolSelect(TradeSymbols[i],true);
|
| 44 |
+
lastEntryBar[i]=0;
|
| 45 |
+
lastTrailBar[i]=0;
|
| 46 |
+
lastBuySL[i]=0;
|
| 47 |
+
lastSellSL[i]=0;
|
| 48 |
+
buyStoppedLoss[i]=false;
|
| 49 |
+
sellStoppedLoss[i]=false;
|
| 50 |
+
}
|
| 51 |
+
EventSetTimer(TimerSec);
|
| 52 |
+
return INIT_SUCCEEDED;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
void OnDeinit(const int reason)
|
| 56 |
+
{
|
| 57 |
+
EventKillTimer();
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
void OnTimer()
|
| 61 |
+
{
|
| 62 |
+
for(int i=0;i<SYM_COUNT;i++)
|
| 63 |
+
{
|
| 64 |
+
HandleEntry(i);
|
| 65 |
+
HandleReversal(i);
|
| 66 |
+
HandleTrailing(i);
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// ============================================================
|
| 71 |
+
// ORIGINAL ENTRY (ONLY 0:00–3:00 H3 BAR)
|
| 72 |
+
// ============================================================
|
| 73 |
+
void HandleEntry(int i)
|
| 74 |
+
{
|
| 75 |
+
string s = TradeSymbols[i];
|
| 76 |
+
|
| 77 |
+
if(PositionSelect(s))
|
| 78 |
+
return;
|
| 79 |
+
|
| 80 |
+
datetime barTime = iTime(s,PERIOD_H3,1);
|
| 81 |
+
if(barTime==0 || barTime==lastEntryBar[i])
|
| 82 |
+
return;
|
| 83 |
+
|
| 84 |
+
lastEntryBar[i]=barTime;
|
| 85 |
+
|
| 86 |
+
MqlDateTime t;
|
| 87 |
+
TimeToStruct(barTime,t);
|
| 88 |
+
if(t.hour!=0) return;
|
| 89 |
+
|
| 90 |
+
double o=iOpen(s,PERIOD_H3,1);
|
| 91 |
+
double c=iClose(s,PERIOD_H3,1);
|
| 92 |
+
double l=iLow(s,PERIOD_H3,1);
|
| 93 |
+
double h=iHigh(s,PERIOD_H3,1);
|
| 94 |
+
|
| 95 |
+
trade.SetDeviationInPoints(20);
|
| 96 |
+
trade.SetTypeFillingBySymbol(s);
|
| 97 |
+
|
| 98 |
+
if(c>o)
|
| 99 |
+
{
|
| 100 |
+
double entry=SymbolInfoDouble(s,SYMBOL_ASK);
|
| 101 |
+
double sl=l;
|
| 102 |
+
double vol=CalcRiskVol(s,entry,sl);
|
| 103 |
+
if(vol>0 && trade.Buy(vol,s,entry,sl,0))
|
| 104 |
+
{
|
| 105 |
+
lastBuySL[i]=sl;
|
| 106 |
+
buyStoppedLoss[i]=false;
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
else if(c<o)
|
| 110 |
+
{
|
| 111 |
+
double entry=SymbolInfoDouble(s,SYMBOL_BID);
|
| 112 |
+
double sl=h;
|
| 113 |
+
double vol=CalcRiskVol(s,entry,sl);
|
| 114 |
+
if(vol>0 && trade.Sell(vol,s,entry,sl,0))
|
| 115 |
+
{
|
| 116 |
+
lastSellSL[i]=sl;
|
| 117 |
+
sellStoppedLoss[i]=false;
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// ============================================================
|
| 123 |
+
// REVERSAL ENTRY (ONLY NEGATIVE STOP OUT)
|
| 124 |
+
// ============================================================
|
| 125 |
+
void HandleReversal(int i)
|
| 126 |
+
{
|
| 127 |
+
string s=TradeSymbols[i];
|
| 128 |
+
|
| 129 |
+
if(PositionSelect(s))
|
| 130 |
+
return;
|
| 131 |
+
|
| 132 |
+
double bid=SymbolInfoDouble(s,SYMBOL_BID);
|
| 133 |
+
double ask=SymbolInfoDouble(s,SYMBOL_ASK);
|
| 134 |
+
|
| 135 |
+
// BUY STOPPED → SELL
|
| 136 |
+
if(lastBuySL[i]>0 && !buyStoppedLoss[i])
|
| 137 |
+
{
|
| 138 |
+
if(bid<=lastBuySL[i])
|
| 139 |
+
{
|
| 140 |
+
buyStoppedLoss[i]=true;
|
| 141 |
+
|
| 142 |
+
double entry=bid;
|
| 143 |
+
double sl=iHigh(s,PERIOD_H3,1);
|
| 144 |
+
double vol=CalcRiskVol(s,entry,sl);
|
| 145 |
+
if(vol>0)
|
| 146 |
+
trade.Sell(vol,s,entry,sl,0);
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
// SELL STOPPED → BUY
|
| 151 |
+
if(lastSellSL[i]>0 && !sellStoppedLoss[i])
|
| 152 |
+
{
|
| 153 |
+
if(ask>=lastSellSL[i])
|
| 154 |
+
{
|
| 155 |
+
sellStoppedLoss[i]=true;
|
| 156 |
+
|
| 157 |
+
double entry=ask;
|
| 158 |
+
double sl=iLow(s,PERIOD_H3,1);
|
| 159 |
+
double vol=CalcRiskVol(s,entry,sl);
|
| 160 |
+
if(vol>0)
|
| 161 |
+
trade.Buy(vol,s,entry,sl,0);
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
// ============================================================
|
| 167 |
+
// TRAILING (H3 CLOSE ONLY, SAME-COLOR ONLY, INFINITE)
|
| 168 |
+
// ============================================================
|
| 169 |
+
void HandleTrailing(int i)
|
| 170 |
+
{
|
| 171 |
+
string s=TradeSymbols[i];
|
| 172 |
+
|
| 173 |
+
if(!PositionSelect(s))
|
| 174 |
+
return;
|
| 175 |
+
|
| 176 |
+
datetime barTime=iTime(s,PERIOD_H3,1);
|
| 177 |
+
if(barTime==0 || barTime==lastTrailBar[i])
|
| 178 |
+
return;
|
| 179 |
+
|
| 180 |
+
lastTrailBar[i]=barTime;
|
| 181 |
+
|
| 182 |
+
long type=PositionGetInteger(POSITION_TYPE);
|
| 183 |
+
double curSL=PositionGetDouble(POSITION_SL);
|
| 184 |
+
|
| 185 |
+
double o=iOpen(s,PERIOD_H3,1);
|
| 186 |
+
double c=iClose(s,PERIOD_H3,1);
|
| 187 |
+
double l=iLow(s,PERIOD_H3,1);
|
| 188 |
+
double h=iHigh(s,PERIOD_H3,1);
|
| 189 |
+
|
| 190 |
+
if(type==POSITION_TYPE_BUY)
|
| 191 |
+
{
|
| 192 |
+
if(c>o && l>curSL)
|
| 193 |
+
trade.PositionModify(s,l,0);
|
| 194 |
+
}
|
| 195 |
+
else if(type==POSITION_TYPE_SELL)
|
| 196 |
+
{
|
| 197 |
+
if(c<o && h<curSL)
|
| 198 |
+
trade.PositionModify(s,h,0);
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
// ============================================================
|
| 203 |
+
// RISK & SPREAD ×10 FILTER
|
| 204 |
+
// ============================================================
|
| 205 |
+
double CalcRiskVol(string s,double entry,double sl)
|
| 206 |
+
{
|
| 207 |
+
double dist=MathAbs(entry-sl);
|
| 208 |
+
if(dist<=0) return 0;
|
| 209 |
+
|
| 210 |
+
double spread=
|
| 211 |
+
SymbolInfoInteger(s,SYMBOL_SPREAD) *
|
| 212 |
+
SymbolInfoDouble(s,SYMBOL_POINT);
|
| 213 |
+
|
| 214 |
+
if(dist < spread*10) return 0;
|
| 215 |
+
|
| 216 |
+
double risk=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/100.0;
|
| 217 |
+
|
| 218 |
+
double tickSize=SymbolInfoDouble(s,SYMBOL_TRADE_TICK_SIZE);
|
| 219 |
+
double tickVal =SymbolInfoDouble(s,SYMBOL_TRADE_TICK_VALUE);
|
| 220 |
+
|
| 221 |
+
double cost=(dist/tickSize)*tickVal;
|
| 222 |
+
if(cost<=0) return 0;
|
| 223 |
+
|
| 224 |
+
double vol=risk/cost;
|
| 225 |
+
|
| 226 |
+
double minLot=SymbolInfoDouble(s,SYMBOL_VOLUME_MIN);
|
| 227 |
+
double maxLot=SymbolInfoDouble(s,SYMBOL_VOLUME_MAX);
|
| 228 |
+
double step =SymbolInfoDouble(s,SYMBOL_VOLUME_STEP);
|
| 229 |
+
|
| 230 |
+
vol=MathFloor(vol/step)*step;
|
| 231 |
+
vol=MathMax(vol,minLot);
|
| 232 |
+
vol=MathMin(vol,maxLot);
|
| 233 |
+
|
| 234 |
+
return vol;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
{gg as}
|
MQL5 Folder/89RS MT5 version/89RS MT5 version.ipynb
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "0d3db06f",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"analyzed, extract, and exammine the lines-of-code and create a corrected version of the code addressing the red error from \"Description, File, Line, Column\"-formatted-toolbox-terminal-in-mt5-platform statements; it is saying:{}"
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "1fc41fb6",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"make everything ideal in live environment, use your knowledge to enchance the code"
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "markdown",
|
| 21 |
+
"id": "2bb937c2",
|
| 22 |
+
"metadata": {},
|
| 23 |
+
"source": []
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"cell_type": "markdown",
|
| 27 |
+
"id": "ec950491",
|
| 28 |
+
"metadata": {},
|
| 29 |
+
"source": [
|
| 30 |
+
"{Design the code ideal for live executions and live environment, robust, with no errors} {Do not make unnecessary inputs }"
|
| 31 |
+
]
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"cell_type": "markdown",
|
| 35 |
+
"id": "7738ccfb",
|
| 36 |
+
"metadata": {},
|
| 37 |
+
"source": [
|
| 38 |
+
"make an EA using MT5 MQL5, Use MQL5, do not ever mix MT4-style functions in MT5, do not ever use the MT4-style helper. Use onTimer() logic is ideal for a live environment. \n",
|
| 39 |
+
"\n",
|
| 40 |
+
"Wait for H1-12pm-candle to close. Then after, locate the highest high and lowest low of that range or candle. Place buystop at the high, and the stoploss is at the middle of the range. Place sellstop at the low, and the stoploss is at the middle of the range. Risking 1% for each trade, accounting for the individual stop-loss distance. The take profit is 2R-multiple. These stoporders (both buystop and sellstop) are only valid within its coresponding day.{Design the code ideal for live executions and live environment, robust, with no errors} {Do not make unnecessary inputs }"
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"cell_type": "markdown",
|
| 45 |
+
"id": "9ab6b4aa",
|
| 46 |
+
"metadata": {},
|
| 47 |
+
"source": [
|
| 48 |
+
"//+------------------------------------------------------------------+\n",
|
| 49 |
+
"//| BreakoutEA.mq5 |\n",
|
| 50 |
+
"//| Robust MT5 EA using OnTimer |\n",
|
| 51 |
+
"//+------------------------------------------------------------------+\n",
|
| 52 |
+
"#include <Trade/Trade.mqh>\n",
|
| 53 |
+
"CTrade trade;\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"//--- Global variables\n",
|
| 56 |
+
"datetime lastProcessed = 0;\n",
|
| 57 |
+
"\n",
|
| 58 |
+
"//+------------------------------------------------------------------+\n",
|
| 59 |
+
"//| Expert initialization function |\n",
|
| 60 |
+
"//+------------------------------------------------------------------+\n",
|
| 61 |
+
"int OnInit()\n",
|
| 62 |
+
"{\n",
|
| 63 |
+
" // Set timer to check every 60 seconds\n",
|
| 64 |
+
" EventSetTimer(60);\n",
|
| 65 |
+
" return(INIT_SUCCEEDED);\n",
|
| 66 |
+
"}\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"//+------------------------------------------------------------------+\n",
|
| 69 |
+
"//| Expert deinitialization function |\n",
|
| 70 |
+
"//+------------------------------------------------------------------+\n",
|
| 71 |
+
"void OnDeinit(const int reason)\n",
|
| 72 |
+
"{\n",
|
| 73 |
+
" EventKillTimer();\n",
|
| 74 |
+
"}\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"//+------------------------------------------------------------------+\n",
|
| 77 |
+
"//| Timer function for live environment |\n",
|
| 78 |
+
"//+------------------------------------------------------------------+\n",
|
| 79 |
+
"void OnTimer()\n",
|
| 80 |
+
"{\n",
|
| 81 |
+
" datetime currentTime = TimeCurrent();\n",
|
| 82 |
+
" MqlDateTime tm;\n",
|
| 83 |
+
" TimeToStruct(currentTime, tm);\n",
|
| 84 |
+
"\n",
|
| 85 |
+
" // Only trigger after 12:00 H1 candle close\n",
|
| 86 |
+
" if(tm.hour == 12 && lastProcessed != iTime(_Symbol, PERIOD_H1, 1))\n",
|
| 87 |
+
" {\n",
|
| 88 |
+
" lastProcessed = iTime(_Symbol, PERIOD_H1, 1); // Record last processed candle\n",
|
| 89 |
+
" ProcessBreakout();\n",
|
| 90 |
+
" }\n",
|
| 91 |
+
"}\n",
|
| 92 |
+
"\n",
|
| 93 |
+
"//+------------------------------------------------------------------+\n",
|
| 94 |
+
"//| Main processing function |\n",
|
| 95 |
+
"//+------------------------------------------------------------------+\n",
|
| 96 |
+
"void ProcessBreakout()\n",
|
| 97 |
+
"{\n",
|
| 98 |
+
" // Get last closed H1 candle\n",
|
| 99 |
+
" double h = iHigh(_Symbol, PERIOD_H1, 1);\n",
|
| 100 |
+
" double l = iLow(_Symbol, PERIOD_H1, 1);\n",
|
| 101 |
+
"\n",
|
| 102 |
+
" double rangeMid = (h + l) / 2.0;\n",
|
| 103 |
+
"\n",
|
| 104 |
+
" // Calculate distance for SL and TP in price\n",
|
| 105 |
+
" double slDistance = MathAbs(h - rangeMid); // Same for both sides\n",
|
| 106 |
+
" double tpDistance = slDistance * 2; // 2R take profit\n",
|
| 107 |
+
"\n",
|
| 108 |
+
" // Calculate lot size to risk 1% of account\n",
|
| 109 |
+
" double riskPercent = 1.0;\n",
|
| 110 |
+
" double lot = CalculateLotSize(slDistance, riskPercent);\n",
|
| 111 |
+
"\n",
|
| 112 |
+
" if(lot <= 0)\n",
|
| 113 |
+
" return; // If lot is too small, skip\n",
|
| 114 |
+
"\n",
|
| 115 |
+
" // Place BuyStop above high\n",
|
| 116 |
+
" double buyPrice = h;\n",
|
| 117 |
+
" double buySL = rangeMid;\n",
|
| 118 |
+
" double buyTP = buyPrice + tpDistance;\n",
|
| 119 |
+
"\n",
|
| 120 |
+
" trade.BuyStop(lot, buyPrice, _Symbol, buySL, buyTP, ORDER_TIME_DAY, 0, \"H1 12PM BuyStop\");\n",
|
| 121 |
+
"\n",
|
| 122 |
+
" // Place SellStop below low\n",
|
| 123 |
+
" double sellPrice = l;\n",
|
| 124 |
+
" double sellSL = rangeMid;\n",
|
| 125 |
+
" double sellTP = sellPrice - tpDistance;\n",
|
| 126 |
+
"\n",
|
| 127 |
+
" trade.SellStop(lot, sellPrice, _Symbol, sellSL, sellTP, ORDER_TIME_DAY, 0, \"H1 12PM SellStop\");\n",
|
| 128 |
+
"}\n",
|
| 129 |
+
"\n",
|
| 130 |
+
"//+------------------------------------------------------------------+\n",
|
| 131 |
+
"//| Calculate lot size based on risk % |\n",
|
| 132 |
+
"//+------------------------------------------------------------------+\n",
|
| 133 |
+
"double CalculateLotSize(double slDistance, double riskPercent)\n",
|
| 134 |
+
"{\n",
|
| 135 |
+
" if(slDistance <= 0)\n",
|
| 136 |
+
" return 0;\n",
|
| 137 |
+
"\n",
|
| 138 |
+
" double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);\n",
|
| 139 |
+
" double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);\n",
|
| 140 |
+
" double accountRisk = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100.0;\n",
|
| 141 |
+
"\n",
|
| 142 |
+
" // Lot calculation: lot = risk / (SL in price * tick value)\n",
|
| 143 |
+
" double lot = accountRisk / (slDistance * tickValue / tickSize);\n",
|
| 144 |
+
"\n",
|
| 145 |
+
" // Round lot to symbol precision\n",
|
| 146 |
+
" double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);\n",
|
| 147 |
+
" lot = MathFloor(lot/step) * step;\n",
|
| 148 |
+
"\n",
|
| 149 |
+
" // Ensure minimum volume\n",
|
| 150 |
+
" double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);\n",
|
| 151 |
+
" if(lot < minLot)\n",
|
| 152 |
+
" lot = 0;\n",
|
| 153 |
+
"\n",
|
| 154 |
+
" return lot;\n",
|
| 155 |
+
"}\n"
|
| 156 |
+
]
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"cell_type": "markdown",
|
| 160 |
+
"id": "7b583fa3",
|
| 161 |
+
"metadata": {},
|
| 162 |
+
"source": [
|
| 163 |
+
"note: its truly worse"
|
| 164 |
+
]
|
| 165 |
+
}
|
| 166 |
+
],
|
| 167 |
+
"metadata": {
|
| 168 |
+
"language_info": {
|
| 169 |
+
"name": "python"
|
| 170 |
+
}
|
| 171 |
+
},
|
| 172 |
+
"nbformat": 4,
|
| 173 |
+
"nbformat_minor": 5
|
| 174 |
+
}
|
MQL5 Folder/ADX Filter/First candle highlighter with adx.ipynb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "7a1ca979",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"Make an MT5 indicator that highlights the corresponding candle red if bearish and blue if bullish on the very first candlestick formed at 0:00. Use MQL5, do not ever mix MT4-style functions in MT5, do not ever use the MT4-style helper. "
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "036e1127",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"#property indicator_chart_window\n",
|
| 17 |
+
"#property indicator_buffers 5\n",
|
| 18 |
+
"#property indicator_plots 1\n",
|
| 19 |
+
"\n",
|
| 20 |
+
"#property indicator_type1 DRAW_COLOR_CANDLES\n",
|
| 21 |
+
"#property indicator_color1 clrBlue, clrRed\n",
|
| 22 |
+
"#property indicator_label1 \"First Daily Candle\"\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"//--- buffers\n",
|
| 25 |
+
"double OpenBuf[];\n",
|
| 26 |
+
"double HighBuf[];\n",
|
| 27 |
+
"double LowBuf[];\n",
|
| 28 |
+
"double CloseBuf[];\n",
|
| 29 |
+
"double ColorBuf[];\n",
|
| 30 |
+
"\n",
|
| 31 |
+
"//--- colors index\n",
|
| 32 |
+
"#define BULL 0\n",
|
| 33 |
+
"#define BEAR 1\n",
|
| 34 |
+
"\n",
|
| 35 |
+
"int OnInit()\n",
|
| 36 |
+
"{\n",
|
| 37 |
+
" SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);\n",
|
| 38 |
+
" SetIndexBuffer(1, HighBuf, INDICATOR_DATA);\n",
|
| 39 |
+
" SetIndexBuffer(2, LowBuf, INDICATOR_DATA);\n",
|
| 40 |
+
" SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);\n",
|
| 41 |
+
" SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);\n",
|
| 42 |
+
"\n",
|
| 43 |
+
" PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1);\n",
|
| 44 |
+
"\n",
|
| 45 |
+
" //--- chart appearance\n",
|
| 46 |
+
" ChartSetInteger(0, CHART_SHOW_GRID, false); // remove grid\n",
|
| 47 |
+
" ChartSetInteger(0, CHART_SHOW_BID_LINE, true); // show bid line\n",
|
| 48 |
+
" ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); // show ask line\n",
|
| 49 |
+
"\n",
|
| 50 |
+
" return(INIT_SUCCEEDED);\n",
|
| 51 |
+
"}\n",
|
| 52 |
+
"\n",
|
| 53 |
+
"int OnCalculate(\n",
|
| 54 |
+
" const int rates_total,\n",
|
| 55 |
+
" const int prev_calcula_\n"
|
| 56 |
+
]
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"cell_type": "markdown",
|
| 60 |
+
"id": "f3293169",
|
| 61 |
+
"metadata": {},
|
| 62 |
+
"source": [
|
| 63 |
+
"#property indicator_chart_window\n",
|
| 64 |
+
"#property indicator_buffers 10\n",
|
| 65 |
+
"#property indicator_plots 2\n",
|
| 66 |
+
"\n",
|
| 67 |
+
"// First plot: custom candle\n",
|
| 68 |
+
"#property indicator_type1 DRAW_COLOR_CANDLES\n",
|
| 69 |
+
"#property indicator_color1 clrBlue, clrRed\n",
|
| 70 |
+
"#property indicator_label1 \"First Daily Candle\"\n",
|
| 71 |
+
"\n",
|
| 72 |
+
"// Second plot: ADX\n",
|
| 73 |
+
"#property indicator_type2 DRAW_LINE\n",
|
| 74 |
+
"#property indicator_color2 clrOrange\n",
|
| 75 |
+
"#property indicator_label2 \"ADX(14)\"\n",
|
| 76 |
+
"#property indicator_separate_window true\n",
|
| 77 |
+
"\n",
|
| 78 |
+
"//--- buffers for custom candle\n",
|
| 79 |
+
"double OpenBuf[];\n",
|
| 80 |
+
"double HighBuf[];\n",
|
| 81 |
+
"double LowBuf[];\n",
|
| 82 |
+
"double CloseBuf[];\n",
|
| 83 |
+
"double ColorBuf[];\n",
|
| 84 |
+
"\n",
|
| 85 |
+
"//--- buffer for ADX\n",
|
| 86 |
+
"double ADXBuf[];\n",
|
| 87 |
+
"\n",
|
| 88 |
+
"//--- colors index\n",
|
| 89 |
+
"#define BULL 0\n",
|
| 90 |
+
"#define BEAR 1\n",
|
| 91 |
+
"\n",
|
| 92 |
+
"int OnInit()\n",
|
| 93 |
+
"{\n",
|
| 94 |
+
" // Custom candle buffers\n",
|
| 95 |
+
" SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);\n",
|
| 96 |
+
" SetIndexBuffer(1, HighBuf, INDICATOR_DATA);\n",
|
| 97 |
+
" SetIndexBuffer(2, LowBuf, INDICATOR_DATA);\n",
|
| 98 |
+
" SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);\n",
|
| 99 |
+
" SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);\n",
|
| 100 |
+
"\n",
|
| 101 |
+
" PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1);\n",
|
| 102 |
+
"\n",
|
| 103 |
+
" // ADX buffer\n",
|
| 104 |
+
" SetIndexBuffer(5, ADXBuf, INDICATOR_DATA);\n",
|
| 105 |
+
" PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 14); // ADX period\n",
|
| 106 |
+
"\n",
|
| 107 |
+
" //--- chart appearance for main chart\n",
|
| 108 |
+
" ChartSetInteger(0, CHART_SHOW_GRID, false); // remove grid\n",
|
| 109 |
+
" ChartSetInteger(0, CHART_SHOW_BID_LINE, true); // show bid line\n",
|
| 110 |
+
" ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); // show ask line\n",
|
| 111 |
+
"\n",
|
| 112 |
+
" return(INIT_SUCCEEDED);\n",
|
| 113 |
+
"}\n",
|
| 114 |
+
"\n",
|
| 115 |
+
"int OnCalculate(\n",
|
| 116 |
+
" const int rates_total,\n",
|
| 117 |
+
" const int prev_calculated,\n",
|
| 118 |
+
" const datetime &time[],\n",
|
| 119 |
+
" const double &open[],\n",
|
| 120 |
+
" const double &high[],\n",
|
| 121 |
+
" const double &low[],\n",
|
| 122 |
+
" const double &close[],\n",
|
| 123 |
+
" const long &tick_volume[],\n",
|
| 124 |
+
" const long &volume[],\n",
|
| 125 |
+
" const int &spread[]\n",
|
| 126 |
+
")\n",
|
| 127 |
+
"{\n",
|
| 128 |
+
" if(rates_total < 15) // minimum for ADX(14)\n",
|
| 129 |
+
" return 0;\n",
|
| 130 |
+
"\n",
|
| 131 |
+
" int start = prev_calculated > 1 ? prev_calculated - 1 : 1;\n",
|
| 132 |
+
"\n",
|
| 133 |
+
" for(int i = start; i < rates_total; i++)\n",
|
| 134 |
+
" {\n",
|
| 135 |
+
" OpenBuf[i] = EMPTY_VALUE;\n",
|
| 136 |
+
" HighBuf[i] = EMPTY_VALUE;\n",
|
| 137 |
+
" LowBuf[i] = EMPTY_VALUE;\n",
|
| 138 |
+
" CloseBuf[i] = EMPTY_VALUE;\n",
|
| 139 |
+
"\n",
|
| 140 |
+
" datetime cur = time[i];\n",
|
| 141 |
+
" datetime prev = time[i - 1];\n",
|
| 142 |
+
"\n",
|
| 143 |
+
" MqlDateTime tcur, tprev;\n",
|
| 144 |
+
" TimeToStruct(cur, tcur);\n",
|
| 145 |
+
" TimeToStruct(prev, tprev);\n",
|
| 146 |
+
"\n",
|
| 147 |
+
" bool is_first_daily_candle =\n",
|
| 148 |
+
" (tcur.hour == 0 && tcur.min == 0) ||\n",
|
| 149 |
+
" (tcur.day != tprev.day);\n",
|
| 150 |
+
"\n",
|
| 151 |
+
" if(is_first_daily_candle)\n",
|
| 152 |
+
" {\n",
|
| 153 |
+
" OpenBuf[i] = open[i];\n",
|
| 154 |
+
" HighBuf[i] = high[i];\n",
|
| 155 |
+
" LowBuf[i] = low[i];\n",
|
| 156 |
+
" CloseBuf[i] = close[i];\n",
|
| 157 |
+
"\n",
|
| 158 |
+
" ColorBuf[i] = close[i] >= open[i] ? BULL : BEAR;\n",
|
| 159 |
+
" }\n",
|
| 160 |
+
" }\n",
|
| 161 |
+
"\n",
|
| 162 |
+
" //--- calculate ADX(14) on close price\n",
|
| 163 |
+
" for(int i = start; i < rates_total; i++)\n",
|
| 164 |
+
" ADXBuf[i] = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_MAIN, i);\n",
|
| 165 |
+
"\n",
|
| 166 |
+
" return(rates_total);\n",
|
| 167 |
+
"}\n"
|
| 168 |
+
]
|
| 169 |
+
}
|
| 170 |
+
],
|
| 171 |
+
"metadata": {
|
| 172 |
+
"language_info": {
|
| 173 |
+
"name": "python"
|
| 174 |
+
}
|
| 175 |
+
},
|
| 176 |
+
"nbformat": 4,
|
| 177 |
+
"nbformat_minor": 5
|
| 178 |
+
}
|
MQL5 Folder/ADX Filter/template with 1st candle highlighter.mq5
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property indicator_chart_window
|
| 2 |
+
#property indicator_buffers 5
|
| 3 |
+
#property indicator_plots 1
|
| 4 |
+
|
| 5 |
+
#property indicator_type1 DRAW_COLOR_CANDLES
|
| 6 |
+
#property indicator_color1 clrBlue, clrRed
|
| 7 |
+
#property indicator_label1 "First Daily Candle"
|
| 8 |
+
|
| 9 |
+
//--- buffers
|
| 10 |
+
double OpenBuf[];
|
| 11 |
+
double HighBuf[];
|
| 12 |
+
double LowBuf[];
|
| 13 |
+
double CloseBuf[];
|
| 14 |
+
double ColorBuf[];
|
| 15 |
+
|
| 16 |
+
//--- colors index
|
| 17 |
+
#define BULL 0
|
| 18 |
+
#define BEAR 1
|
| 19 |
+
|
| 20 |
+
int OnInit()
|
| 21 |
+
{
|
| 22 |
+
SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);
|
| 23 |
+
SetIndexBuffer(1, HighBuf, INDICATOR_DATA);
|
| 24 |
+
SetIndexBuffer(2, LowBuf, INDICATOR_DATA);
|
| 25 |
+
SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);
|
| 26 |
+
SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);
|
| 27 |
+
|
| 28 |
+
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1);
|
| 29 |
+
|
| 30 |
+
//--- chart appearance
|
| 31 |
+
ChartSetInteger(0, CHART_SHOW_GRID, false); // remove grid
|
| 32 |
+
ChartSetInteger(0, CHART_SHOW_BID_LINE, true); // show bid line
|
| 33 |
+
ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); // show ask line
|
| 34 |
+
|
| 35 |
+
return(INIT_SUCCEEDED);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
int OnCalculate(
|
| 39 |
+
const int rates_total,
|
| 40 |
+
const int prev_calculated,
|
| 41 |
+
const datetime &time[],
|
| 42 |
+
const double &open[],
|
| 43 |
+
const double &high[],
|
| 44 |
+
const double &low[],
|
| 45 |
+
const double &close[],
|
| 46 |
+
const long &tick_volume[],
|
| 47 |
+
const long &volume[],
|
| 48 |
+
const int &spread[]
|
| 49 |
+
)
|
| 50 |
+
{
|
| 51 |
+
if(rates_total < 2)
|
| 52 |
+
return 0;
|
| 53 |
+
|
| 54 |
+
int start = prev_calculated > 1 ? prev_calculated - 1 : 1;
|
| 55 |
+
|
| 56 |
+
for(int i = start; i < rates_total; i++)
|
| 57 |
+
{
|
| 58 |
+
OpenBuf[i] = EMPTY_VALUE;
|
| 59 |
+
HighBuf[i] = EMPTY_VALUE;
|
| 60 |
+
LowBuf[i] = EMPTY_VALUE;
|
| 61 |
+
CloseBuf[i] = EMPTY_VALUE;
|
| 62 |
+
|
| 63 |
+
datetime cur = time[i];
|
| 64 |
+
datetime prev = time[i - 1];
|
| 65 |
+
|
| 66 |
+
MqlDateTime tcur, tprev;
|
| 67 |
+
TimeToStruct(cur, tcur);
|
| 68 |
+
TimeToStruct(prev, tprev);
|
| 69 |
+
|
| 70 |
+
bool is_first_daily_candle =
|
| 71 |
+
(tcur.hour == 0 && tcur.min == 0) ||
|
| 72 |
+
(tcur.day != tprev.day);
|
| 73 |
+
|
| 74 |
+
if(is_first_daily_candle)
|
| 75 |
+
{
|
| 76 |
+
OpenBuf[i] = open[i];
|
| 77 |
+
HighBuf[i] = high[i];
|
| 78 |
+
LowBuf[i] = low[i];
|
| 79 |
+
CloseBuf[i] = close[i];
|
| 80 |
+
|
| 81 |
+
ColorBuf[i] = close[i] >= open[i] ? BULL : BEAR;
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
return(rates_total);
|
| 86 |
+
}
|
MQL5 Folder/Dec25_Volume Profile based breakout momentuim strategy/codeclaude.c++
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//+------------------------------------------------------------------+
|
| 2 |
+
//| VolumeProfileTradingEA.mq5 |
|
| 3 |
+
//| |
|
| 4 |
+
//+------------------------------------------------------------------+
|
| 5 |
+
#property copyright "Volume Profile Trading EA"
|
| 6 |
+
#property version "1.00"
|
| 7 |
+
#property strict
|
| 8 |
+
|
| 9 |
+
input double RiskPercent = 1.0; // Risk per trade (%)
|
| 10 |
+
input int SpreadMultiplier = 10; // Minimum SL = Spread x This
|
| 11 |
+
input double ValueAreaPercent = 0.70; // Value Area (70%)
|
| 12 |
+
input double PriceStepForVP = 0.10; // Price step for volume profile
|
| 13 |
+
|
| 14 |
+
// Global variables
|
| 15 |
+
datetime g_lastTradeHour = 0; // Track last trade hour
|
| 16 |
+
double g_cumVolume[]; // Cumulative volume by price
|
| 17 |
+
double g_priceLevels[]; // Price levels array
|
| 18 |
+
int g_volumeSize = 0; // Size of volume arrays
|
| 19 |
+
|
| 20 |
+
struct SessionData {
|
| 21 |
+
datetime startTime;
|
| 22 |
+
datetime currentTime;
|
| 23 |
+
double poc;
|
| 24 |
+
double vah;
|
| 25 |
+
double val;
|
| 26 |
+
bool isValid;
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
SessionData g_currentSession;
|
| 30 |
+
|
| 31 |
+
//+------------------------------------------------------------------+
|
| 32 |
+
//| Expert initialization function |
|
| 33 |
+
//+------------------------------------------------------------------+
|
| 34 |
+
int OnInit() {
|
| 35 |
+
Print("Volume Profile Trading EA initialized");
|
| 36 |
+
|
| 37 |
+
// Initialize session
|
| 38 |
+
g_currentSession.isValid = false;
|
| 39 |
+
g_lastTradeHour = 0;
|
| 40 |
+
|
| 41 |
+
// Reserve array space
|
| 42 |
+
ArrayResize(g_cumVolume, 10000);
|
| 43 |
+
ArrayResize(g_priceLevels, 10000);
|
| 44 |
+
ArrayFill(g_cumVolume, 0, 10000, 0.0);
|
| 45 |
+
g_volumeSize = 0;
|
| 46 |
+
|
| 47 |
+
return(INIT_SUCCEEDED);
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
//+------------------------------------------------------------------+
|
| 51 |
+
//| Expert deinitialization function |
|
| 52 |
+
//+------------------------------------------------------------------+
|
| 53 |
+
void OnDeinit(const int reason) {
|
| 54 |
+
Print("EA deinitialized: ", reason);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
//+------------------------------------------------------------------+
|
| 58 |
+
//| Expert tick function |
|
| 59 |
+
//+------------------------------------------------------------------+
|
| 60 |
+
void OnTick() {
|
| 61 |
+
datetime currentTime = TimeCurrent();
|
| 62 |
+
MqlDateTime dt;
|
| 63 |
+
TimeToStruct(currentTime, dt);
|
| 64 |
+
|
| 65 |
+
// Detect new trading session (gap detection)
|
| 66 |
+
if(IsNewTradingSession(currentTime)) {
|
| 67 |
+
ResetSession(currentTime);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// Update developing POC/VAH/VAL with each new bar
|
| 71 |
+
if(IsNewBar()) {
|
| 72 |
+
UpdateVolumeProfile();
|
| 73 |
+
|
| 74 |
+
// Check trading conditions on bar close
|
| 75 |
+
CheckTradingSignals();
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
//+------------------------------------------------------------------+
|
| 80 |
+
//| Detect new trading session based on time gaps |
|
| 81 |
+
//+------------------------------------------------------------------+
|
| 82 |
+
bool IsNewTradingSession(datetime currentTime) {
|
| 83 |
+
static datetime lastBarTime = 0;
|
| 84 |
+
|
| 85 |
+
if(lastBarTime == 0) {
|
| 86 |
+
lastBarTime = currentTime;
|
| 87 |
+
return true;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// Detect gap larger than normal bar interval
|
| 91 |
+
int barInterval = PeriodSeconds();
|
| 92 |
+
long timeDiff = currentTime - lastBarTime;
|
| 93 |
+
|
| 94 |
+
lastBarTime = currentTime;
|
| 95 |
+
|
| 96 |
+
// If gap is more than 2x normal interval, it's a new session
|
| 97 |
+
if(timeDiff > barInterval * 2) {
|
| 98 |
+
return true;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
return false;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
//+------------------------------------------------------------------+
|
| 105 |
+
//| Reset session data |
|
| 106 |
+
//+------------------------------------------------------------------+
|
| 107 |
+
void ResetSession(datetime startTime) {
|
| 108 |
+
g_currentSession.startTime = startTime;
|
| 109 |
+
g_currentSession.currentTime = startTime;
|
| 110 |
+
g_currentSession.isValid = false;
|
| 111 |
+
|
| 112 |
+
// Clear cumulative volume
|
| 113 |
+
ArrayFill(g_cumVolume, 0, ArraySize(g_cumVolume), 0.0);
|
| 114 |
+
g_volumeSize = 0;
|
| 115 |
+
|
| 116 |
+
Print("New trading session started at: ", TimeToString(startTime));
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
//+------------------------------------------------------------------+
|
| 120 |
+
//| Check if new bar formed |
|
| 121 |
+
//+------------------------------------------------------------------+
|
| 122 |
+
bool IsNewBar() {
|
| 123 |
+
static datetime lastBarTime = 0;
|
| 124 |
+
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
|
| 125 |
+
|
| 126 |
+
if(currentBarTime != lastBarTime) {
|
| 127 |
+
lastBarTime = currentBarTime;
|
| 128 |
+
return true;
|
| 129 |
+
}
|
| 130 |
+
return false;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
//+------------------------------------------------------------------+
|
| 134 |
+
//| Update developing volume profile |
|
| 135 |
+
//+------------------------------------------------------------------+
|
| 136 |
+
void UpdateVolumeProfile() {
|
| 137 |
+
int bar = 0;
|
| 138 |
+
double high = iHigh(_Symbol, PERIOD_CURRENT, bar);
|
| 139 |
+
double low = iLow(_Symbol, PERIOD_CURRENT, bar);
|
| 140 |
+
long volume = iVolume(_Symbol, PERIOD_CURRENT, bar);
|
| 141 |
+
|
| 142 |
+
if(volume <= 0) return;
|
| 143 |
+
|
| 144 |
+
// Distribute volume across price levels
|
| 145 |
+
double priceStep = PriceStepForVP;
|
| 146 |
+
int numLevels = (int)MathCeil((high - low) / priceStep) + 1;
|
| 147 |
+
|
| 148 |
+
if(numLevels <= 0) numLevels = 1;
|
| 149 |
+
|
| 150 |
+
double volPerLevel = (double)volume / numLevels;
|
| 151 |
+
|
| 152 |
+
for(double p = low; p <= high + 0.001; p += priceStep) {
|
| 153 |
+
double priceLevel = NormalizeDouble(p, 2);
|
| 154 |
+
AddVolumeToLevel(priceLevel, volPerLevel);
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
// Calculate POC, VAH, VAL
|
| 158 |
+
CalculateVolumeProfileLevels();
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
//+------------------------------------------------------------------+
|
| 162 |
+
//| Add volume to specific price level |
|
| 163 |
+
//+------------------------------------------------------------------+
|
| 164 |
+
void AddVolumeToLevel(double price, double volume) {
|
| 165 |
+
// Find if price level exists
|
| 166 |
+
int index = -1;
|
| 167 |
+
for(int i = 0; i < g_volumeSize; i++) {
|
| 168 |
+
if(MathAbs(g_priceLevels[i] - price) < 0.001) {
|
| 169 |
+
index = i;
|
| 170 |
+
break;
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
if(index >= 0) {
|
| 175 |
+
g_cumVolume[index] += volume;
|
| 176 |
+
} else {
|
| 177 |
+
// Add new level
|
| 178 |
+
if(g_volumeSize < ArraySize(g_cumVolume)) {
|
| 179 |
+
g_priceLevels[g_volumeSize] = price;
|
| 180 |
+
g_cumVolume[g_volumeSize] = volume;
|
| 181 |
+
g_volumeSize++;
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
//+------------------------------------------------------------------+
|
| 187 |
+
//| Calculate POC, VAH, VAL from cumulative volume |
|
| 188 |
+
//+------------------------------------------------------------------+
|
| 189 |
+
void CalculateVolumeProfileLevels() {
|
| 190 |
+
if(g_volumeSize == 0) return;
|
| 191 |
+
|
| 192 |
+
// Find POC (Point of Control - highest volume)
|
| 193 |
+
int pocIndex = 0;
|
| 194 |
+
double maxVolume = g_cumVolume[0];
|
| 195 |
+
|
| 196 |
+
for(int i = 1; i < g_volumeSize; i++) {
|
| 197 |
+
if(g_cumVolume[i] > maxVolume) {
|
| 198 |
+
maxVolume = g_cumVolume[i];
|
| 199 |
+
pocIndex = i;
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
g_currentSession.poc = g_priceLevels[pocIndex];
|
| 204 |
+
|
| 205 |
+
// Calculate total volume
|
| 206 |
+
double totalVolume = 0;
|
| 207 |
+
for(int i = 0; i < g_volumeSize; i++) {
|
| 208 |
+
totalVolume += g_cumVolume[i];
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
// Calculate Value Area (70% of volume around POC)
|
| 212 |
+
double targetVolume = totalVolume * ValueAreaPercent;
|
| 213 |
+
double cumVol = g_cumVolume[pocIndex];
|
| 214 |
+
|
| 215 |
+
int loIndex = pocIndex;
|
| 216 |
+
int hiIndex = pocIndex;
|
| 217 |
+
|
| 218 |
+
while(cumVol < targetVolume && (loIndex > 0 || hiIndex < g_volumeSize - 1)) {
|
| 219 |
+
bool expandLow = false;
|
| 220 |
+
bool expandHigh = false;
|
| 221 |
+
|
| 222 |
+
if(loIndex > 0) expandLow = true;
|
| 223 |
+
if(hiIndex < g_volumeSize - 1) expandHigh = true;
|
| 224 |
+
|
| 225 |
+
if(expandLow && expandHigh) {
|
| 226 |
+
// Expand to side with more volume
|
| 227 |
+
if(g_cumVolume[loIndex - 1] > g_cumVolume[hiIndex + 1]) {
|
| 228 |
+
loIndex--;
|
| 229 |
+
cumVol += g_cumVolume[loIndex];
|
| 230 |
+
} else {
|
| 231 |
+
hiIndex++;
|
| 232 |
+
cumVol += g_cumVolume[hiIndex];
|
| 233 |
+
}
|
| 234 |
+
} else if(expandLow) {
|
| 235 |
+
loIndex--;
|
| 236 |
+
cumVol += g_cumVolume[loIndex];
|
| 237 |
+
} else if(expandHigh) {
|
| 238 |
+
hiIndex++;
|
| 239 |
+
cumVol += g_cumVolume[hiIndex];
|
| 240 |
+
}
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
g_currentSession.vah = g_priceLevels[hiIndex];
|
| 244 |
+
g_currentSession.val = g_priceLevels[loIndex];
|
| 245 |
+
g_currentSession.isValid = true;
|
| 246 |
+
g_currentSession.currentTime = TimeCurrent();
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
//+------------------------------------------------------------------+
|
| 250 |
+
//| Check for trading signals |
|
| 251 |
+
//+------------------------------------------------------------------+
|
| 252 |
+
void CheckTradingSignals() {
|
| 253 |
+
if(!g_currentSession.isValid) return;
|
| 254 |
+
|
| 255 |
+
// Only one trade per whole trading hour
|
| 256 |
+
datetime currentTime = TimeCurrent();
|
| 257 |
+
MqlDateTime dt;
|
| 258 |
+
TimeToStruct(currentTime, dt);
|
| 259 |
+
|
| 260 |
+
datetime currentHour = StringToTime(StringFormat("%04d.%02d.%02d %02d:00",
|
| 261 |
+
dt.year, dt.mon, dt.day, dt.hour));
|
| 262 |
+
|
| 263 |
+
if(g_lastTradeHour == currentHour) {
|
| 264 |
+
return; // Already traded this hour
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
// Check if we already have an open position
|
| 268 |
+
if(PositionSelect(_Symbol)) {
|
| 269 |
+
return; // Position already open
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
// Get latest closed candle
|
| 273 |
+
int bar = 1;
|
| 274 |
+
double close = iClose(_Symbol, PERIOD_CURRENT, bar);
|
| 275 |
+
double high = iHigh(_Symbol, PERIOD_CURRENT, bar);
|
| 276 |
+
double low = iLow(_Symbol, PERIOD_CURRENT, bar);
|
| 277 |
+
double open = iOpen(_Symbol, PERIOD_CURRENT, bar);
|
| 278 |
+
|
| 279 |
+
// Determine body boundaries
|
| 280 |
+
double bodyHigh = MathMax(open, close);
|
| 281 |
+
double bodyLow = MathMin(open, close);
|
| 282 |
+
|
| 283 |
+
// Check if POC is between candle body (for exit check if position exists)
|
| 284 |
+
// This will be handled in position management
|
| 285 |
+
|
| 286 |
+
// Trading logic
|
| 287 |
+
bool buySignal = false;
|
| 288 |
+
bool sellSignal = false;
|
| 289 |
+
double sl = 0;
|
| 290 |
+
|
| 291 |
+
// Buy signal: Close above VAH
|
| 292 |
+
if(close > g_currentSession.vah) {
|
| 293 |
+
buySignal = true;
|
| 294 |
+
sl = low;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
// Sell signal: Close below VAL
|
| 298 |
+
if(close < g_currentSession.val) {
|
| 299 |
+
sellSignal = true;
|
| 300 |
+
sl = high;
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
// Execute trades
|
| 304 |
+
if(buySignal) {
|
| 305 |
+
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
| 306 |
+
double spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
| 307 |
+
double slDistance = currentPrice - sl;
|
| 308 |
+
|
| 309 |
+
// Check minimum SL distance
|
| 310 |
+
if(slDistance >= spread * SpreadMultiplier) {
|
| 311 |
+
OpenBuyTrade(currentPrice, sl);
|
| 312 |
+
g_lastTradeHour = currentHour;
|
| 313 |
+
}
|
| 314 |
+
} else if(sellSignal) {
|
| 315 |
+
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
| 316 |
+
double spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
| 317 |
+
double slDistance = sl - currentPrice;
|
| 318 |
+
|
| 319 |
+
// Check minimum SL distance
|
| 320 |
+
if(slDistance >= spread * SpreadMultiplier) {
|
| 321 |
+
OpenSellTrade(currentPrice, sl);
|
| 322 |
+
g_lastTradeHour = currentHour;
|
| 323 |
+
}
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
// Check exit conditions for existing positions
|
| 327 |
+
CheckExitConditions(bodyLow, bodyHigh);
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
//+------------------------------------------------------------------+
|
| 331 |
+
//| Open Buy Trade with 1% risk |
|
| 332 |
+
//+------------------------------------------------------------------+
|
| 333 |
+
void OpenBuyTrade(double price, double sl) {
|
| 334 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 335 |
+
double riskAmount = balance * (RiskPercent / 100.0);
|
| 336 |
+
double slDistance = price - sl;
|
| 337 |
+
|
| 338 |
+
if(slDistance <= 0) return;
|
| 339 |
+
|
| 340 |
+
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
| 341 |
+
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
| 342 |
+
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
| 343 |
+
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
| 344 |
+
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
| 345 |
+
|
| 346 |
+
double lotSize = (riskAmount * tickSize) / (slDistance * tickValue);
|
| 347 |
+
lotSize = MathFloor(lotSize / lotStep) * lotStep;
|
| 348 |
+
lotSize = MathMax(lotSize, minLot);
|
| 349 |
+
lotSize = MathMin(lotSize, maxLot);
|
| 350 |
+
|
| 351 |
+
MqlTradeRequest request = {};
|
| 352 |
+
MqlTradeResult result = {};
|
| 353 |
+
|
| 354 |
+
request.action = TRADE_ACTION_DEAL;
|
| 355 |
+
request.symbol = _Symbol;
|
| 356 |
+
request.volume = lotSize;
|
| 357 |
+
request.type = ORDER_TYPE_BUY;
|
| 358 |
+
request.price = price;
|
| 359 |
+
request.sl = sl;
|
| 360 |
+
request.tp = 0; // Dynamic TP based on POC
|
| 361 |
+
request.deviation = 10;
|
| 362 |
+
request.magic = 123456;
|
| 363 |
+
request.comment = "VP Buy";
|
| 364 |
+
|
| 365 |
+
if(OrderSend(request, result)) {
|
| 366 |
+
Print("Buy order opened: ", result.order, " at ", price);
|
| 367 |
+
} else {
|
| 368 |
+
Print("Buy order failed: ", GetLastError());
|
| 369 |
+
}
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
//+------------------------------------------------------------------+
|
| 373 |
+
//| Open Sell Trade with 1% risk |
|
| 374 |
+
//+------------------------------------------------------------------+
|
| 375 |
+
void OpenSellTrade(double price, double sl) {
|
| 376 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 377 |
+
double riskAmount = balance * (RiskPercent / 100.0);
|
| 378 |
+
double slDistance = sl - price;
|
| 379 |
+
|
| 380 |
+
if(slDistance <= 0) return;
|
| 381 |
+
|
| 382 |
+
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
| 383 |
+
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
| 384 |
+
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
| 385 |
+
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
| 386 |
+
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
| 387 |
+
|
| 388 |
+
double lotSize = (riskAmount * tickSize) / (slDistance * tickValue);
|
| 389 |
+
lotSize = MathFloor(lotSize / lotStep) * lotStep;
|
| 390 |
+
lotSize = MathMax(lotSize, minLot);
|
| 391 |
+
lotSize = MathMin(lotSize, maxLot);
|
| 392 |
+
|
| 393 |
+
MqlTradeRequest request = {};
|
| 394 |
+
MqlTradeResult result = {};
|
| 395 |
+
|
| 396 |
+
request.action = TRADE_ACTION_DEAL;
|
| 397 |
+
request.symbol = _Symbol;
|
| 398 |
+
request.volume = lotSize;
|
| 399 |
+
request.type = ORDER_TYPE_SELL;
|
| 400 |
+
request.price = price;
|
| 401 |
+
request.sl = sl;
|
| 402 |
+
request.tp = 0; // Dynamic TP based on POC
|
| 403 |
+
request.deviation = 10;
|
| 404 |
+
request.magic = 123456;
|
| 405 |
+
request.comment = "VP Sell";
|
| 406 |
+
|
| 407 |
+
if(OrderSend(request, result)) {
|
| 408 |
+
Print("Sell order opened: ", result.order, " at ", price);
|
| 409 |
+
} else {
|
| 410 |
+
Print("Sell order failed: ", GetLastError());
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
//+------------------------------------------------------------------+
|
| 415 |
+
//| Check exit conditions based on POC crossing candle body |
|
| 416 |
+
//+------------------------------------------------------------------+
|
| 417 |
+
void CheckExitConditions(double bodyLow, double bodyHigh) {
|
| 418 |
+
if(!PositionSelect(_Symbol)) return;
|
| 419 |
+
|
| 420 |
+
// Check if POC is between candle body
|
| 421 |
+
if(g_currentSession.poc >= bodyLow && g_currentSession.poc <= bodyHigh) {
|
| 422 |
+
// Close position
|
| 423 |
+
MqlTradeRequest request = {};
|
| 424 |
+
MqlTradeResult result = {};
|
| 425 |
+
|
| 426 |
+
request.action = TRADE_ACTION_DEAL;
|
| 427 |
+
request.symbol = _Symbol;
|
| 428 |
+
request.volume = PositionGetDouble(POSITION_VOLUME);
|
| 429 |
+
request.deviation = 10;
|
| 430 |
+
request.magic = 123456;
|
| 431 |
+
|
| 432 |
+
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
|
| 433 |
+
request.type = ORDER_TYPE_SELL;
|
| 434 |
+
request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
| 435 |
+
} else {
|
| 436 |
+
request.type = ORDER_TYPE_BUY;
|
| 437 |
+
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
if(OrderSend(request, result)) {
|
| 441 |
+
Print("Position closed: POC crossed candle body");
|
| 442 |
+
}
|
| 443 |
+
}
|
| 444 |
+
}
|
| 445 |
+
//+------------------------------------------------------------------+
|
MQL5 Folder/Dec25_Volume Profile based breakout momentuim strategy/codegemini.c++
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//+------------------------------------------------------------------+
|
| 2 |
+
//| VolumeProfile_Breakout.mq5 |
|
| 3 |
+
//| Copyright 2024, Claude AI |
|
| 4 |
+
//| https://www.mql5.com |
|
| 5 |
+
//+------------------------------------------------------------------+
|
| 6 |
+
#property copyright "Claude AI"
|
| 7 |
+
#property link "https://www.mql5.com"
|
| 8 |
+
#property version "1.00"
|
| 9 |
+
#property strict
|
| 10 |
+
|
| 11 |
+
#include <Trade\Trade.mqh>
|
| 12 |
+
#include <Trade\SymbolInfo.mqh>
|
| 13 |
+
#include <Trade\PositionInfo.mqh>
|
| 14 |
+
#include <Trade\AccountInfo.mqh>
|
| 15 |
+
|
| 16 |
+
//--- INPUT PARAMETERS
|
| 17 |
+
input group "Risk Management"
|
| 18 |
+
input double InpRiskPercent = 1.0; // Risk per trade (%) or simply 1%
|
| 19 |
+
input double InpPriceStep = 0.10; // VP Price Step (e.g., 0.10 XAU price unit precision)
|
| 20 |
+
input double InpValueAreaPct = 0.70; // Value Area Percent (0.70)
|
| 21 |
+
|
| 22 |
+
input group "Filters"
|
| 23 |
+
input int InpMinSLDistance = 10; // Min StopLoss Factor (Spread * X) for example in XAU (Sl is not < 0.160 x 10)
|
| 24 |
+
|
| 25 |
+
input group "System"
|
| 26 |
+
input int InpMagicNumber = 123456; // Magic Number
|
| 27 |
+
input string InpTradeComment = "VP_Algo"; // Trade Comment
|
| 28 |
+
|
| 29 |
+
//--- GLOBAL OBJECTS
|
| 30 |
+
CTrade m_trade;
|
| 31 |
+
CSymbolInfo m_symbol;
|
| 32 |
+
CPositionInfo m_position;
|
| 33 |
+
CAccountInfo m_account;
|
| 34 |
+
|
| 35 |
+
//--- GLOBAL VARIABLES
|
| 36 |
+
datetime m_last_calc_time;
|
| 37 |
+
datetime m_last_trade_hour; // Tracks the hour of the last trade
|
| 38 |
+
double m_developing_poc;
|
| 39 |
+
double m_developing_vah;
|
| 40 |
+
double m_developing_val;
|
| 41 |
+
|
| 42 |
+
//--- DATA STRUCTURE FOR VOLUME PROFILE
|
| 43 |
+
struct PriceLevel
|
| 44 |
+
{
|
| 45 |
+
double price;
|
| 46 |
+
double volume;
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
//+------------------------------------------------------------------+
|
| 50 |
+
//| Expert initialization function |
|
| 51 |
+
//+------------------------------------------------------------------+
|
| 52 |
+
int OnInit()
|
| 53 |
+
{
|
| 54 |
+
if(!m_symbol.Name(Symbol()))
|
| 55 |
+
return(INIT_FAILED);
|
| 56 |
+
|
| 57 |
+
m_trade.SetExpertMagicNumber(InpMagicNumber);
|
| 58 |
+
m_trade.SetMarginMode();
|
| 59 |
+
m_trade.SetTypeFillingBySymbol(Symbol());
|
| 60 |
+
|
| 61 |
+
// Normalize Price Step to avoid zero division
|
| 62 |
+
if(InpPriceStep <= 0)
|
| 63 |
+
{
|
| 64 |
+
Print("Error: Price Step must be > 0");
|
| 65 |
+
return(INIT_PARAMETERS_INCORRECT);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
m_last_calc_time = 0;
|
| 69 |
+
m_last_trade_hour = 0;
|
| 70 |
+
|
| 71 |
+
return(INIT_SUCCEEDED);
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
//+------------------------------------------------------------------+
|
| 75 |
+
//| Expert tick function |
|
| 76 |
+
//+------------------------------------------------------------------+
|
| 77 |
+
void OnTick()
|
| 78 |
+
{
|
| 79 |
+
if(!m_symbol.RefreshRates()) return;
|
| 80 |
+
|
| 81 |
+
// 1. Manage Open Trades (Dynamic TP Logic)
|
| 82 |
+
ManageOpenTrades();
|
| 83 |
+
|
| 84 |
+
// 2. Check for New Bar to Calculate Profile and Signals
|
| 85 |
+
// We only calculate logic on bar close as per requirement
|
| 86 |
+
datetime time_0 = iTime(_Symbol, PERIOD_CURRENT, 0);
|
| 87 |
+
if(time_0 <= m_last_calc_time) return; // Already calculated for this bar
|
| 88 |
+
|
| 89 |
+
m_last_calc_time = time_0;
|
| 90 |
+
|
| 91 |
+
// --- CALCULATE PROFILE FOR PREVIOUS BARS ---
|
| 92 |
+
CalculateVolumeProfile();
|
| 93 |
+
|
| 94 |
+
// --- CHECK TRADING HOUR LOGIC ---
|
| 95 |
+
// Logic: Max one trade per whole trading hour.
|
| 96 |
+
datetime current_hour_dt = time_0 - (time_0 % 3600); // Floor to hour
|
| 97 |
+
|
| 98 |
+
if(m_last_trade_hour == current_hour_dt)
|
| 99 |
+
{
|
| 100 |
+
// We already traded this hour
|
| 101 |
+
return;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
// --- CHECK ENTRY SIGNALS ---
|
| 105 |
+
CheckEntrySignals(current_hour_dt);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
//+------------------------------------------------------------------+
|
| 109 |
+
//| Logic: Calculate Developing POC/VAH/VAL |
|
| 110 |
+
//| Replicates the Python "cumulative_volume" distribution |
|
| 111 |
+
//+------------------------------------------------------------------+
|
| 112 |
+
void CalculateVolumeProfile()
|
| 113 |
+
{
|
| 114 |
+
// Get Start of Day (Session)
|
| 115 |
+
datetime time_current = iTime(_Symbol, PERIOD_CURRENT, 0);
|
| 116 |
+
datetime time_day_start = iTime(_Symbol, PERIOD_D1, 0);
|
| 117 |
+
|
| 118 |
+
// If data is unavailable, fallback
|
| 119 |
+
if(time_day_start == 0) time_day_start = time_current - 86400;
|
| 120 |
+
|
| 121 |
+
// Get all bars from start of day up to index 1 (closed bar)
|
| 122 |
+
int start_idx = iBarShift(_Symbol, PERIOD_CURRENT, time_day_start);
|
| 123 |
+
int end_idx = 1; // We look at closed bars only for calculation
|
| 124 |
+
|
| 125 |
+
if(start_idx < end_idx) return;
|
| 126 |
+
|
| 127 |
+
// Map: Price(int normalized) -> Volume
|
| 128 |
+
// Using dynamic arrays as a simple hash map replacement
|
| 129 |
+
double volumes[];
|
| 130 |
+
double prices[];
|
| 131 |
+
int total_levels = 0;
|
| 132 |
+
|
| 133 |
+
// Resize initially to a reasonable estimate
|
| 134 |
+
ArrayResize(volumes, 1000);
|
| 135 |
+
ArrayResize(prices, 1000);
|
| 136 |
+
ArrayInitialize(volumes, 0);
|
| 137 |
+
ArrayInitialize(prices, 0);
|
| 138 |
+
|
| 139 |
+
// --- ITERATE CANDLES ---
|
| 140 |
+
for(int i = start_idx; i >= end_idx; i--)
|
| 141 |
+
{
|
| 142 |
+
double h = iHigh(_Symbol, PERIOD_CURRENT, i);
|
| 143 |
+
double l = iLow(_Symbol, PERIOD_CURRENT, i);
|
| 144 |
+
long v = iVolume(_Symbol, PERIOD_CURRENT, i); // Tick Volume
|
| 145 |
+
|
| 146 |
+
if(v <= 0) continue;
|
| 147 |
+
|
| 148 |
+
// Python logic: prices = np.arange(low, high + 0.01, step)
|
| 149 |
+
// Count steps
|
| 150 |
+
int steps = (int)((h - l) / InpPriceStep) + 1;
|
| 151 |
+
if(steps <= 0) steps = 1;
|
| 152 |
+
|
| 153 |
+
double vol_per_step = (double)v / steps;
|
| 154 |
+
|
| 155 |
+
for(int s = 0; s < steps; s++)
|
| 156 |
+
{
|
| 157 |
+
double p_raw = l + (s * InpPriceStep);
|
| 158 |
+
double p_norm = NormalizeDouble(p_raw, _Digits);
|
| 159 |
+
|
| 160 |
+
// Find or Add to array (Simple linear search is slow but robust for MQL5 arrays without generics)
|
| 161 |
+
// Optimization: In production, use a sorted array + binary search or a min-max offset array.
|
| 162 |
+
// Here we use a simplified accumulating method sufficient for M15 data.
|
| 163 |
+
|
| 164 |
+
bool found = false;
|
| 165 |
+
for(int k=0; k<total_levels; k++)
|
| 166 |
+
{
|
| 167 |
+
// Floating point comparison
|
| 168 |
+
if(MathAbs(prices[k] - p_norm) < _Point)
|
| 169 |
+
{
|
| 170 |
+
volumes[k] += vol_per_step;
|
| 171 |
+
found = true;
|
| 172 |
+
break;
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
if(!found)
|
| 177 |
+
{
|
| 178 |
+
if(total_levels >= ArraySize(prices))
|
| 179 |
+
{
|
| 180 |
+
ArrayResize(prices, total_levels + 500);
|
| 181 |
+
ArrayResize(volumes, total_levels + 500);
|
| 182 |
+
}
|
| 183 |
+
prices[total_levels] = p_norm;
|
| 184 |
+
volumes[total_levels] = vol_per_step;
|
| 185 |
+
total_levels++;
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
// Sort Data (Bubble sort is slow, we copy to struct array and use built-in Sort)
|
| 191 |
+
PriceLevel levels[];
|
| 192 |
+
ArrayResize(levels, total_levels);
|
| 193 |
+
double total_vol = 0;
|
| 194 |
+
|
| 195 |
+
for(int i=0; i<total_levels; i++)
|
| 196 |
+
{
|
| 197 |
+
levels[i].price = prices[i];
|
| 198 |
+
levels[i].volume = volumes[i];
|
| 199 |
+
total_vol += volumes[i];
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
// Sort by Price Ascending for Value Area calc
|
| 203 |
+
// Note: We need a custom sort or manual sort.
|
| 204 |
+
// Simple selection sort for Price (since total_levels usually < 500 per session on M15)
|
| 205 |
+
for(int i=0; i<total_levels-1; i++)
|
| 206 |
+
{
|
| 207 |
+
int min_idx = i;
|
| 208 |
+
for(int j=i+1; j<total_levels; j++)
|
| 209 |
+
{
|
| 210 |
+
if(levels[j].price < levels[min_idx].price) min_idx = j;
|
| 211 |
+
}
|
| 212 |
+
PriceLevel temp = levels[min_idx];
|
| 213 |
+
levels[min_idx] = levels[i];
|
| 214 |
+
levels[i] = temp;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
// --- FIND POC ---
|
| 218 |
+
int poc_idx = 0;
|
| 219 |
+
double max_vol = -1.0;
|
| 220 |
+
|
| 221 |
+
for(int i=0; i<total_levels; i++)
|
| 222 |
+
{
|
| 223 |
+
if(levels[i].volume > max_vol)
|
| 224 |
+
{
|
| 225 |
+
max_vol = levels[i].volume;
|
| 226 |
+
poc_idx = i;
|
| 227 |
+
}
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
m_developing_poc = levels[poc_idx].price;
|
| 231 |
+
|
| 232 |
+
// --- CALCULATE VAH / VAL (70% Rule) ---
|
| 233 |
+
double target_vol = total_vol * InpValueAreaPct;
|
| 234 |
+
double current_vol = levels[poc_idx].volume;
|
| 235 |
+
int idx_low = poc_idx;
|
| 236 |
+
int idx_high = poc_idx;
|
| 237 |
+
|
| 238 |
+
// Expand outwards from POC
|
| 239 |
+
while(current_vol < target_vol)
|
| 240 |
+
{
|
| 241 |
+
double vol_below = (idx_low > 0) ? levels[idx_low - 1].volume : 0;
|
| 242 |
+
double vol_above = (idx_high < total_levels - 1) ? levels[idx_high + 1].volume : 0;
|
| 243 |
+
|
| 244 |
+
// If we hit boundaries
|
| 245 |
+
if(idx_low == 0 && idx_high == total_levels - 1) break;
|
| 246 |
+
|
| 247 |
+
if(vol_above > vol_below || idx_low == 0)
|
| 248 |
+
{
|
| 249 |
+
if(idx_high < total_levels - 1)
|
| 250 |
+
{
|
| 251 |
+
idx_high++;
|
| 252 |
+
current_vol += levels[idx_high].volume;
|
| 253 |
+
}
|
| 254 |
+
}
|
| 255 |
+
else
|
| 256 |
+
{
|
| 257 |
+
if(idx_low > 0)
|
| 258 |
+
{
|
| 259 |
+
idx_low--;
|
| 260 |
+
current_vol += levels[idx_low].volume;
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
m_developing_val = levels[idx_low].price;
|
| 266 |
+
m_developing_vah = levels[idx_high].price;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
//+------------------------------------------------------------------+
|
| 270 |
+
//| Check Logic and Open Trades |
|
| 271 |
+
//+------------------------------------------------------------------+
|
| 272 |
+
void CheckEntrySignals(datetime current_hour)
|
| 273 |
+
{
|
| 274 |
+
// Previous closed candle (Signal Candle)
|
| 275 |
+
double close = iClose(_Symbol, PERIOD_CURRENT, 1);
|
| 276 |
+
double low = iLow(_Symbol, PERIOD_CURRENT, 1);
|
| 277 |
+
double high = iHigh(_Symbol, PERIOD_CURRENT, 1);
|
| 278 |
+
|
| 279 |
+
// Get Spread
|
| 280 |
+
double spread = (double)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * _Point;
|
| 281 |
+
|
| 282 |
+
// --- BUY LOGIC ---
|
| 283 |
+
// Candle Closes ABOVE VAH
|
| 284 |
+
if(close > m_developing_vah)
|
| 285 |
+
{
|
| 286 |
+
double sl_price = low;
|
| 287 |
+
double sl_dist = close - sl_price;
|
| 288 |
+
|
| 289 |
+
// Filter: Stop Loss Distance < Spread * 10
|
| 290 |
+
if(sl_dist < (spread * InpMinSLDistance)) return;
|
| 291 |
+
|
| 292 |
+
// Calculate Lot Size
|
| 293 |
+
double vol = GetLotSize(sl_dist);
|
| 294 |
+
|
| 295 |
+
if(m_trade.Buy(vol, _Symbol, 0, sl_price, 0, InpTradeComment))
|
| 296 |
+
{
|
| 297 |
+
m_last_trade_hour = current_hour;
|
| 298 |
+
}
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
// --- SELL LOGIC ---
|
| 302 |
+
// Candle Closes BELOW VAL
|
| 303 |
+
else if(close < m_developing_val)
|
| 304 |
+
{
|
| 305 |
+
double sl_price = high;
|
| 306 |
+
double sl_dist = sl_price - close;
|
| 307 |
+
|
| 308 |
+
// Filter: Stop Loss Distance < Spread * 10
|
| 309 |
+
if(sl_dist < (spread * InpMinSLDistance)) return;
|
| 310 |
+
|
| 311 |
+
double vol = GetLotSize(sl_dist);
|
| 312 |
+
|
| 313 |
+
if(m_trade.Sell(vol, _Symbol, 0, sl_price, 0, InpTradeComment))
|
| 314 |
+
{
|
| 315 |
+
m_last_trade_hour = current_hour;
|
| 316 |
+
}
|
| 317 |
+
}
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
//+------------------------------------------------------------------+
|
| 321 |
+
//| Manage Open Trades (Dynamic Take Profit) |
|
| 322 |
+
//| "Close if corresponding POC closes between body of candle" |
|
| 323 |
+
//+------------------------------------------------------------------+
|
| 324 |
+
void ManageOpenTrades()
|
| 325 |
+
{
|
| 326 |
+
if(PositionsTotal() == 0) return;
|
| 327 |
+
|
| 328 |
+
// Check current active candle data
|
| 329 |
+
double open_current = iOpen(_Symbol, PERIOD_CURRENT, 0);
|
| 330 |
+
double close_current = iClose(_Symbol, PERIOD_CURRENT, 0); // Current price
|
| 331 |
+
|
| 332 |
+
double body_high = MathMax(open_current, close_current);
|
| 333 |
+
double body_low = MathMin(open_current, close_current);
|
| 334 |
+
|
| 335 |
+
// Iterate backwards to avoid index issues on close
|
| 336 |
+
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
| 337 |
+
{
|
| 338 |
+
if(m_position.SelectByIndex(i))
|
| 339 |
+
{
|
| 340 |
+
if(m_position.Symbol() == _Symbol && m_position.Magic() == InpMagicNumber)
|
| 341 |
+
{
|
| 342 |
+
// Logic: Is current POC inside current candle BODY?
|
| 343 |
+
if(m_developing_poc >= body_low && m_developing_poc <= body_high)
|
| 344 |
+
{
|
| 345 |
+
// Close the trade
|
| 346 |
+
m_trade.PositionClose(m_position.Ticket());
|
| 347 |
+
}
|
| 348 |
+
}
|
| 349 |
+
}
|
| 350 |
+
}
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
//+------------------------------------------------------------------+
|
| 354 |
+
//| Helper: Calculate Lot Size based on Risk % |
|
| 355 |
+
//+------------------------------------------------------------------+
|
| 356 |
+
double GetLotSize(double sl_distance)
|
| 357 |
+
{
|
| 358 |
+
if(sl_distance <= 0) return 0.01;
|
| 359 |
+
|
| 360 |
+
double risk_money = m_account.Balance() * (InpRiskPercent / 100.0);
|
| 361 |
+
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
| 362 |
+
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
| 363 |
+
|
| 364 |
+
if(tick_size == 0 || tick_value == 0) return 0.01;
|
| 365 |
+
|
| 366 |
+
double loss_per_lot = (sl_distance / tick_size) * tick_value;
|
| 367 |
+
if(loss_per_lot == 0) return 0.01;
|
| 368 |
+
|
| 369 |
+
double lots = risk_money / loss_per_lot;
|
| 370 |
+
|
| 371 |
+
// Normalize lots
|
| 372 |
+
double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
| 373 |
+
double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
| 374 |
+
double step_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
| 375 |
+
|
| 376 |
+
lots = MathFloor(lots / step_lot) * step_lot;
|
| 377 |
+
|
| 378 |
+
if(lots < min_lot) lots = min_lot;
|
| 379 |
+
if(lots > max_lot) lots = max_lot;
|
| 380 |
+
|
| 381 |
+
return lots;
|
| 382 |
+
}
|
MQL5 Folder/Dec29_6-8 range/strategy.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
MQL5 Folder/Dec29_6-8 range/v1.c++
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//+------------------------------------------------------------------+
|
| 2 |
+
//| RangeBreakout_M3.mq5 |
|
| 3 |
+
//| Copyright 2023, Gemini AI Asst. |
|
| 4 |
+
//| https://www.mql5.com |
|
| 5 |
+
//+------------------------------------------------------------------+
|
| 6 |
+
#property copyright "Gemini AI"
|
| 7 |
+
#property link "https://www.mql5.com"
|
| 8 |
+
#property version "1.00"
|
| 9 |
+
#property strict
|
| 10 |
+
|
| 11 |
+
//--- Include Standard Library for easier trade execution
|
| 12 |
+
#include <Trade\Trade.mqh>
|
| 13 |
+
|
| 14 |
+
//+------------------------------------------------------------------+
|
| 15 |
+
//| Inputs |
|
| 16 |
+
//+------------------------------------------------------------------+
|
| 17 |
+
input group "Risk Management"
|
| 18 |
+
input double InpRiskPercent = 1.0; // Risk per trade (% of Balance)
|
| 19 |
+
input int InpRewardRatio = 10; // Reward Ratio (TP = 10 * Risk)
|
| 20 |
+
|
| 21 |
+
input group "Time Settings"
|
| 22 |
+
input int InpRangeStartHour = 22; // Range Start Hour (UTC equivalent)
|
| 23 |
+
input int InpRangeEndHour = 0; // Range End Hour (0 = Midnight)
|
| 24 |
+
input int InpBrokerOffset = 0; // Broker Time Offset from UTC (e.g., if Broker is UTC+2, put 2)
|
| 25 |
+
|
| 26 |
+
input group "System"
|
| 27 |
+
input ulong InpMagicNum = 123456; // Magic Number
|
| 28 |
+
|
| 29 |
+
//+------------------------------------------------------------------+
|
| 30 |
+
//| Global Variables |
|
| 31 |
+
//+------------------------------------------------------------------+
|
| 32 |
+
CTrade trade;
|
| 33 |
+
datetime lastBarTime = 0;
|
| 34 |
+
bool tradeTakenToday = false;
|
| 35 |
+
int lastTradeDay = -1;
|
| 36 |
+
|
| 37 |
+
// Structure to hold Range Data
|
| 38 |
+
struct RangeData {
|
| 39 |
+
double HHR; // Highest High of Range
|
| 40 |
+
double LLR; // Lowest Low of Range
|
| 41 |
+
datetime timeHHR; // Time of HHR (EP)
|
| 42 |
+
datetime timeLLR; // Time of LLR (EP)
|
| 43 |
+
bool isValid; // Is range calculated?
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
RangeData currentRange;
|
| 47 |
+
|
| 48 |
+
//+------------------------------------------------------------------+
|
| 49 |
+
//| Expert initialization function |
|
| 50 |
+
//+------------------------------------------------------------------+
|
| 51 |
+
int OnInit()
|
| 52 |
+
{
|
| 53 |
+
trade.SetExpertMagicNumber(InpMagicNum);
|
| 54 |
+
// Ensure we are allowed to trade
|
| 55 |
+
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
|
| 56 |
+
Print("Warning: AutoTrading is disabled in Terminal.");
|
| 57 |
+
|
| 58 |
+
return(INIT_SUCCEEDED);
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
//+------------------------------------------------------------------+
|
| 62 |
+
//| Expert tick function |
|
| 63 |
+
//+------------------------------------------------------------------+
|
| 64 |
+
void OnTick()
|
| 65 |
+
{
|
| 66 |
+
// 1. Check for New Bar on M3 Timeframe
|
| 67 |
+
// We strictly use M3 per instructions
|
| 68 |
+
datetime currentBarTime = iTime(_Symbol, PERIOD_M3, 0);
|
| 69 |
+
if(currentBarTime == lastBarTime) return; // Wait for candle close
|
| 70 |
+
lastBarTime = currentBarTime;
|
| 71 |
+
|
| 72 |
+
// 2. Reset Daily Flags
|
| 73 |
+
MqlDateTime dt;
|
| 74 |
+
TimeCurrent(dt);
|
| 75 |
+
|
| 76 |
+
if(lastTradeDay != dt.day) {
|
| 77 |
+
tradeTakenToday = false;
|
| 78 |
+
lastTradeDay = dt.day;
|
| 79 |
+
currentRange.isValid = false; // Reset range for the new day
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// 3. One Trade Per Day Logic
|
| 83 |
+
if(tradeTakenToday) return;
|
| 84 |
+
|
| 85 |
+
// 4. Calculate Range if not yet done and time is past 00:00
|
| 86 |
+
// We need to define the 22:00 - 00:00 window of the *previous* session
|
| 87 |
+
if(!currentRange.isValid) {
|
| 88 |
+
CalculateRange();
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
// 5. If Range is valid, Check for Breakout Logic
|
| 92 |
+
if(currentRange.isValid) {
|
| 93 |
+
CheckBreakoutSignal();
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
//+------------------------------------------------------------------+
|
| 98 |
+
//| Function to Calculate HHR and LLR (22:00 - 00:00) |
|
| 99 |
+
//+------------------------------------------------------------------+
|
| 100 |
+
void CalculateRange()
|
| 101 |
+
{
|
| 102 |
+
MqlDateTime dt;
|
| 103 |
+
TimeCurrent(dt);
|
| 104 |
+
|
| 105 |
+
// Determine the correct start and end time for the range
|
| 106 |
+
// The range is 22:00 (Previous Day) to 00:00 (Today)
|
| 107 |
+
// Adjusted for Broker Offset
|
| 108 |
+
|
| 109 |
+
int startHour = InpRangeStartHour + InpBrokerOffset;
|
| 110 |
+
int endHour = InpRangeEndHour + InpBrokerOffset;
|
| 111 |
+
|
| 112 |
+
// Handle hour overflow (e.g., 22 + 2 = 24 -> 00)
|
| 113 |
+
if(startHour >= 24) startHour -= 24;
|
| 114 |
+
if(endHour >= 24) endHour -= 24;
|
| 115 |
+
|
| 116 |
+
// We need the range from yesterday's 22:00 to today's 00:00
|
| 117 |
+
datetime timeEnd = StringToTime(StringFormat("%04d.%02d.%02d %02d:00", dt.year, dt.mon, dt.day, endHour));
|
| 118 |
+
datetime timeStart = timeEnd - (2 * 3600); // Subtract 2 hours (22 to 00 is 2 hours)
|
| 119 |
+
|
| 120 |
+
// Check if we have passed the range end time
|
| 121 |
+
if(TimeCurrent() < timeEnd) return; // Wait until range closes
|
| 122 |
+
|
| 123 |
+
// Get Bars inside the range
|
| 124 |
+
MqlRates rates[];
|
| 125 |
+
ArraySetAsSeries(rates, true);
|
| 126 |
+
|
| 127 |
+
// Get data from M3 timeframe
|
| 128 |
+
int copied = CopyRates(_Symbol, PERIOD_M3, timeStart, timeEnd, rates);
|
| 129 |
+
|
| 130 |
+
if(copied > 0) {
|
| 131 |
+
double highest = -DBL_MAX;
|
| 132 |
+
double lowest = DBL_MAX;
|
| 133 |
+
datetime tHigh = 0;
|
| 134 |
+
datetime tLow = 0;
|
| 135 |
+
|
| 136 |
+
for(int i=0; i<copied; i++) {
|
| 137 |
+
if(rates[i].high > highest) {
|
| 138 |
+
highest = rates[i].high;
|
| 139 |
+
tHigh = rates[i].time;
|
| 140 |
+
}
|
| 141 |
+
if(rates[i].low < lowest) {
|
| 142 |
+
lowest = rates[i].low;
|
| 143 |
+
tLow = rates[i].time;
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
currentRange.HHR = highest;
|
| 148 |
+
currentRange.LLR = lowest;
|
| 149 |
+
currentRange.timeHHR = tHigh;
|
| 150 |
+
currentRange.timeLLR = tLow;
|
| 151 |
+
currentRange.isValid = true;
|
| 152 |
+
|
| 153 |
+
// Print("Range Calculated: HHR=", currentRange.HHR, " LLR=", currentRange.LLR);
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
//+------------------------------------------------------------------+
|
| 158 |
+
//| Function to Check Breakout & Validation |
|
| 159 |
+
//+------------------------------------------------------------------+
|
| 160 |
+
void CheckBreakoutSignal()
|
| 161 |
+
{
|
| 162 |
+
// Get the Breakout Candle (BCC) - Index 1 (Closed Candle)
|
| 163 |
+
MqlRates bcc[];
|
| 164 |
+
ArraySetAsSeries(bcc, true);
|
| 165 |
+
if(CopyRates(_Symbol, PERIOD_M3, 1, 1, bcc) != 1) return;
|
| 166 |
+
|
| 167 |
+
double bccClose = bcc[0].close;
|
| 168 |
+
double bccHigh = bcc[0].high;
|
| 169 |
+
double bccLow = bcc[0].low;
|
| 170 |
+
datetime bccTime = bcc[0].time;
|
| 171 |
+
|
| 172 |
+
// --- BUY LOGIC ---
|
| 173 |
+
if(bccClose > currentRange.HHR) {
|
| 174 |
+
// Filter: Check candles from EP (timeHHR) until BCC
|
| 175 |
+
// Ensure wicks haven't touched HHR in between
|
| 176 |
+
if(IsPathClear(currentRange.timeHHR, bccTime, currentRange.HHR, true)) {
|
| 177 |
+
|
| 178 |
+
double sl = bccLow;
|
| 179 |
+
double riskDist = bccClose - sl;
|
| 180 |
+
|
| 181 |
+
// Safety check for zero distance
|
| 182 |
+
if(riskDist <= 0) return;
|
| 183 |
+
|
| 184 |
+
double tp = bccClose + (riskDist * InpRewardRatio);
|
| 185 |
+
double lotSize = CalculateLotSize(MathAbs(bccClose - sl));
|
| 186 |
+
|
| 187 |
+
if(trade.Buy(lotSize, _Symbol, bccClose, sl, tp, "Range Breakout Buy")) {
|
| 188 |
+
tradeTakenToday = true;
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
// --- SELL LOGIC ---
|
| 194 |
+
else if(bccClose < currentRange.LLR) {
|
| 195 |
+
// Filter: Check candles from EP (timeLLR) until BCC
|
| 196 |
+
// Ensure wicks haven't touched LLR in between
|
| 197 |
+
if(IsPathClear(currentRange.timeLLR, bccTime, currentRange.LLR, false)) {
|
| 198 |
+
|
| 199 |
+
double sl = bccHigh;
|
| 200 |
+
double riskDist = sl - bccClose;
|
| 201 |
+
|
| 202 |
+
if(riskDist <= 0) return;
|
| 203 |
+
|
| 204 |
+
double tp = bccClose - (riskDist * InpRewardRatio);
|
| 205 |
+
double lotSize = CalculateLotSize(MathAbs(sl - bccClose));
|
| 206 |
+
|
| 207 |
+
if(trade.Sell(lotSize, _Symbol, bccClose, sl, tp, "Range Breakout Sell")) {
|
| 208 |
+
tradeTakenToday = true;
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
}
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
//+------------------------------------------------------------------+
|
| 215 |
+
//| Filter: Verify no touches between EP and BCC |
|
| 216 |
+
//+------------------------------------------------------------------+
|
| 217 |
+
bool IsPathClear(datetime startTime, datetime endTime, double level, bool isBuy)
|
| 218 |
+
{
|
| 219 |
+
// We need candles BETWEEN startTime and endTime (exclusive of start, exclusive of end)
|
| 220 |
+
// Logic: Get bars from Start to End.
|
| 221 |
+
|
| 222 |
+
MqlRates rates[];
|
| 223 |
+
ArraySetAsSeries(rates, true);
|
| 224 |
+
|
| 225 |
+
// Copy rates from start time to end time
|
| 226 |
+
int count = CopyRates(_Symbol, PERIOD_M3, startTime, endTime, rates);
|
| 227 |
+
|
| 228 |
+
// Iterate, skipping the first (which matches startTime/EP) and last (which is BCC - handled by logic)
|
| 229 |
+
// Note: CopyRates with start/end includes the bars that contain those times.
|
| 230 |
+
// Because Array is Series, index 0 is the bar AT endTime (The Breakout Candle).
|
| 231 |
+
// Index [count-1] is the bar AT startTime (The EP).
|
| 232 |
+
|
| 233 |
+
for(int i = 1; i < count - 1; i++) {
|
| 234 |
+
if(isBuy) {
|
| 235 |
+
// For Buy: No High should have touched HHR
|
| 236 |
+
if(rates[i].high >= level) return false;
|
| 237 |
+
} else {
|
| 238 |
+
// For Sell: No Low should have touched LLR
|
| 239 |
+
if(rates[i].low <= level) return false;
|
| 240 |
+
}
|
| 241 |
+
}
|
| 242 |
+
return true;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
//+------------------------------------------------------------------+
|
| 246 |
+
//| Risk Management: Calculate Lots based on 1% Risk |
|
| 247 |
+
//+------------------------------------------------------------------+
|
| 248 |
+
double CalculateLotSize(double slDistancePrice)
|
| 249 |
+
{
|
| 250 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 251 |
+
double riskMoney = balance * (InpRiskPercent / 100.0);
|
| 252 |
+
|
| 253 |
+
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
| 254 |
+
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
| 255 |
+
|
| 256 |
+
if(tickSize == 0 || tickValue == 0 || slDistancePrice == 0) return 0.01; // Safety
|
| 257 |
+
|
| 258 |
+
double slPoints = slDistancePrice / tickSize;
|
| 259 |
+
double lotSize = riskMoney / (slPoints * tickValue);
|
| 260 |
+
|
| 261 |
+
// Normalize Lot Size
|
| 262 |
+
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
| 263 |
+
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
| 264 |
+
double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
| 265 |
+
|
| 266 |
+
lotSize = MathFloor(lotSize / stepLot) * stepLot;
|
| 267 |
+
|
| 268 |
+
if(lotSize < minLot) lotSize = minLot;
|
| 269 |
+
if(lotSize > maxLot) lotSize = maxLot;
|
| 270 |
+
|
| 271 |
+
return lotSize;
|
| 272 |
+
}
|
| 273 |
+
//+------------------------------------------------------------------+
|
MQL5 Folder/Dec29_6-8 range/v2.c++
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//+------------------------------------------------------------------+
|
| 2 |
+
//| RangeBreakout_Visual_M3.mq5 |
|
| 3 |
+
//| Copyright 2023, Gemini AI Asst. |
|
| 4 |
+
//| https://www.mql5.com |
|
| 5 |
+
//+------------------------------------------------------------------+
|
| 6 |
+
#property copyright "Gemini AI"
|
| 7 |
+
#property link "https://www.mql5.com"
|
| 8 |
+
#property version "1.10"
|
| 9 |
+
#property strict
|
| 10 |
+
|
| 11 |
+
//--- Include Standard Library for easier trade execution
|
| 12 |
+
#include <Trade\Trade.mqh>
|
| 13 |
+
|
| 14 |
+
//+------------------------------------------------------------------+
|
| 15 |
+
//| Inputs |
|
| 16 |
+
//+------------------------------------------------------------------+
|
| 17 |
+
input group "Risk Management"
|
| 18 |
+
input double InpRiskPercent = 1.0; // Risk per trade (% of Balance)
|
| 19 |
+
input int InpRewardRatio = 10; // Reward Ratio (TP = 10 * Risk)
|
| 20 |
+
|
| 21 |
+
input group "Time Settings"
|
| 22 |
+
input int InpRangeStartHour = 22; // Range Start Hour (UTC equivalent)
|
| 23 |
+
input int InpRangeEndHour = 0; // Range End Hour (0 = Midnight)
|
| 24 |
+
input int InpBrokerOffset = 0; // Broker Time Offset from UTC
|
| 25 |
+
|
| 26 |
+
input group "Visuals"
|
| 27 |
+
input bool InpDrawRange = true; // Draw Range Box on Chart
|
| 28 |
+
input color InpBoxColor = clrLavender; // Color of the Range Box
|
| 29 |
+
|
| 30 |
+
input group "System"
|
| 31 |
+
input ulong InpMagicNum = 123456; // Magic Number
|
| 32 |
+
|
| 33 |
+
//+------------------------------------------------------------------+
|
| 34 |
+
//| Global Variables |
|
| 35 |
+
//+------------------------------------------------------------------+
|
| 36 |
+
CTrade trade;
|
| 37 |
+
datetime lastBarTime = 0;
|
| 38 |
+
bool tradeTakenToday = false;
|
| 39 |
+
int lastTradeDay = -1;
|
| 40 |
+
string rangeObjName = "Range_Box_Visual";
|
| 41 |
+
|
| 42 |
+
// Structure to hold Range Data
|
| 43 |
+
struct RangeData {
|
| 44 |
+
double HHR; // Highest High of Range
|
| 45 |
+
double LLR; // Lowest Low of Range
|
| 46 |
+
datetime timeHHR; // Time of HHR (EP)
|
| 47 |
+
datetime timeLLR; // Time of LLR (EP)
|
| 48 |
+
bool isValid; // Is range calculated?
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
RangeData currentRange;
|
| 52 |
+
|
| 53 |
+
//+------------------------------------------------------------------+
|
| 54 |
+
//| Expert initialization function |
|
| 55 |
+
//+------------------------------------------------------------------+
|
| 56 |
+
int OnInit()
|
| 57 |
+
{
|
| 58 |
+
trade.SetExpertMagicNumber(InpMagicNum);
|
| 59 |
+
|
| 60 |
+
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
|
| 61 |
+
Print("Warning: AutoTrading is disabled in Terminal.");
|
| 62 |
+
|
| 63 |
+
return(INIT_SUCCEEDED);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
//+------------------------------------------------------------------+
|
| 67 |
+
//| Expert deinitialization function |
|
| 68 |
+
//+------------------------------------------------------------------+
|
| 69 |
+
void OnDeinit(const int reason)
|
| 70 |
+
{
|
| 71 |
+
// Cleanup drawing objects when EA is removed
|
| 72 |
+
if(ObjectFind(0, rangeObjName) >= 0) {
|
| 73 |
+
ObjectDelete(0, rangeObjName);
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
//+------------------------------------------------------------------+
|
| 78 |
+
//| Expert tick function |
|
| 79 |
+
//+------------------------------------------------------------------+
|
| 80 |
+
void OnTick()
|
| 81 |
+
{
|
| 82 |
+
datetime currentBarTime = iTime(_Symbol, PERIOD_M3, 0);
|
| 83 |
+
if(currentBarTime == lastBarTime) return; // Wait for candle close
|
| 84 |
+
lastBarTime = currentBarTime;
|
| 85 |
+
|
| 86 |
+
// Reset Daily Flags
|
| 87 |
+
MqlDateTime dt;
|
| 88 |
+
TimeCurrent(dt);
|
| 89 |
+
|
| 90 |
+
if(lastTradeDay != dt.day) {
|
| 91 |
+
tradeTakenToday = false;
|
| 92 |
+
lastTradeDay = dt.day;
|
| 93 |
+
currentRange.isValid = false;
|
| 94 |
+
// Optional: Delete yesterday's box to keep chart clean
|
| 95 |
+
if(ObjectFind(0, rangeObjName) >= 0) ObjectDelete(0, rangeObjName);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
if(tradeTakenToday) return;
|
| 99 |
+
|
| 100 |
+
// Calculate Range if not yet done
|
| 101 |
+
if(!currentRange.isValid) {
|
| 102 |
+
CalculateRange();
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
if(currentRange.isValid) {
|
| 106 |
+
CheckBreakoutSignal();
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
//+------------------------------------------------------------------+
|
| 111 |
+
//| Function to Calculate HHR and LLR |
|
| 112 |
+
//+------------------------------------------------------------------+
|
| 113 |
+
void CalculateRange()
|
| 114 |
+
{
|
| 115 |
+
MqlDateTime dt;
|
| 116 |
+
TimeCurrent(dt);
|
| 117 |
+
|
| 118 |
+
int startHour = InpRangeStartHour + InpBrokerOffset;
|
| 119 |
+
int endHour = InpRangeEndHour + InpBrokerOffset;
|
| 120 |
+
|
| 121 |
+
if(startHour >= 24) startHour -= 24;
|
| 122 |
+
if(endHour >= 24) endHour -= 24;
|
| 123 |
+
|
| 124 |
+
// Calculate specific time range (Yesterday 22:00 to Today 00:00)
|
| 125 |
+
datetime timeEnd = StringToTime(StringFormat("%04d.%02d.%02d %02d:00", dt.year, dt.mon, dt.day, endHour));
|
| 126 |
+
datetime timeStart = timeEnd - (2 * 3600); // 2 hours duration
|
| 127 |
+
|
| 128 |
+
// Check if the current time is actually past the range end
|
| 129 |
+
if(TimeCurrent() < timeEnd) return;
|
| 130 |
+
|
| 131 |
+
// Get Bars inside the range
|
| 132 |
+
MqlRates rates[];
|
| 133 |
+
ArraySetAsSeries(rates, true);
|
| 134 |
+
|
| 135 |
+
int copied = CopyRates(_Symbol, PERIOD_M3, timeStart, timeEnd, rates);
|
| 136 |
+
|
| 137 |
+
if(copied > 0) {
|
| 138 |
+
double highest = -DBL_MAX;
|
| 139 |
+
double lowest = DBL_MAX;
|
| 140 |
+
datetime tHigh = 0;
|
| 141 |
+
datetime tLow = 0;
|
| 142 |
+
|
| 143 |
+
for(int i=0; i<copied; i++) {
|
| 144 |
+
if(rates[i].high > highest) {
|
| 145 |
+
highest = rates[i].high;
|
| 146 |
+
tHigh = rates[i].time;
|
| 147 |
+
}
|
| 148 |
+
if(rates[i].low < lowest) {
|
| 149 |
+
lowest = rates[i].low;
|
| 150 |
+
tLow = rates[i].time;
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
currentRange.HHR = highest;
|
| 155 |
+
currentRange.LLR = lowest;
|
| 156 |
+
currentRange.timeHHR = tHigh;
|
| 157 |
+
currentRange.timeLLR = tLow;
|
| 158 |
+
currentRange.isValid = true;
|
| 159 |
+
|
| 160 |
+
// DRAW THE RANGE
|
| 161 |
+
if(InpDrawRange) {
|
| 162 |
+
DrawRangeBox(timeStart, timeEnd, currentRange.HHR, currentRange.LLR);
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
//+------------------------------------------------------------------+
|
| 168 |
+
//| Function to Draw the Range Box |
|
| 169 |
+
//+------------------------------------------------------------------+
|
| 170 |
+
void DrawRangeBox(datetime t1, datetime t2, double priceHigh, double priceLow)
|
| 171 |
+
{
|
| 172 |
+
// Delete if exists to update
|
| 173 |
+
if(ObjectFind(0, rangeObjName) >= 0) ObjectDelete(0, rangeObjName);
|
| 174 |
+
|
| 175 |
+
// Create Rectangle
|
| 176 |
+
if(ObjectCreate(0, rangeObjName, OBJ_RECTANGLE, 0, t1, priceHigh, t2, priceLow)) {
|
| 177 |
+
ObjectSetInteger(0, rangeObjName, OBJPROP_COLOR, InpBoxColor);
|
| 178 |
+
ObjectSetInteger(0, rangeObjName, OBJPROP_FILL, true); // Fill the box
|
| 179 |
+
ObjectSetInteger(0, rangeObjName, OBJPROP_BACK, true); // Put behind candles
|
| 180 |
+
ObjectSetInteger(0, rangeObjName, OBJPROP_WIDTH, 1);
|
| 181 |
+
ObjectSetString(0, rangeObjName, OBJPROP_TEXT, "Daily Range");
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
//+------------------------------------------------------------------+
|
| 186 |
+
//| Function to Check Breakout & Validation |
|
| 187 |
+
//+------------------------------------------------------------------+
|
| 188 |
+
void CheckBreakoutSignal()
|
| 189 |
+
{
|
| 190 |
+
MqlRates bcc[];
|
| 191 |
+
ArraySetAsSeries(bcc, true);
|
| 192 |
+
if(CopyRates(_Symbol, PERIOD_M3, 1, 1, bcc) != 1) return;
|
| 193 |
+
|
| 194 |
+
double bccClose = bcc[0].close;
|
| 195 |
+
double bccHigh = bcc[0].high;
|
| 196 |
+
double bccLow = bcc[0].low;
|
| 197 |
+
datetime bccTime = bcc[0].time;
|
| 198 |
+
|
| 199 |
+
// --- BUY LOGIC ---
|
| 200 |
+
if(bccClose > currentRange.HHR) {
|
| 201 |
+
if(IsPathClear(currentRange.timeHHR, bccTime, currentRange.HHR, true)) {
|
| 202 |
+
|
| 203 |
+
double sl = bccLow;
|
| 204 |
+
double riskDist = bccClose - sl;
|
| 205 |
+
|
| 206 |
+
if(riskDist <= 0) return;
|
| 207 |
+
|
| 208 |
+
double tp = bccClose + (riskDist * InpRewardRatio);
|
| 209 |
+
double lotSize = CalculateLotSize(MathAbs(bccClose - sl));
|
| 210 |
+
|
| 211 |
+
if(trade.Buy(lotSize, _Symbol, bccClose, sl, tp, "Range Breakout Buy")) {
|
| 212 |
+
tradeTakenToday = true;
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
// --- SELL LOGIC ---
|
| 218 |
+
else if(bccClose < currentRange.LLR) {
|
| 219 |
+
if(IsPathClear(currentRange.timeLLR, bccTime, currentRange.LLR, false)) {
|
| 220 |
+
|
| 221 |
+
double sl = bccHigh;
|
| 222 |
+
double riskDist = sl - bccClose;
|
| 223 |
+
|
| 224 |
+
if(riskDist <= 0) return;
|
| 225 |
+
|
| 226 |
+
double tp = bccClose - (riskDist * InpRewardRatio);
|
| 227 |
+
double lotSize = CalculateLotSize(MathAbs(sl - bccClose));
|
| 228 |
+
|
| 229 |
+
if(trade.Sell(lotSize, _Symbol, bccClose, sl, tp, "Range Breakout Sell")) {
|
| 230 |
+
tradeTakenToday = true;
|
| 231 |
+
}
|
| 232 |
+
}
|
| 233 |
+
}
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
//+------------------------------------------------------------------+
|
| 237 |
+
//| Filter: Verify no touches between EP and BCC |
|
| 238 |
+
//+------------------------------------------------------------------+
|
| 239 |
+
bool IsPathClear(datetime startTime, datetime endTime, double level, bool isBuy)
|
| 240 |
+
{
|
| 241 |
+
MqlRates rates[];
|
| 242 |
+
ArraySetAsSeries(rates, true);
|
| 243 |
+
|
| 244 |
+
int count = CopyRates(_Symbol, PERIOD_M3, startTime, endTime, rates);
|
| 245 |
+
|
| 246 |
+
// Loop excludes start (EP) and end (BCC)
|
| 247 |
+
for(int i = 1; i < count - 1; i++) {
|
| 248 |
+
if(isBuy) {
|
| 249 |
+
if(rates[i].high >= level) return false;
|
| 250 |
+
} else {
|
| 251 |
+
if(rates[i].low <= level) return false;
|
| 252 |
+
}
|
| 253 |
+
}
|
| 254 |
+
return true;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
//+------------------------------------------------------------------+
|
| 258 |
+
//| Risk Management |
|
| 259 |
+
//+------------------------------------------------------------------+
|
| 260 |
+
double CalculateLotSize(double slDistancePrice)
|
| 261 |
+
{
|
| 262 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 263 |
+
double riskMoney = balance * (InpRiskPercent / 100.0);
|
| 264 |
+
|
| 265 |
+
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
| 266 |
+
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
| 267 |
+
|
| 268 |
+
if(tickSize == 0 || tickValue == 0 || slDistancePrice == 0) return 0.01;
|
| 269 |
+
|
| 270 |
+
double slPoints = slDistancePrice / tickSize;
|
| 271 |
+
double lotSize = riskMoney / (slPoints * tickValue);
|
| 272 |
+
|
| 273 |
+
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
| 274 |
+
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
| 275 |
+
double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
| 276 |
+
|
| 277 |
+
lotSize = MathFloor(lotSize / stepLot) * stepLot;
|
| 278 |
+
|
| 279 |
+
if(lotSize < minLot) lotSize = minLot;
|
| 280 |
+
if(lotSize > maxLot) lotSize = maxLot;
|
| 281 |
+
|
| 282 |
+
return lotSize;
|
| 283 |
+
}
|
| 284 |
+
//+------------------------------------------------------------------+
|
MQL5 Folder/Developing POC/developing POC line.ipynb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "fdbde53e",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"This error is from the toolbox of MT5: {} it has a CSV format of \"Description, File, Line, Column,\" columns with their corresponding rows. But I only want you to care about what is written in the Description and Line because that's the 'error' it wants to depict. Then, after that, revise the previous code you've given me based on that 'Description' withthe corresponding 'Line' error specification statements."
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "7f2371cf",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"This error is from the toolbox of MT5: {\n",
|
| 17 |
+
"} It has a CSV format of \"Description, File, Line, Column,\" columns with their corresponding rows. But I only want you to care about what is written in the Description and Line because that's the 'error' it wants to depict. Then, after that, revise the previous code you've given me based on that 'Description' with the corresponding 'Line' error specification statements."
|
| 18 |
+
]
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"cell_type": "markdown",
|
| 22 |
+
"id": "1c85cb54",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"source": []
|
| 25 |
+
}
|
| 26 |
+
],
|
| 27 |
+
"metadata": {
|
| 28 |
+
"language_info": {
|
| 29 |
+
"name": "python"
|
| 30 |
+
}
|
| 31 |
+
},
|
| 32 |
+
"nbformat": 4,
|
| 33 |
+
"nbformat_minor": 5
|
| 34 |
+
}
|
MQL5 Folder/H3 0 bar redbear bluebull (indicator)/1_version.mq5
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property indicator_chart_window
|
| 2 |
+
#property indicator_buffers 5
|
| 3 |
+
#property indicator_plots 1
|
| 4 |
+
|
| 5 |
+
#property indicator_type1 DRAW_COLOR_CANDLES
|
| 6 |
+
#property indicator_label1 "H3 00:00 Candle"
|
| 7 |
+
#property indicator_color1 clrBlue, clrRed
|
| 8 |
+
|
| 9 |
+
// =====================
|
| 10 |
+
// BUFFERS
|
| 11 |
+
// =====================
|
| 12 |
+
double OpenBuf[];
|
| 13 |
+
double HighBuf[];
|
| 14 |
+
double LowBuf[];
|
| 15 |
+
double CloseBuf[];
|
| 16 |
+
double ColorBuf[];
|
| 17 |
+
|
| 18 |
+
// =====================
|
| 19 |
+
// INIT
|
| 20 |
+
// =====================
|
| 21 |
+
int OnInit()
|
| 22 |
+
{
|
| 23 |
+
// Chart visual settings
|
| 24 |
+
ChartSetInteger(0, CHART_SHOW_GRID, false);
|
| 25 |
+
ChartSetInteger(0, CHART_SHOW_BID_LINE, true);
|
| 26 |
+
ChartSetInteger(0, CHART_SHOW_ASK_LINE, true);
|
| 27 |
+
|
| 28 |
+
SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);
|
| 29 |
+
SetIndexBuffer(1, HighBuf, INDICATOR_DATA);
|
| 30 |
+
SetIndexBuffer(2, LowBuf, INDICATOR_DATA);
|
| 31 |
+
SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);
|
| 32 |
+
SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);
|
| 33 |
+
|
| 34 |
+
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
|
| 35 |
+
PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);
|
| 36 |
+
|
| 37 |
+
IndicatorSetString(INDICATOR_SHORTNAME, "H3 00:00 Bull/Bear Candle");
|
| 38 |
+
|
| 39 |
+
return(INIT_SUCCEEDED);
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
// =====================
|
| 43 |
+
// CALCULATION
|
| 44 |
+
// =====================
|
| 45 |
+
int OnCalculate(
|
| 46 |
+
const int rates_total,
|
| 47 |
+
const int prev_calculated,
|
| 48 |
+
const datetime &time[],
|
| 49 |
+
const double &open[],
|
| 50 |
+
const double &high[],
|
| 51 |
+
const double &low[],
|
| 52 |
+
const double &close[],
|
| 53 |
+
const long &tick_volume[],
|
| 54 |
+
const long &volume[],
|
| 55 |
+
const int &spread[]
|
| 56 |
+
)
|
| 57 |
+
{
|
| 58 |
+
if(_Period != PERIOD_H3)
|
| 59 |
+
return(rates_total);
|
| 60 |
+
|
| 61 |
+
int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
|
| 62 |
+
|
| 63 |
+
for(int i = start; i < rates_total; i++)
|
| 64 |
+
{
|
| 65 |
+
OpenBuf[i] = open[i];
|
| 66 |
+
HighBuf[i] = high[i];
|
| 67 |
+
LowBuf[i] = low[i];
|
| 68 |
+
CloseBuf[i] = close[i];
|
| 69 |
+
|
| 70 |
+
ColorBuf[i] = EMPTY_VALUE;
|
| 71 |
+
|
| 72 |
+
MqlDateTime t;
|
| 73 |
+
TimeToStruct(time[i], t);
|
| 74 |
+
|
| 75 |
+
// H3 candle starting at 00:00
|
| 76 |
+
if(t.hour == 0)
|
| 77 |
+
{
|
| 78 |
+
if(close[i] > open[i])
|
| 79 |
+
ColorBuf[i] = 0; // Bullish (Blue)
|
| 80 |
+
else if(close[i] < open[i])
|
| 81 |
+
ColorBuf[i] = 1; // Bearish (Red)
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
return(rates_total);
|
| 86 |
+
}
|
MQL5 Folder/H3 0 bar redbear bluebull (indicator)/H3 0 bar redbear bluebull (indicator).ipynb
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "07883ea1",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"indicator that makes that 0:00 H3 bullish bar blue and red if bearish"
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "35195363",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"#property indicator_chart_window\n",
|
| 17 |
+
"#property indicator_buffers 5\n",
|
| 18 |
+
"#property indicator_plots 1\n",
|
| 19 |
+
"\n",
|
| 20 |
+
"#property indicator_type1 DRAW_COLOR_CANDLES\n",
|
| 21 |
+
"#property indicator_label1 \"H3 00:00 Candle\"\n",
|
| 22 |
+
"#property indicator_color1 clrBlue, clrRed\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"// =====================\n",
|
| 25 |
+
"// BUFFERS\n",
|
| 26 |
+
"// =====================\n",
|
| 27 |
+
"double OpenBuf[];\n",
|
| 28 |
+
"double HighBuf[];\n",
|
| 29 |
+
"double LowBuf[];\n",
|
| 30 |
+
"double CloseBuf[];\n",
|
| 31 |
+
"double ColorBuf[];\n",
|
| 32 |
+
"\n",
|
| 33 |
+
"// =====================\n",
|
| 34 |
+
"// INIT\n",
|
| 35 |
+
"// =====================\n",
|
| 36 |
+
"int OnInit()\n",
|
| 37 |
+
"{\n",
|
| 38 |
+
" SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);\n",
|
| 39 |
+
" SetIndexBuffer(1, HighBuf, INDICATOR_DATA);\n",
|
| 40 |
+
" SetIndexBuffer(2, LowBuf, INDICATOR_DATA);\n",
|
| 41 |
+
" SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);\n",
|
| 42 |
+
" SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);\n",
|
| 43 |
+
"\n",
|
| 44 |
+
" PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);\n",
|
| 45 |
+
" PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);\n",
|
| 46 |
+
"\n",
|
| 47 |
+
" IndicatorSetString(INDICATOR_SHORTNAME, \"H3 00:00 Bull/Bear Candle\");\n",
|
| 48 |
+
"\n",
|
| 49 |
+
" return(INIT_SUCCEEDED);\n",
|
| 50 |
+
"}\n",
|
| 51 |
+
"\n",
|
| 52 |
+
"// =====================\n",
|
| 53 |
+
"// CALCULATION\n",
|
| 54 |
+
"// =====================\n",
|
| 55 |
+
"int OnCalculate(\n",
|
| 56 |
+
" const int rates_total,\n",
|
| 57 |
+
" const int prev_calculated,\n",
|
| 58 |
+
" const datetime &time[],\n",
|
| 59 |
+
" const double &open[],\n",
|
| 60 |
+
" const double &high[],\n",
|
| 61 |
+
" const double &low[],\n",
|
| 62 |
+
" const double &close[],\n",
|
| 63 |
+
" const long &tick_volume[],\n",
|
| 64 |
+
" const long &volume[],\n",
|
| 65 |
+
" const int &spread[]\n",
|
| 66 |
+
")\n",
|
| 67 |
+
"{\n",
|
| 68 |
+
" // Only valid on H3\n",
|
| 69 |
+
" if(_Period != PERIOD_H3)\n",
|
| 70 |
+
" return(rates_total);\n",
|
| 71 |
+
"\n",
|
| 72 |
+
" int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;\n",
|
| 73 |
+
"\n",
|
| 74 |
+
" for(int i = start; i < rates_total; i++)\n",
|
| 75 |
+
" {\n",
|
| 76 |
+
" // Copy price data\n",
|
| 77 |
+
" OpenBuf[i] = open[i];\n",
|
| 78 |
+
" HighBuf[i] = high[i];\n",
|
| 79 |
+
" LowBuf[i] = low[i];\n",
|
| 80 |
+
" CloseBuf[i] = close[i];\n",
|
| 81 |
+
"\n",
|
| 82 |
+
" ColorBuf[i] = EMPTY_VALUE;\n",
|
| 83 |
+
"\n",
|
| 84 |
+
" MqlDateTime t;\n",
|
| 85 |
+
" TimeToStruct(time[i], t);\n",
|
| 86 |
+
"\n",
|
| 87 |
+
" // Check H3 candle starting at 00:00\n",
|
| 88 |
+
" if(t.hour == 0 && (t.hour % 3) == 0)\n",
|
| 89 |
+
" {\n",
|
| 90 |
+
" if(close[i] > open[i])\n",
|
| 91 |
+
" ColorBuf[i] = 0; // Blue (bullish)\n",
|
| 92 |
+
" else if(close[i] < open[i])\n",
|
| 93 |
+
" ColorBuf[i] = 1; // Red (bearish)\n",
|
| 94 |
+
" }\n",
|
| 95 |
+
" }\n",
|
| 96 |
+
"\n",
|
| 97 |
+
" return(rates_total);\n",
|
| 98 |
+
"}\n"
|
| 99 |
+
]
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"cell_type": "markdown",
|
| 103 |
+
"id": "9dd739c6",
|
| 104 |
+
"metadata": {},
|
| 105 |
+
"source": [
|
| 106 |
+
"remove the grid of the chart\n",
|
| 107 |
+
"ChartSetInteger(0, CHART_SHOW_GRID, false); in OnInit()"
|
| 108 |
+
]
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"attachments": {
|
| 112 |
+
"image.png": {
|
| 113 |
+
"image/png": "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U3LHtGnT3F/+8hf3zTffJEpO3Pbt292ll15qyw6jbcjudixdutSWqb8AAMTVaR/glC5d2i7YK1ascPv377eylStXuh07drh//OMf7l//+peVrVq1ylWoUMECn5xQQHDjjTe6ZcuWJUq+c+TIEffaa6+5V155xR0+fDhRCgAATpXTPsApUKCAu+GGG9y6devcZ599ZmWzZ892l112mdu2bZvbunWrZVUWLFjg6tev78455xyrk11a1vLly0MzNIUKFXLDhw93Y8aMcUWLFk2UAgCAUyUWY3CuvPJKy6IoyFEWRxmcn//8565YsWJuw4YNbs+ePW79+vWuQYMGFhDJrl273J133ulKlSrlmjVrZoGQvPDCC9aVpfLq1au7mTNnWhdR69at3cGDB12TJk3coEGDrK6ndfpuLwVAL774YnIZP/7xj92BAwcSNb/18ccfu5YtW9p0PTp06OD27t1r806ePNnWq/JevXq5Q4cOJeZytg3KImma2qyuOE/r6NmzpytTpow9HnvsMWvvV1995QYPHuzOP/98d+6559r2ff3114m5AACIp1gEOJUqVXKXXHKJdR9t2bLFMjnK1tSsWdOyOZs3b3Y7d+50V111VWIOZ11avXv3djNmzHBr1qyxLiZRAKFpX3zxhbvlllssONAYnwkTJljANHfuXNe9e3erG0ZZnieffNL98Y9/tKDl1VdfdcWLF09M/VbJkiXdkCFDbB3z5893f/3rX917771n7deyH330URt/07hxY/f555/bPAqiHnjgAdtWBTYDBgyw7RIFRn379rU6yjQtXrzYvf766+6NN96w4Oy3v/2tZZc0X8WKFW29AADEWSwCnBIlSliX1LvvvmuPsmXLumrVqlnXlYKVDz/80MqqVq2amMO56667zjI/derUscemTZusXIOW77vvPhurM2rUKMsMhXVLRSlfvry74IILLBgZO3bscdkbKVKkiI3XadiwobVRAYfWo2BH8996660WFH3/+9+3gEQ2btxo44jatWvn/vM//9Parm0QBXQKZBTEKFNTr149q68ASAGc1qMgTYGVlq1MDgAAcRaLAEcUKKgLR5mY//qv/7KgR1kddT0p+6KByBqQHEXZFnVxtW/f3v3P//yPPVdWJLvKlSvnpk+f7vr06eMGDhzoWrRokRwb5PXr18/NmTPHvfXWWxaAKSsj6k5S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bt26uUaNGtlfLSdY5h8LFiyw+qlUV8vT3cg7duxot0YYO3Zssr7+6rXMmzfPboJ533332XqC9WT48OGR99hKbbfo9guPPvqou/322+2ml7oBpl+mbtypMt1QM0xwn3gq03b4bdayVNahQwe3fv16q6t5/Ly+np4DAJAdsQpwdE+knTt32kPPc4su5s8//7zr1auX3cupXbt27ssvv7RgQ44ePZp8rovztm3b7ILtywoXLuymTJni7r77bjd69GhXvHhxN3jwYDds2DDXvHlzu/t448aNrW6qGTNmuKpVq7qJEye6ESNG2P2d1J5Dhw7ZdP3V67Vr17qpU6fa8nv27Gl34tYNKX09UT21NUxYu3UX7x/84Adu8uTJ7sknn3RFihSxZRw8eND96U9/ck2aNHEXXXSR1U0V3Cee2qPt0DZr2++55x6rt3nzZrs/ln65pnlUpnE2qqN907t378QSAADIDF1UGVA2RBdnBRpSsGBB+7tlyxY3bdo0N2vWLLvoy4oVK1z9+vVdzZo13cqVK61MF2wFELqhZrVq1awsUzVq1LDgaPHixccEJx988IGtW39FQULdunUtePLt1I07FSiMGTPG2iVRP68Oa3ft2rVt3nXr1lmGx3v99ddtPTfffHOi5MRoPbq5qdbjHTlyxDJF2kYFXQAAZEesAhzdwbps2bL20PPcoqxFyZIlE6+iKQhQwFGnTh3XoEED984771i5sj0KgpYuXepuu+02K8vUZZddZtmeRYsWWcZj69atiSnHU9ARpDtuqytN7XjrrbesLLWORLW7WbNmlglTJuf++++3/SAfffSRBSC5Rf/b5sYbb7RsFQAAuSFWAU7btm0tS6KHnueWKlWq2EXdX+C9SpUquZYtW7qmTZu6YsWKuV27drm5c+e6zp07ux49elj3irpcNE1jT6644go3e/bsxNyZU7eUlnn99de71atXW5kCEa1bf6Vo0aLuww8/tGBF2SJ195QpU8YCHNVTt93u3butbirVD2u3VKhQwbqIypUrZ/tAunTpYoFWcHzPidJ2bN++PbmOQoUKWbed2n7xxRdbGQAAmaKLKgMKZNR907p1a/fggw/a+JYwq1atcjfddJMFCAsXLnTXXnutdW95yogoO5IaKKWj7EnXrl3dww8/bN1UyrKEueaaayyrooHQGvzbvn17+4+/mzZtcg0bNnQXXnihrVfBVip1T6W2W4OHn3nmGVuv1q8Bxn68jcYUKch56aWX0maUtIw+ffpYe9TtpW6op59+2s2fP9/24Zw5cxI1nbWrRYsWFmyJ1qc6mlf7AACA7OBWDRH8hRb5k8ZEAQAQhQAnwskOcNSt9sQTT9jAYO+SSy5xjzzySGjWJaf0KzD9YimoTZs29vP3nFBXlsbp6CflnrqzNAZKXWt5hQAHAJAOAU4EdadwS4D8SYOSNYAaAIAojMGJoPErupAif/F3EwcAIB0yOAAAIHbI4AAAgNghwAEAALFDgAMAAGKHAAcAAMQOAQ4AAIgdAhwAABA7BDgAACB2CHAAAEDs8I/+kGNff/21+9e//nXa3dLC/zfks84ivgeAuOIMjxw7HYMbUZvVdgBAfBHgIMdO55uRciNVAIi3WAQ4S5cudeeff77dYVqPzp07J6aE279/v9XZvn27vZ42bZobNGiQPc/vUtseNHLkSNsXmdI2a9uD9LpVq1a2HgAATlexyeD85Cc/cXv37nXbtm2zv9m50OM7LVu2dG+++aYrUaJEouTUOnr0qNuzZ4/LZKiY6mzYsMEdOHDAXn/22Wdu06ZN9hwAcGaJXRfVvn377IJYvnx5e60shc/sKDOhi96dd97pxo8f72rWrJnMYGzdutVdeumlkRmg4HL8dAVReq7l+qxHsF5qdkSUefHr8fOoXo8ePY5bfzAzpWnBrM0bb7yRXE9Y9knLDJuuZatMy33//fcTpd/ROpUJErXp8ccfTy4nbHuCVq9e7e69917XunVr99577yVKjzd27FjXqFEje+i9+PzzzxNTjrdlyxbXtWtXt2vXrkSJs6DlD3/4Q+LVdxYtWuTGjRvnChcubK+LFi3qRowYYe8tAODMEpsA56WXXrKLsIKWbt26WYCjC/LMmTOTWZ3KlSu7l19+2U2cONG1adPGrV271jIWoqzFrFmzIjNA3bt3t3I9SpYsmZw+b948179/f5t/7ty5VqY6Ws6UKVOOCUoUzPTp08fWozpq5/Dhw21a2Prr1q3rduzYYa8HDBhgQZls3rzZghOVaxsmTZp0THv1/O2337bpeugCrzLtD82rdWzcuNECwXQULCrA0DK0bWPGjInsulKQ8sILL1g7f/e737nRo0e7L774woIRrVPtWbNmjdW955573LBhw1zz5s3tvTj33HNtP6nu/Pnz3eLFiy0bs3v3btu+Dh06JDNKqqftWLhwof312622vvLKK65Lly6uUKFCVqb3ScGW9hs/FgSAM0vsuqj0UGChi5/+KojwF0dd/KK+zXfs2NGCItVt1qxZovQ7wcyLghIFCaIsjAIR0foUwKhOhQoVjgtw1q1bZ2UKwlRHF19lPSRq/T7jEqyrQK1v3772XPNcfvnlyfbI7NmzrY2aL9je4P7QQwFGOgoQtM+kRo0atv1RPvnkE1etWjVXrlw5yw6dd955FhxNnz7dPfbYY65SpUrWjp07dybmONaKFSvc/fff70qXLu2mTp1q26qfcmtfTZ482d5XOeecc6wd2u769eu76tWrW7mCpwsvvNCVLVvWXnsXXXSR+/TTT9NmiQAA8RO7Liq59dZb7WKeW5S1UAZH3R+60PrgIsyECROSgZayLz748Zo2bZrM0uihTEYUdS3Vrl3b6imDooAjU2qjX4cePlOVl4oXL5549h39r5y2bdu6WrVqWbClLsIoP/jBD1ydOnXcBRdcYPtOmRgFTL7LSYoUKWJBjrqfFERpmaJslM/cBKlNxYoVOyYABADEXywDHAU3CnL0GDx4cLJbZejQoa5ixYr2PDuC43q0LHV7hVEwElxfKs2/bNmyZFdWVpTF0DJFWRm1Q9Tls2TJEnuuLprly5e7evXq2WvRPBp7Esweicp94JduO3JCQYSyKIcOHbJ2qntKwUmQgp0jR44kXkVTPQ0uzo6CBQvafKm0HE1LbYsogAwbvwQAOP3FbgyO/0avjIUe6s5Rd5EvVyZG3TO62AcHGaejwETdOaqvLhF1o4TRsoPr84OIPS1HWaB27dol25pu/eoe8nU15sZncLQOBVIqb9GihY190bI9bbe6vHxXmB+g3KlTJwuOVJZuO3JCXUHqKlN7NShY2Zhgm4LmzJnjhgwZYuNtnn76acswhVm5cqV1+WnbNc5Jr6Vq1aqW4XnooYdsrI9o/R9//LEFWEHqOjt8+LBlfQAAZw5u1YAcy2/jWl588UUbg6PMnejQHjhwoGvSpIlr0KCBlQVpcDMAIJ5i2UWFM5OyR+pK1K+vRF1mGvh89dVX22sAwJmDDA5yTF1Lp+stD3TDTXXVAQDiiQwOckw/41agcLrxdxMHAMQXGRwAABA7ZHAAAEDsEOAAAIDYIcABAACxQ4ADAABihwAHAADEDgEOAACIGef+H8VU/AHxqyxSAAAAAElFTkSuQmCC"
|
| 114 |
+
}
|
| 115 |
+
},
|
| 116 |
+
"cell_type": "markdown",
|
| 117 |
+
"id": "b5503b25",
|
| 118 |
+
"metadata": {},
|
| 119 |
+
"source": [
|
| 120 |
+
""
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"cell_type": "code",
|
| 125 |
+
"execution_count": null,
|
| 126 |
+
"id": "d0611a9f",
|
| 127 |
+
"metadata": {
|
| 128 |
+
"vscode": {
|
| 129 |
+
"languageId": "plaintext"
|
| 130 |
+
}
|
| 131 |
+
},
|
| 132 |
+
"outputs": [],
|
| 133 |
+
"source": [
|
| 134 |
+
"#property indicator_chart_window\n",
|
| 135 |
+
"#property indicator_buffers 5\n",
|
| 136 |
+
"#property indicator_plots 1\n",
|
| 137 |
+
"\n",
|
| 138 |
+
"#property indicator_type1 DRAW_COLOR_CANDLES\n",
|
| 139 |
+
"#property indicator_label1 \"H3 00:00 Candle\"\n",
|
| 140 |
+
"#property indicator_color1 clrBlue, clrRed\n",
|
| 141 |
+
"\n",
|
| 142 |
+
"// =====================\n",
|
| 143 |
+
"// BUFFERS\n",
|
| 144 |
+
"// =====================\n",
|
| 145 |
+
"double OpenBuf[];\n",
|
| 146 |
+
"double HighBuf[];\n",
|
| 147 |
+
"double LowBuf[];\n",
|
| 148 |
+
"double CloseBuf[];\n",
|
| 149 |
+
"double ColorBuf[];\n",
|
| 150 |
+
"\n",
|
| 151 |
+
"// =====================\n",
|
| 152 |
+
"// INIT\n",
|
| 153 |
+
"// =====================\n",
|
| 154 |
+
"int OnInit()\n",
|
| 155 |
+
"{\n",
|
| 156 |
+
" // Chart visual settings\n",
|
| 157 |
+
" ChartSetInteger(0, CHART_SHOW_GRID, false);\n",
|
| 158 |
+
" ChartSetInteger(0, CHART_SHOW_BID_LINE, true);\n",
|
| 159 |
+
" ChartSetInteger(0, CHART_SHOW_ASK_LINE, true);\n",
|
| 160 |
+
"\n",
|
| 161 |
+
" SetIndexBuffer(0, OpenBuf, INDICATOR_DATA);\n",
|
| 162 |
+
" SetIndexBuffer(1, HighBuf, INDICATOR_DATA);\n",
|
| 163 |
+
" SetIndexBuffer(2, LowBuf, INDICATOR_DATA);\n",
|
| 164 |
+
" SetIndexBuffer(3, CloseBuf, INDICATOR_DATA);\n",
|
| 165 |
+
" SetIndexBuffer(4, ColorBuf, INDICATOR_COLOR_INDEX);\n",
|
| 166 |
+
"\n",
|
| 167 |
+
" PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);\n",
|
| 168 |
+
" PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);\n",
|
| 169 |
+
"\n",
|
| 170 |
+
" IndicatorSetString(INDICATOR_SHORTNAME, \"H3 00:00 Bull/Bear Candle\");\n",
|
| 171 |
+
"\n",
|
| 172 |
+
" return(INIT_SUCCEEDED);\n",
|
| 173 |
+
"}\n",
|
| 174 |
+
"\n",
|
| 175 |
+
"// =====================\n",
|
| 176 |
+
"// CALCULATION\n",
|
| 177 |
+
"// =====================\n",
|
| 178 |
+
"int OnCalculate(\n",
|
| 179 |
+
" const int rates_total,\n",
|
| 180 |
+
" const int prev_calculated,\n",
|
| 181 |
+
" const datetime &time[],\n",
|
| 182 |
+
" const double &open[],\n",
|
| 183 |
+
" const double &high[],\n",
|
| 184 |
+
" const double &low[],\n",
|
| 185 |
+
" const double &close[],\n",
|
| 186 |
+
" const long &tick_volume[],\n",
|
| 187 |
+
" const long &volume[],\n",
|
| 188 |
+
" const int &spread[]\n",
|
| 189 |
+
")\n",
|
| 190 |
+
"{\n",
|
| 191 |
+
" if(_Period != PERIOD_H3)\n",
|
| 192 |
+
" return(rates_total);\n",
|
| 193 |
+
"\n",
|
| 194 |
+
" int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;\n",
|
| 195 |
+
"\n",
|
| 196 |
+
" for(int i = start; i < rates_total; i++)\n",
|
| 197 |
+
" {\n",
|
| 198 |
+
" OpenBuf[i] = open[i];\n",
|
| 199 |
+
" HighBuf[i] = high[i];\n",
|
| 200 |
+
" LowBuf[i] = low[i];\n",
|
| 201 |
+
" CloseBuf[i] = close[i];\n",
|
| 202 |
+
"\n",
|
| 203 |
+
" ColorBuf[i] = EMPTY_VALUE;\n",
|
| 204 |
+
"\n",
|
| 205 |
+
" MqlDateTime t;\n",
|
| 206 |
+
" TimeToStruct(time[i], t);\n",
|
| 207 |
+
"\n",
|
| 208 |
+
" // H3 candle starting at 00:00\n",
|
| 209 |
+
" if(t.hour == 0)\n",
|
| 210 |
+
" {\n",
|
| 211 |
+
" if(close[i] > open[i])\n",
|
| 212 |
+
" ColorBuf[i] = 0; // Bullish (Blue)\n",
|
| 213 |
+
" else if(close[i] < open[i])\n",
|
| 214 |
+
" ColorBuf[i] = 1; // Bearish (Red)\n",
|
| 215 |
+
" }\n",
|
| 216 |
+
" }\n",
|
| 217 |
+
"\n",
|
| 218 |
+
" return(rates_total);\n",
|
| 219 |
+
"}\n"
|
| 220 |
+
]
|
| 221 |
+
},
|
| 222 |
+
{
|
| 223 |
+
"cell_type": "markdown",
|
| 224 |
+
"id": "7186708c",
|
| 225 |
+
"metadata": {},
|
| 226 |
+
"source": [
|
| 227 |
+
"Use MQL5, do not ever mix MT4-style functions in MT5, do not ever use the MT4-style helper, "
|
| 228 |
+
]
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"cell_type": "markdown",
|
| 232 |
+
"id": "db07c1e8",
|
| 233 |
+
"metadata": {},
|
| 234 |
+
"source": [
|
| 235 |
+
"Make an MT5 indicator that draws a box (range size) at the first bar from 0:00 am time, extend this box 4 bars to the right. Use MQL5, do not ever mix MT4-style functions in MT5, do not ever use the MT4-style helper, "
|
| 236 |
+
]
|
| 237 |
+
},
|
| 238 |
+
{
|
| 239 |
+
"cell_type": "markdown",
|
| 240 |
+
"id": "b60c0f99",
|
| 241 |
+
"metadata": {},
|
| 242 |
+
"source": [
|
| 243 |
+
"#property indicator_chart_window\n",
|
| 244 |
+
"#property indicator_buffers 0\n",
|
| 245 |
+
"\n",
|
| 246 |
+
"#include <ChartObjects\\ChartObjectsShapes.mqh>\n",
|
| 247 |
+
"\n",
|
| 248 |
+
"input color BoxColor = clrYellow; // Color of the box\n",
|
| 249 |
+
"input int BoxWidth = 2; // Width of the box border\n",
|
| 250 |
+
"input int ExtendBars = 4; // How many bars to extend to the right\n",
|
| 251 |
+
"\n",
|
| 252 |
+
"// Global variables\n",
|
| 253 |
+
"CChartObjectRect box;\n",
|
| 254 |
+
"datetime lastDate = 0;\n",
|
| 255 |
+
"\n",
|
| 256 |
+
"//+------------------------------------------------------------------+\n",
|
| 257 |
+
"//| Custom indicator iteration function |\n",
|
| 258 |
+
"//+------------------------------------------------------------------+\n",
|
| 259 |
+
"int OnCalculate(const int rates_total,\n",
|
| 260 |
+
" const int prev_calculated,\n",
|
| 261 |
+
" const int begin,\n",
|
| 262 |
+
" const double &price[])\n",
|
| 263 |
+
"{\n",
|
| 264 |
+
" if(rates_total < 1)\n",
|
| 265 |
+
" return(0);\n",
|
| 266 |
+
"\n",
|
| 267 |
+
" // Get the current bar's date (YYYYMMDD)\n",
|
| 268 |
+
" datetime barTime = iTime(_Symbol, PERIOD_CURRENT, 0);\n",
|
| 269 |
+
" MqlDateTime dt;\n",
|
| 270 |
+
" TimeToStruct(barTime, dt);\n",
|
| 271 |
+
"\n",
|
| 272 |
+
" // Only once per new day\n",
|
| 273 |
+
" if(dt.hour == 0 && dt.min == 0 && lastDate != dt.day)\n",
|
| 274 |
+
" {\n",
|
| 275 |
+
" lastDate = dt.day;\n",
|
| 276 |
+
"\n",
|
| 277 |
+
" // Determine high and low of the first bar\n",
|
| 278 |
+
" double barHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);\n",
|
| 279 |
+
" double barLow = iLow(_Symbol, PERIOD_CURRENT, 0);\n",
|
| 280 |
+
"\n",
|
| 281 |
+
" // Delete previous box if exists\n",
|
| 282 |
+
" if(box.Name() != \"\")\n",
|
| 283 |
+
" box.Delete();\n",
|
| 284 |
+
"\n",
|
| 285 |
+
" // Create a new rectangle\n",
|
| 286 |
+
" string boxName = \"MidnightBox_\" + IntegerToString(dt.day);\n",
|
| 287 |
+
" if(!box.Create(0, boxName, 0, 0, 0))\n",
|
| 288 |
+
" {\n",
|
| 289 |
+
" Print(\"Failed to create box!\");\n",
|
| 290 |
+
" return(prev_calculated);\n",
|
| 291 |
+
" }\n",
|
| 292 |
+
"\n",
|
| 293 |
+
" // Set rectangle properties\n",
|
| 294 |
+
" box.SetInteger(OBJPROP_COLOR, BoxColor);\n",
|
| 295 |
+
" box.SetInteger(OBJPROP_WIDTH, BoxWidth);\n",
|
| 296 |
+
" box.SetInteger(OBJPROP_STYLE, STYLE_SOLID);\n",
|
| 297 |
+
" box.SetInteger(OBJPROP_RAY_RIGHT, false);\n",
|
| 298 |
+
"\n",
|
| 299 |
+
" // Set coordinates: start from the current bar, extend to the right\n",
|
| 300 |
+
" int startBar = 0;\n",
|
| 301 |
+
" int endBar = MathMin(rates_total - 1, startBar + ExtendBars);\n",
|
| 302 |
+
"\n",
|
| 303 |
+
" box.SetInteger(OBJPROP_TIME1, iTime(_Symbol, PERIOD_CURRENT, startBar));\n",
|
| 304 |
+
" box.SetDouble(OBJPROP_PRICE1, barHigh);\n",
|
| 305 |
+
"\n",
|
| 306 |
+
" box.SetInteger(OBJPROP_TIME2, iTime(_Symbol, PERIOD_CURRENT, endBar));\n",
|
| 307 |
+
" box.SetDouble(OBJPROP_PRICE2, barLow);\n",
|
| 308 |
+
" }\n",
|
| 309 |
+
"\n",
|
| 310 |
+
" return(rates_total);\n",
|
| 311 |
+
"}\n"
|
| 312 |
+
]
|
| 313 |
+
}
|
| 314 |
+
],
|
| 315 |
+
"metadata": {
|
| 316 |
+
"language_info": {
|
| 317 |
+
"name": "python"
|
| 318 |
+
}
|
| 319 |
+
},
|
| 320 |
+
"nbformat": 4,
|
| 321 |
+
"nbformat_minor": 5
|
| 322 |
+
}
|
MQL5 Folder/Revised 0-3/1_latestbest.mq5
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property strict
|
| 2 |
+
#include <Trade/Trade.mqh>
|
| 3 |
+
|
| 4 |
+
CTrade trade;
|
| 5 |
+
|
| 6 |
+
// =====================
|
| 7 |
+
// INPUTS
|
| 8 |
+
// =====================
|
| 9 |
+
input double RiskPercent = 1.0; // 1% risk per trade
|
| 10 |
+
input int TimerSec = 5; // timer interval in seconds
|
| 11 |
+
|
| 12 |
+
// =====================
|
| 13 |
+
// GLOBALS
|
| 14 |
+
// =====================
|
| 15 |
+
string TradeSymbol;
|
| 16 |
+
datetime lastEntryBarTime = 0; // track last original entry bar
|
| 17 |
+
datetime lastTrailBarTime = 0; // track last trailing bar
|
| 18 |
+
bool originalEntryDone = false; // flag for original entry per day
|
| 19 |
+
bool reverseEntryDone = false; // flag for reverse entry per day
|
| 20 |
+
long originalEntryType = -1; // POSITION_TYPE_BUY or POSITION_TYPE_SELL
|
| 21 |
+
double initialSL = 0.0; // store initial SL
|
| 22 |
+
|
| 23 |
+
// =====================
|
| 24 |
+
// INIT
|
| 25 |
+
// =====================
|
| 26 |
+
int OnInit()
|
| 27 |
+
{
|
| 28 |
+
TradeSymbol = _Symbol;
|
| 29 |
+
if(!SymbolSelect(TradeSymbol, true))
|
| 30 |
+
return INIT_FAILED;
|
| 31 |
+
|
| 32 |
+
EventSetTimer(TimerSec);
|
| 33 |
+
return INIT_SUCCEEDED;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// =====================
|
| 37 |
+
void OnDeinit(const int reason)
|
| 38 |
+
{
|
| 39 |
+
EventKillTimer();
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
// =====================
|
| 43 |
+
void OnTimer()
|
| 44 |
+
{
|
| 45 |
+
ResetFlags(); // reset daily flags if new day
|
| 46 |
+
HandleEntry();
|
| 47 |
+
HandleReverseEntry();
|
| 48 |
+
HandleTrailing();
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// ============================================================
|
| 52 |
+
// ORIGINAL ENTRY LOGIC
|
| 53 |
+
// ============================================================
|
| 54 |
+
void HandleEntry()
|
| 55 |
+
{
|
| 56 |
+
if(PositionSelect(TradeSymbol) || originalEntryDone)
|
| 57 |
+
return;
|
| 58 |
+
|
| 59 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 60 |
+
if(barTime == 0 || barTime == lastEntryBarTime)
|
| 61 |
+
return;
|
| 62 |
+
|
| 63 |
+
lastEntryBarTime = barTime;
|
| 64 |
+
|
| 65 |
+
MqlDateTime t;
|
| 66 |
+
TimeToStruct(barTime, t);
|
| 67 |
+
if(t.hour != 0) // only 0:00–3:00 H3 candle
|
| 68 |
+
return;
|
| 69 |
+
|
| 70 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 71 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 72 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 73 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 74 |
+
|
| 75 |
+
trade.SetDeviationInPoints(20);
|
| 76 |
+
trade.SetTypeFillingBySymbol(TradeSymbol);
|
| 77 |
+
|
| 78 |
+
// ---------------- BUY ----------------
|
| 79 |
+
if(close > open)
|
| 80 |
+
{
|
| 81 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 82 |
+
double sl = low;
|
| 83 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 84 |
+
if(vol > 0)
|
| 85 |
+
{
|
| 86 |
+
if(trade.Buy(vol, TradeSymbol, entry, sl, 0.0))
|
| 87 |
+
{
|
| 88 |
+
initialSL = sl;
|
| 89 |
+
originalEntryDone = true;
|
| 90 |
+
originalEntryType = POSITION_TYPE_BUY;
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// ---------------- SELL ----------------
|
| 96 |
+
if(close < open)
|
| 97 |
+
{
|
| 98 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 99 |
+
double sl = high;
|
| 100 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 101 |
+
if(vol > 0)
|
| 102 |
+
{
|
| 103 |
+
if(trade.Sell(vol, TradeSymbol, entry, sl, 0.0))
|
| 104 |
+
{
|
| 105 |
+
initialSL = sl;
|
| 106 |
+
originalEntryDone = true;
|
| 107 |
+
originalEntryType = POSITION_TYPE_SELL;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
// ============================================================
|
| 114 |
+
// REVERSE ENTRY LOGIC (TRIGGERED ON STOPLOSS HIT)
|
| 115 |
+
// ============================================================
|
| 116 |
+
void HandleReverseEntry()
|
| 117 |
+
{
|
| 118 |
+
if(reverseEntryDone || !originalEntryDone)
|
| 119 |
+
return;
|
| 120 |
+
|
| 121 |
+
if(!PositionSelect(TradeSymbol))
|
| 122 |
+
{
|
| 123 |
+
// Original trade was BUY
|
| 124 |
+
if(originalEntryType == POSITION_TYPE_BUY)
|
| 125 |
+
{
|
| 126 |
+
// Check if stoploss was hit in negative profit
|
| 127 |
+
double ask = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 128 |
+
if(initialSL > 0 && ask <= initialSL) // original BUY SL hit
|
| 129 |
+
{
|
| 130 |
+
// Reverse SELL
|
| 131 |
+
double prevHigh = iHigh(TradeSymbol, PERIOD_H3, 2); // previous H3 candle
|
| 132 |
+
double vol = CalculateRiskVolume(ask, prevHigh);
|
| 133 |
+
if(vol > 0)
|
| 134 |
+
{
|
| 135 |
+
if(trade.Sell(vol, TradeSymbol, ask, prevHigh, 0.0))
|
| 136 |
+
reverseEntryDone = true;
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
// Original trade was SELL
|
| 142 |
+
if(originalEntryType == POSITION_TYPE_SELL)
|
| 143 |
+
{
|
| 144 |
+
// Check if stoploss was hit in negative profit
|
| 145 |
+
double bid = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 146 |
+
if(initialSL > 0 && bid >= initialSL) // original SELL SL hit
|
| 147 |
+
{
|
| 148 |
+
// Reverse BUY
|
| 149 |
+
double prevLow = iLow(TradeSymbol, PERIOD_H3, 2); // previous H3 candle
|
| 150 |
+
double vol = CalculateRiskVolume(bid, prevLow);
|
| 151 |
+
if(vol > 0)
|
| 152 |
+
{
|
| 153 |
+
if(trade.Buy(vol, TradeSymbol, bid, prevLow, 0.0))
|
| 154 |
+
reverseEntryDone = true;
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
// ============================================================
|
| 162 |
+
// TRAILING LOGIC (STRICT CLOSED H3 CANDLES ONLY)
|
| 163 |
+
// ============================================================
|
| 164 |
+
void HandleTrailing()
|
| 165 |
+
{
|
| 166 |
+
if(!PositionSelect(TradeSymbol))
|
| 167 |
+
return;
|
| 168 |
+
|
| 169 |
+
// Use last closed H3 candle only (index 1)
|
| 170 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 171 |
+
if(barTime == 0 || barTime == lastTrailBarTime)
|
| 172 |
+
return;
|
| 173 |
+
|
| 174 |
+
lastTrailBarTime = barTime;
|
| 175 |
+
|
| 176 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 177 |
+
double currentSL = PositionGetDouble(POSITION_SL);
|
| 178 |
+
|
| 179 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 180 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 181 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 182 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 183 |
+
|
| 184 |
+
// ---------------- BUY ----------------
|
| 185 |
+
if(type == POSITION_TYPE_BUY)
|
| 186 |
+
{
|
| 187 |
+
if(close > open && low > currentSL)
|
| 188 |
+
trade.PositionModify(TradeSymbol, low, 0.0);
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
// ---------------- SELL ----------------
|
| 192 |
+
if(type == POSITION_TYPE_SELL)
|
| 193 |
+
{
|
| 194 |
+
if(close < open && high < currentSL)
|
| 195 |
+
trade.PositionModify(TradeSymbol, high, 0.0);
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
// ============================================================
|
| 200 |
+
// RISK-BASED LOT CALCULATION
|
| 201 |
+
// ============================================================
|
| 202 |
+
double CalculateRiskVolume(double entry, double stop)
|
| 203 |
+
{
|
| 204 |
+
double distance = MathAbs(entry - stop);
|
| 205 |
+
if(distance <= 0)
|
| 206 |
+
return 0;
|
| 207 |
+
|
| 208 |
+
// spread x 10 rule
|
| 209 |
+
int spread_points = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD);
|
| 210 |
+
double spread = spread_points * SymbolInfoDouble(TradeSymbol, SYMBOL_POINT);
|
| 211 |
+
if(distance < spread * 10)
|
| 212 |
+
return 0;
|
| 213 |
+
|
| 214 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 215 |
+
double riskAmt = balance * (RiskPercent / 100.0);
|
| 216 |
+
|
| 217 |
+
double tickSize = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_SIZE);
|
| 218 |
+
double tickValue = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_VALUE);
|
| 219 |
+
|
| 220 |
+
double costPerLot = (distance / tickSize) * tickValue;
|
| 221 |
+
if(costPerLot <= 0)
|
| 222 |
+
return 0;
|
| 223 |
+
|
| 224 |
+
double volume = riskAmt / costPerLot;
|
| 225 |
+
|
| 226 |
+
double minLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MIN);
|
| 227 |
+
double maxLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MAX);
|
| 228 |
+
double stepLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_STEP);
|
| 229 |
+
|
| 230 |
+
volume = MathFloor(volume / stepLot) * stepLot;
|
| 231 |
+
volume = MathMax(volume, minLot);
|
| 232 |
+
volume = MathMin(volume, maxLot);
|
| 233 |
+
|
| 234 |
+
return volume;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
// ============================================================
|
| 238 |
+
// DAILY RESET OF FLAGS
|
| 239 |
+
// ============================================================
|
| 240 |
+
void ResetFlags()
|
| 241 |
+
{
|
| 242 |
+
static datetime lastResetTime = 0;
|
| 243 |
+
datetime now = TimeCurrent();
|
| 244 |
+
MqlDateTime t;
|
| 245 |
+
TimeToStruct(now, t);
|
| 246 |
+
|
| 247 |
+
// Reset once per day at 0:00 H3 candle
|
| 248 |
+
if(t.hour == 0 && lastResetTime < now - 3600)
|
| 249 |
+
{
|
| 250 |
+
originalEntryDone = false;
|
| 251 |
+
reverseEntryDone = false;
|
| 252 |
+
initialSL = 0.0;
|
| 253 |
+
originalEntryType = -1;
|
| 254 |
+
lastResetTime = now;
|
| 255 |
+
}
|
| 256 |
+
}
|
MQL5 Folder/Revised 0-3/2_latestbest.mq5
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property strict
|
| 2 |
+
#include <Trade/Trade.mqh>
|
| 3 |
+
|
| 4 |
+
CTrade trade;
|
| 5 |
+
|
| 6 |
+
// =====================
|
| 7 |
+
// INPUTS
|
| 8 |
+
// =====================
|
| 9 |
+
input double RiskPercent = 1.0; // 1% risk per trade
|
| 10 |
+
input int TimerSec = 5; // timer interval in seconds
|
| 11 |
+
|
| 12 |
+
// =====================
|
| 13 |
+
// GLOBALS
|
| 14 |
+
// =====================
|
| 15 |
+
string TradeSymbol;
|
| 16 |
+
datetime lastEntryBarTime = 0; // track last original entry bar
|
| 17 |
+
datetime lastTrailBarTime = 0; // track last trailing bar
|
| 18 |
+
bool originalEntryDone = false; // flag for original entry per day
|
| 19 |
+
bool reverseEntryDone = false; // flag for reverse entry per day
|
| 20 |
+
long originalEntryType = -1; // POSITION_TYPE_BUY or POSITION_TYPE_SELL
|
| 21 |
+
double initialSL = 0.0; // store initial SL
|
| 22 |
+
|
| 23 |
+
// =====================
|
| 24 |
+
// INIT
|
| 25 |
+
// =====================
|
| 26 |
+
int OnInit()
|
| 27 |
+
{
|
| 28 |
+
TradeSymbol = _Symbol;
|
| 29 |
+
if(!SymbolSelect(TradeSymbol, true))
|
| 30 |
+
return INIT_FAILED;
|
| 31 |
+
|
| 32 |
+
EventSetTimer(TimerSec);
|
| 33 |
+
return INIT_SUCCEEDED;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// =====================
|
| 37 |
+
void OnDeinit(const int reason)
|
| 38 |
+
{
|
| 39 |
+
EventKillTimer();
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
// =====================
|
| 43 |
+
void OnTimer()
|
| 44 |
+
{
|
| 45 |
+
ResetFlags(); // reset daily flags if new day
|
| 46 |
+
HandleEntry();
|
| 47 |
+
HandleReverseEntry();
|
| 48 |
+
HandleTrailing();
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// ============================================================
|
| 52 |
+
// ORIGINAL ENTRY LOGIC
|
| 53 |
+
// ============================================================
|
| 54 |
+
void HandleEntry()
|
| 55 |
+
{
|
| 56 |
+
if(PositionSelect(TradeSymbol) || originalEntryDone)
|
| 57 |
+
return;
|
| 58 |
+
|
| 59 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 60 |
+
if(barTime == 0 || barTime == lastEntryBarTime)
|
| 61 |
+
return;
|
| 62 |
+
|
| 63 |
+
lastEntryBarTime = barTime;
|
| 64 |
+
|
| 65 |
+
MqlDateTime t;
|
| 66 |
+
TimeToStruct(barTime, t);
|
| 67 |
+
if(t.hour != 0) // only 0:00–3:00 H3 candle
|
| 68 |
+
return;
|
| 69 |
+
|
| 70 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 71 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 72 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 73 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 74 |
+
|
| 75 |
+
trade.SetDeviationInPoints(20);
|
| 76 |
+
trade.SetTypeFillingBySymbol(TradeSymbol);
|
| 77 |
+
|
| 78 |
+
// ---------------- BUY ----------------
|
| 79 |
+
if(close > open)
|
| 80 |
+
{
|
| 81 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 82 |
+
double sl = low;
|
| 83 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 84 |
+
if(vol > 0)
|
| 85 |
+
{
|
| 86 |
+
if(trade.Buy(vol, TradeSymbol, entry, sl, 0.0))
|
| 87 |
+
{
|
| 88 |
+
initialSL = sl;
|
| 89 |
+
originalEntryDone = true;
|
| 90 |
+
originalEntryType = POSITION_TYPE_BUY;
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// ---------------- SELL ----------------
|
| 96 |
+
if(close < open)
|
| 97 |
+
{
|
| 98 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 99 |
+
double sl = high;
|
| 100 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 101 |
+
if(vol > 0)
|
| 102 |
+
{
|
| 103 |
+
if(trade.Sell(vol, TradeSymbol, entry, sl, 0.0))
|
| 104 |
+
{
|
| 105 |
+
initialSL = sl;
|
| 106 |
+
originalEntryDone = true;
|
| 107 |
+
originalEntryType = POSITION_TYPE_SELL;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
// ============================================================
|
| 114 |
+
// REVERSE ENTRY LOGIC (TRIGGERED ON STOPLOSS HIT, SL BASED ON PREV CANDLE)
|
| 115 |
+
// ============================================================
|
| 116 |
+
void HandleReverseEntry()
|
| 117 |
+
{
|
| 118 |
+
if(reverseEntryDone || !originalEntryDone)
|
| 119 |
+
return;
|
| 120 |
+
|
| 121 |
+
if(!PositionSelect(TradeSymbol))
|
| 122 |
+
{
|
| 123 |
+
// Current H3 candle (position = 0)
|
| 124 |
+
double open0 = iOpen(TradeSymbol, PERIOD_H3, 0);
|
| 125 |
+
double close0 = iClose(TradeSymbol, PERIOD_H3, 0);
|
| 126 |
+
double low0 = iLow(TradeSymbol, PERIOD_H3, 0);
|
| 127 |
+
double high0 = iHigh(TradeSymbol, PERIOD_H3, 0);
|
| 128 |
+
|
| 129 |
+
// Previous candle (position = -1)
|
| 130 |
+
double lowPrev = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 131 |
+
double highPrev = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 132 |
+
|
| 133 |
+
// Original trade was BUY → Reverse SELL
|
| 134 |
+
if(originalEntryType == POSITION_TYPE_BUY)
|
| 135 |
+
{
|
| 136 |
+
double bid = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 137 |
+
if(initialSL > 0 && bid <= initialSL) // original BUY SL hit
|
| 138 |
+
{
|
| 139 |
+
double sl = highPrev; // SL of reverse SELL = high of previous candle
|
| 140 |
+
double vol = CalculateRiskVolume(bid, sl);
|
| 141 |
+
if(vol > 0)
|
| 142 |
+
{
|
| 143 |
+
if(trade.Sell(vol, TradeSymbol, bid, sl, 0.0))
|
| 144 |
+
reverseEntryDone = true;
|
| 145 |
+
}
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
// Original trade was SELL → Reverse BUY
|
| 150 |
+
if(originalEntryType == POSITION_TYPE_SELL)
|
| 151 |
+
{
|
| 152 |
+
double ask = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 153 |
+
if(initialSL > 0 && ask >= initialSL) // original SELL SL hit
|
| 154 |
+
{
|
| 155 |
+
double sl = lowPrev; // SL of reverse BUY = low of previous candle
|
| 156 |
+
double vol = CalculateRiskVolume(ask, sl);
|
| 157 |
+
if(vol > 0)
|
| 158 |
+
{
|
| 159 |
+
if(trade.Buy(vol, TradeSymbol, ask, sl, 0.0))
|
| 160 |
+
reverseEntryDone = true;
|
| 161 |
+
}
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
// ============================================================
|
| 168 |
+
// TRAILING LOGIC (STRICT CLOSED H3 CANDLES ONLY)
|
| 169 |
+
// ============================================================
|
| 170 |
+
void HandleTrailing()
|
| 171 |
+
{
|
| 172 |
+
if(!PositionSelect(TradeSymbol))
|
| 173 |
+
return;
|
| 174 |
+
|
| 175 |
+
// Use last closed H3 candle only (index 1)
|
| 176 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 177 |
+
if(barTime == 0 || barTime == lastTrailBarTime)
|
| 178 |
+
return;
|
| 179 |
+
|
| 180 |
+
lastTrailBarTime = barTime;
|
| 181 |
+
|
| 182 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 183 |
+
double currentSL = PositionGetDouble(POSITION_SL);
|
| 184 |
+
|
| 185 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 186 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 187 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 188 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 189 |
+
|
| 190 |
+
// ---------------- BUY ----------------
|
| 191 |
+
if(type == POSITION_TYPE_BUY)
|
| 192 |
+
{
|
| 193 |
+
if(close > open && low > currentSL)
|
| 194 |
+
trade.PositionModify(TradeSymbol, low, 0.0);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
// ---------------- SELL ----------------
|
| 198 |
+
if(type == POSITION_TYPE_SELL)
|
| 199 |
+
{
|
| 200 |
+
if(close < open && high < currentSL)
|
| 201 |
+
trade.PositionModify(TradeSymbol, high, 0.0);
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// ============================================================
|
| 206 |
+
// RISK-BASED LOT CALCULATION
|
| 207 |
+
// ============================================================
|
| 208 |
+
double CalculateRiskVolume(double entry, double stop)
|
| 209 |
+
{
|
| 210 |
+
double distance = MathAbs(entry - stop);
|
| 211 |
+
if(distance <= 0)
|
| 212 |
+
return 0;
|
| 213 |
+
|
| 214 |
+
// spread x 10 rule
|
| 215 |
+
int spread_points = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD);
|
| 216 |
+
double spread = spread_points * SymbolInfoDouble(TradeSymbol, SYMBOL_POINT);
|
| 217 |
+
if(distance < spread * 10)
|
| 218 |
+
return 0;
|
| 219 |
+
|
| 220 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 221 |
+
double riskAmt = balance * (RiskPercent / 100.0);
|
| 222 |
+
|
| 223 |
+
double tickSize = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_SIZE);
|
| 224 |
+
double tickValue = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_VALUE);
|
| 225 |
+
|
| 226 |
+
double costPerLot = (distance / tickSize) * tickValue;
|
| 227 |
+
if(costPerLot <= 0)
|
| 228 |
+
return 0;
|
| 229 |
+
|
| 230 |
+
double volume = riskAmt / costPerLot;
|
| 231 |
+
|
| 232 |
+
double minLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MIN);
|
| 233 |
+
double maxLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MAX);
|
| 234 |
+
double stepLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_STEP);
|
| 235 |
+
|
| 236 |
+
volume = MathFloor(volume / stepLot) * stepLot;
|
| 237 |
+
volume = MathMax(volume, minLot);
|
| 238 |
+
volume = MathMin(volume, maxLot);
|
| 239 |
+
|
| 240 |
+
return volume;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
// ============================================================
|
| 244 |
+
// DAILY RESET OF FLAGS
|
| 245 |
+
// ============================================================
|
| 246 |
+
void ResetFlags()
|
| 247 |
+
{
|
| 248 |
+
static datetime lastResetTime = 0;
|
| 249 |
+
datetime now = TimeCurrent();
|
| 250 |
+
MqlDateTime t;
|
| 251 |
+
TimeToStruct(now, t);
|
| 252 |
+
|
| 253 |
+
// Reset once per day at 0:00 H3 candle
|
| 254 |
+
if(t.hour == 0 && lastResetTime < now - 3600)
|
| 255 |
+
{
|
| 256 |
+
originalEntryDone = false;
|
| 257 |
+
reverseEntryDone = false;
|
| 258 |
+
initialSL = 0.0;
|
| 259 |
+
originalEntryType = -1;
|
| 260 |
+
lastResetTime = now;
|
| 261 |
+
}
|
| 262 |
+
}
|
MQL5 Folder/Revised 0-3/3_latestbest.mw5
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property strict
|
| 2 |
+
#include <Trade/Trade.mqh>
|
| 3 |
+
|
| 4 |
+
CTrade trade;
|
| 5 |
+
|
| 6 |
+
// =====================
|
| 7 |
+
// INPUTS
|
| 8 |
+
// =====================
|
| 9 |
+
input double RiskPercent = 1.0; // 1% risk per trade
|
| 10 |
+
input int TimerSec = 5; // timer interval in seconds
|
| 11 |
+
|
| 12 |
+
// =====================
|
| 13 |
+
// GLOBALS
|
| 14 |
+
// =====================
|
| 15 |
+
string TradeSymbol;
|
| 16 |
+
datetime lastEntryBarTime = 0; // track last original entry bar
|
| 17 |
+
datetime lastTrailBarTime = 0; // track last trailing bar
|
| 18 |
+
bool originalEntryDone = false; // flag for original entry per day
|
| 19 |
+
bool originalEntryLoss = false; // true if original entry closed at loss
|
| 20 |
+
bool reverseEntryDone = false; // flag for reverse entry per day
|
| 21 |
+
long originalEntryType = -1; // POSITION_TYPE_BUY or POSITION_TYPE_SELL
|
| 22 |
+
double initialSL = 0.0; // store initial SL
|
| 23 |
+
ulong originalTicket = 0; // ticket of original entry
|
| 24 |
+
|
| 25 |
+
// =====================
|
| 26 |
+
// INIT
|
| 27 |
+
// =====================
|
| 28 |
+
int OnInit()
|
| 29 |
+
{
|
| 30 |
+
TradeSymbol = _Symbol;
|
| 31 |
+
if(!SymbolSelect(TradeSymbol, true))
|
| 32 |
+
return INIT_FAILED;
|
| 33 |
+
|
| 34 |
+
EventSetTimer(TimerSec);
|
| 35 |
+
return INIT_SUCCEEDED;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// =====================
|
| 39 |
+
void OnDeinit(const int reason)
|
| 40 |
+
{
|
| 41 |
+
EventKillTimer();
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// =====================
|
| 45 |
+
void OnTimer()
|
| 46 |
+
{
|
| 47 |
+
ResetFlags(); // reset daily flags if new day
|
| 48 |
+
HandleEntry();
|
| 49 |
+
HandleReverseEntry();
|
| 50 |
+
HandleTrailing();
|
| 51 |
+
CheckOriginalTradeProfit();
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// ============================================================
|
| 55 |
+
// ORIGINAL ENTRY LOGIC
|
| 56 |
+
// ============================================================
|
| 57 |
+
void HandleEntry()
|
| 58 |
+
{
|
| 59 |
+
if(PositionSelect(TradeSymbol) || originalEntryDone)
|
| 60 |
+
return;
|
| 61 |
+
|
| 62 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 63 |
+
if(barTime == 0 || barTime == lastEntryBarTime)
|
| 64 |
+
return;
|
| 65 |
+
|
| 66 |
+
lastEntryBarTime = barTime;
|
| 67 |
+
|
| 68 |
+
MqlDateTime t;
|
| 69 |
+
TimeToStruct(barTime, t);
|
| 70 |
+
if(t.hour != 0) // only 0:00–3:00 H3 candle
|
| 71 |
+
return;
|
| 72 |
+
|
| 73 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 74 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 75 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 76 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 77 |
+
|
| 78 |
+
trade.SetDeviationInPoints(20);
|
| 79 |
+
trade.SetTypeFillingBySymbol(TradeSymbol);
|
| 80 |
+
|
| 81 |
+
// ---------------- BUY ----------------
|
| 82 |
+
if(close > open)
|
| 83 |
+
{
|
| 84 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 85 |
+
double sl = low;
|
| 86 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 87 |
+
if(vol > 0)
|
| 88 |
+
{
|
| 89 |
+
if(trade.Buy(vol, TradeSymbol, entry, sl, 0.0))
|
| 90 |
+
{
|
| 91 |
+
initialSL = sl;
|
| 92 |
+
originalEntryDone = true;
|
| 93 |
+
originalEntryType = POSITION_TYPE_BUY;
|
| 94 |
+
originalTicket = trade.ResultOrder(); // store ticket
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// ---------------- SELL ----------------
|
| 100 |
+
if(close < open)
|
| 101 |
+
{
|
| 102 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 103 |
+
double sl = high;
|
| 104 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 105 |
+
if(vol > 0)
|
| 106 |
+
{
|
| 107 |
+
if(trade.Sell(vol, TradeSymbol, entry, sl, 0.0))
|
| 108 |
+
{
|
| 109 |
+
initialSL = sl;
|
| 110 |
+
originalEntryDone = true;
|
| 111 |
+
originalEntryType = POSITION_TYPE_SELL;
|
| 112 |
+
originalTicket = trade.ResultOrder(); // store ticket
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
// ============================================================
|
| 119 |
+
// CHECK IF ORIGINAL TRADE CLOSED IN LOSS OR PROFIT
|
| 120 |
+
// ============================================================
|
| 121 |
+
void CheckOriginalTradeProfit()
|
| 122 |
+
{
|
| 123 |
+
if(!originalEntryDone || originalTicket == 0)
|
| 124 |
+
return;
|
| 125 |
+
|
| 126 |
+
// Check if original trade exists
|
| 127 |
+
if(!PositionSelect(TradeSymbol))
|
| 128 |
+
return;
|
| 129 |
+
|
| 130 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 131 |
+
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
| 132 |
+
double closePrice = PositionGetDouble(POSITION_PRICE_CURRENT);
|
| 133 |
+
|
| 134 |
+
double profit = 0.0;
|
| 135 |
+
if(type == POSITION_TYPE_BUY)
|
| 136 |
+
profit = closePrice - openPrice;
|
| 137 |
+
else if(type == POSITION_TYPE_SELL)
|
| 138 |
+
profit = openPrice - closePrice;
|
| 139 |
+
|
| 140 |
+
if(profit > 0)
|
| 141 |
+
originalEntryLoss = false; // profitable → reverse-entry disabled
|
| 142 |
+
else
|
| 143 |
+
originalEntryLoss = true; // loss → reverse-entry possible
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
// ============================================================
|
| 147 |
+
// REVERSE ENTRY LOGIC (TRIGGERED ON LOSS, SL BASED ON PREV CANDLE)
|
| 148 |
+
// ============================================================
|
| 149 |
+
void HandleReverseEntry()
|
| 150 |
+
{
|
| 151 |
+
if(reverseEntryDone || !originalEntryDone || !originalEntryLoss)
|
| 152 |
+
return;
|
| 153 |
+
|
| 154 |
+
if(!PositionSelect(TradeSymbol))
|
| 155 |
+
{
|
| 156 |
+
// Current H3 candle (position = 0)
|
| 157 |
+
double open0 = iOpen(TradeSymbol, PERIOD_H3, 0);
|
| 158 |
+
double close0 = iClose(TradeSymbol, PERIOD_H3, 0);
|
| 159 |
+
double low0 = iLow(TradeSymbol, PERIOD_H3, 0);
|
| 160 |
+
double high0 = iHigh(TradeSymbol, PERIOD_H3, 0);
|
| 161 |
+
|
| 162 |
+
// Previous candle (position = -1)
|
| 163 |
+
double lowPrev = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 164 |
+
double highPrev = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 165 |
+
|
| 166 |
+
// Original trade was BUY → Reverse SELL
|
| 167 |
+
if(originalEntryType == POSITION_TYPE_BUY)
|
| 168 |
+
{
|
| 169 |
+
double bid = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 170 |
+
if(initialSL > 0 && bid <= initialSL) // original BUY SL hit
|
| 171 |
+
{
|
| 172 |
+
double sl = highPrev; // SL of reverse SELL = high of previous candle
|
| 173 |
+
double vol = CalculateRiskVolume(bid, sl);
|
| 174 |
+
if(vol > 0)
|
| 175 |
+
{
|
| 176 |
+
if(trade.Sell(vol, TradeSymbol, bid, sl, 0.0))
|
| 177 |
+
reverseEntryDone = true;
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
// Original trade was SELL → Reverse BUY
|
| 183 |
+
if(originalEntryType == POSITION_TYPE_SELL)
|
| 184 |
+
{
|
| 185 |
+
double ask = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 186 |
+
if(initialSL > 0 && ask >= initialSL) // original SELL SL hit
|
| 187 |
+
{
|
| 188 |
+
double sl = lowPrev; // SL of reverse BUY = low of previous candle
|
| 189 |
+
double vol = CalculateRiskVolume(ask, sl);
|
| 190 |
+
if(vol > 0)
|
| 191 |
+
{
|
| 192 |
+
if(trade.Buy(vol, TradeSymbol, ask, sl, 0.0))
|
| 193 |
+
reverseEntryDone = true;
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
// ============================================================
|
| 201 |
+
// TRAILING LOGIC (STRICT CLOSED H3 CANDLES ONLY)
|
| 202 |
+
// ============================================================
|
| 203 |
+
void HandleTrailing()
|
| 204 |
+
{
|
| 205 |
+
if(!PositionSelect(TradeSymbol))
|
| 206 |
+
return;
|
| 207 |
+
|
| 208 |
+
// Use last closed H3 candle only (index 1)
|
| 209 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 210 |
+
if(barTime == 0 || barTime == lastTrailBarTime)
|
| 211 |
+
return;
|
| 212 |
+
|
| 213 |
+
lastTrailBarTime = barTime;
|
| 214 |
+
|
| 215 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 216 |
+
double currentSL = PositionGetDouble(POSITION_SL);
|
| 217 |
+
|
| 218 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 219 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 220 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 221 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 222 |
+
|
| 223 |
+
// ---------------- BUY ----------------
|
| 224 |
+
if(type == POSITION_TYPE_BUY)
|
| 225 |
+
{
|
| 226 |
+
if(close > open && low > currentSL)
|
| 227 |
+
trade.PositionModify(TradeSymbol, low, 0.0);
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
// ---------------- SELL ----------------
|
| 231 |
+
if(type == POSITION_TYPE_SELL)
|
| 232 |
+
{
|
| 233 |
+
if(close < open && high < currentSL)
|
| 234 |
+
trade.PositionModify(TradeSymbol, high, 0.0);
|
| 235 |
+
}
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
// ============================================================
|
| 239 |
+
// RISK-BASED LOT CALCULATION
|
| 240 |
+
// ============================================================
|
| 241 |
+
double CalculateRiskVolume(double entry, double stop)
|
| 242 |
+
{
|
| 243 |
+
double distance = MathAbs(entry - stop);
|
| 244 |
+
if(distance <= 0)
|
| 245 |
+
return 0;
|
| 246 |
+
|
| 247 |
+
// spread x 10 rule
|
| 248 |
+
int spread_points = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD);
|
| 249 |
+
double spread = spread_points * SymbolInfoDouble(TradeSymbol, SYMBOL_POINT);
|
| 250 |
+
if(distance < spread * 10)
|
| 251 |
+
return 0;
|
| 252 |
+
|
| 253 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 254 |
+
double riskAmt = balance * (RiskPercent / 100.0);
|
| 255 |
+
|
| 256 |
+
double tickSize = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_SIZE);
|
| 257 |
+
double tickValue = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_VALUE);
|
| 258 |
+
|
| 259 |
+
double costPerLot = (distance / tickSize) * tickValue;
|
| 260 |
+
if(costPerLot <= 0)
|
| 261 |
+
return 0;
|
| 262 |
+
|
| 263 |
+
double volume = riskAmt / costPerLot;
|
| 264 |
+
|
| 265 |
+
double minLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MIN);
|
| 266 |
+
double maxLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MAX);
|
| 267 |
+
double stepLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_STEP);
|
| 268 |
+
|
| 269 |
+
volume = MathFloor(volume / stepLot) * stepLot;
|
| 270 |
+
volume = MathMax(volume, minLot);
|
| 271 |
+
volume = MathMin(volume, maxLot);
|
| 272 |
+
|
| 273 |
+
return volume;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
// ============================================================
|
| 277 |
+
// DAILY RESET OF FLAGS
|
| 278 |
+
// ============================================================
|
| 279 |
+
void ResetFlags()
|
| 280 |
+
{
|
| 281 |
+
static datetime lastResetTime = 0;
|
| 282 |
+
datetime now = TimeCurrent();
|
| 283 |
+
MqlDateTime t;
|
| 284 |
+
TimeToStruct(now, t);
|
| 285 |
+
|
| 286 |
+
// Reset once per day at 0:00 H3 candle
|
| 287 |
+
if(t.hour == 0 && lastResetTime < now - 3600)
|
| 288 |
+
{
|
| 289 |
+
originalEntryDone = false;
|
| 290 |
+
originalEntryLoss = false;
|
| 291 |
+
reverseEntryDone = false;
|
| 292 |
+
initialSL = 0.0;
|
| 293 |
+
originalEntryType = -1;
|
| 294 |
+
originalTicket = 0;
|
| 295 |
+
lastResetTime = now;
|
| 296 |
+
}
|
| 297 |
+
}
|
MQL5 Folder/Revised 0-3/4_latestbest.mq5
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#property strict
|
| 2 |
+
#include <Trade/Trade.mqh>
|
| 3 |
+
|
| 4 |
+
CTrade trade;
|
| 5 |
+
|
| 6 |
+
// =====================
|
| 7 |
+
// INPUTS
|
| 8 |
+
// =====================
|
| 9 |
+
input double RiskPercent = 1.0; // 1% risk per trade
|
| 10 |
+
input int TimerSec = 5; // timer interval in seconds
|
| 11 |
+
|
| 12 |
+
// =====================
|
| 13 |
+
// GLOBALS
|
| 14 |
+
// =====================
|
| 15 |
+
string TradeSymbol;
|
| 16 |
+
datetime lastEntryBarTime = 0; // track last original entry bar
|
| 17 |
+
datetime lastTrailBarTime = 0; // track last trailing bar
|
| 18 |
+
bool originalEntryDone = false; // flag for original entry per day
|
| 19 |
+
bool originalEntryLoss = false; // true if original entry closed at loss
|
| 20 |
+
bool reverseEntryDone = false; // flag for reverse entry per day
|
| 21 |
+
long originalEntryType = -1; // POSITION_TYPE_BUY or POSITION_TYPE_SELL
|
| 22 |
+
double initialSL = 0.0; // store initial SL
|
| 23 |
+
ulong originalTicket = 0; // ticket of original entry
|
| 24 |
+
|
| 25 |
+
// =====================
|
| 26 |
+
// INIT
|
| 27 |
+
// =====================
|
| 28 |
+
int OnInit()
|
| 29 |
+
{
|
| 30 |
+
TradeSymbol = _Symbol;
|
| 31 |
+
if(!SymbolSelect(TradeSymbol, true))
|
| 32 |
+
return INIT_FAILED;
|
| 33 |
+
|
| 34 |
+
EventSetTimer(TimerSec);
|
| 35 |
+
return INIT_SUCCEEDED;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// =====================
|
| 39 |
+
void OnDeinit(const int reason)
|
| 40 |
+
{
|
| 41 |
+
EventKillTimer();
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// =====================
|
| 45 |
+
void OnTimer()
|
| 46 |
+
{
|
| 47 |
+
ResetFlags(); // reset daily flags if new day
|
| 48 |
+
HandleEntry();
|
| 49 |
+
HandleReverseEntry();
|
| 50 |
+
HandleTrailing();
|
| 51 |
+
CheckOriginalTradeProfit();
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// ============================================================
|
| 55 |
+
// ORIGINAL ENTRY LOGIC
|
| 56 |
+
// ============================================================
|
| 57 |
+
void HandleEntry()
|
| 58 |
+
{
|
| 59 |
+
if(PositionSelect(TradeSymbol) || originalEntryDone)
|
| 60 |
+
return;
|
| 61 |
+
|
| 62 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 63 |
+
if(barTime == 0 || barTime == lastEntryBarTime)
|
| 64 |
+
return;
|
| 65 |
+
|
| 66 |
+
lastEntryBarTime = barTime;
|
| 67 |
+
|
| 68 |
+
MqlDateTime t;
|
| 69 |
+
TimeToStruct(barTime, t);
|
| 70 |
+
if(t.hour != 0) // only 0:00–3:00 H3 candle
|
| 71 |
+
return;
|
| 72 |
+
|
| 73 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 74 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 75 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 76 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 77 |
+
|
| 78 |
+
trade.SetDeviationInPoints(20);
|
| 79 |
+
trade.SetTypeFillingBySymbol(TradeSymbol);
|
| 80 |
+
|
| 81 |
+
// ---------------- BUY ----------------
|
| 82 |
+
if(close > open)
|
| 83 |
+
{
|
| 84 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 85 |
+
double sl = low;
|
| 86 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 87 |
+
if(vol > 0)
|
| 88 |
+
{
|
| 89 |
+
if(trade.Buy(vol, TradeSymbol, entry, sl, 0.0))
|
| 90 |
+
{
|
| 91 |
+
initialSL = sl;
|
| 92 |
+
originalEntryDone = true;
|
| 93 |
+
originalEntryType = POSITION_TYPE_BUY;
|
| 94 |
+
originalTicket = trade.ResultOrder(); // store ticket
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// ---------------- SELL ----------------
|
| 100 |
+
if(close < open)
|
| 101 |
+
{
|
| 102 |
+
double entry = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 103 |
+
double sl = high;
|
| 104 |
+
double vol = CalculateRiskVolume(entry, sl);
|
| 105 |
+
if(vol > 0)
|
| 106 |
+
{
|
| 107 |
+
if(trade.Sell(vol, TradeSymbol, entry, sl, 0.0))
|
| 108 |
+
{
|
| 109 |
+
initialSL = sl;
|
| 110 |
+
originalEntryDone = true;
|
| 111 |
+
originalEntryType = POSITION_TYPE_SELL;
|
| 112 |
+
originalTicket = trade.ResultOrder(); // store ticket
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
// ============================================================
|
| 119 |
+
// CHECK IF ORIGINAL TRADE CLOSED IN LOSS OR PROFIT
|
| 120 |
+
// ============================================================
|
| 121 |
+
void CheckOriginalTradeProfit()
|
| 122 |
+
{
|
| 123 |
+
if(!originalEntryDone || originalTicket == 0)
|
| 124 |
+
return;
|
| 125 |
+
|
| 126 |
+
// Check if original trade exists
|
| 127 |
+
if(!PositionSelect(TradeSymbol))
|
| 128 |
+
return;
|
| 129 |
+
|
| 130 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 131 |
+
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
| 132 |
+
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
|
| 133 |
+
|
| 134 |
+
double profit = 0.0;
|
| 135 |
+
if(type == POSITION_TYPE_BUY)
|
| 136 |
+
profit = currentPrice - openPrice;
|
| 137 |
+
else if(type == POSITION_TYPE_SELL)
|
| 138 |
+
profit = openPrice - currentPrice;
|
| 139 |
+
|
| 140 |
+
if(profit > 0)
|
| 141 |
+
originalEntryLoss = false; // profitable → reverse-entry disabled
|
| 142 |
+
else
|
| 143 |
+
originalEntryLoss = true; // loss → reverse-entry possible
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
// ============================================================
|
| 147 |
+
// REVERSE ENTRY LOGIC (IMMEDIATE ON LOSS, SL FROM PREVIOUS CANDLE)
|
| 148 |
+
// ============================================================
|
| 149 |
+
void HandleReverseEntry()
|
| 150 |
+
{
|
| 151 |
+
if(reverseEntryDone || !originalEntryDone || !originalEntryLoss)
|
| 152 |
+
return;
|
| 153 |
+
|
| 154 |
+
if(!PositionSelect(TradeSymbol))
|
| 155 |
+
{
|
| 156 |
+
// Current H3 candle (position = 0)
|
| 157 |
+
double open0 = iOpen(TradeSymbol, PERIOD_H3, 0);
|
| 158 |
+
double close0 = iClose(TradeSymbol, PERIOD_H3, 0);
|
| 159 |
+
double low0 = iLow(TradeSymbol, PERIOD_H3, 0);
|
| 160 |
+
double high0 = iHigh(TradeSymbol, PERIOD_H3, 0);
|
| 161 |
+
|
| 162 |
+
// Previous candle (position = -1)
|
| 163 |
+
double lowPrev = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 164 |
+
double highPrev = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 165 |
+
|
| 166 |
+
// Original trade was BUY → Reverse SELL
|
| 167 |
+
if(originalEntryType == POSITION_TYPE_BUY)
|
| 168 |
+
{
|
| 169 |
+
double bid = SymbolInfoDouble(TradeSymbol, SYMBOL_BID);
|
| 170 |
+
if(initialSL > 0 && bid <= initialSL) // original BUY SL hit in negative profit
|
| 171 |
+
{
|
| 172 |
+
double sl = highPrev; // SL of reverse SELL = high of previous candle
|
| 173 |
+
double vol = CalculateRiskVolume(bid, sl);
|
| 174 |
+
if(vol > 0)
|
| 175 |
+
{
|
| 176 |
+
if(trade.Sell(vol, TradeSymbol, bid, sl, 0.0))
|
| 177 |
+
reverseEntryDone = true;
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
// Original trade was SELL → Reverse BUY
|
| 183 |
+
if(originalEntryType == POSITION_TYPE_SELL)
|
| 184 |
+
{
|
| 185 |
+
double ask = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK);
|
| 186 |
+
if(initialSL > 0 && ask >= initialSL) // original SELL SL hit in negative profit
|
| 187 |
+
{
|
| 188 |
+
double sl = lowPrev; // SL of reverse BUY = low of previous candle
|
| 189 |
+
double vol = CalculateRiskVolume(ask, sl);
|
| 190 |
+
if(vol > 0)
|
| 191 |
+
{
|
| 192 |
+
if(trade.Buy(vol, TradeSymbol, ask, sl, 0.0))
|
| 193 |
+
reverseEntryDone = true;
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
// ============================================================
|
| 201 |
+
// TRAILING LOGIC (STRICT CLOSED H3 CANDLES ONLY)
|
| 202 |
+
// ============================================================
|
| 203 |
+
void HandleTrailing()
|
| 204 |
+
{
|
| 205 |
+
if(!PositionSelect(TradeSymbol))
|
| 206 |
+
return;
|
| 207 |
+
|
| 208 |
+
datetime barTime = iTime(TradeSymbol, PERIOD_H3, 1);
|
| 209 |
+
if(barTime == 0 || barTime == lastTrailBarTime)
|
| 210 |
+
return;
|
| 211 |
+
|
| 212 |
+
lastTrailBarTime = barTime;
|
| 213 |
+
|
| 214 |
+
long type = PositionGetInteger(POSITION_TYPE);
|
| 215 |
+
double currentSL = PositionGetDouble(POSITION_SL);
|
| 216 |
+
|
| 217 |
+
double open = iOpen(TradeSymbol, PERIOD_H3, 1);
|
| 218 |
+
double close = iClose(TradeSymbol, PERIOD_H3, 1);
|
| 219 |
+
double low = iLow(TradeSymbol, PERIOD_H3, 1);
|
| 220 |
+
double high = iHigh(TradeSymbol, PERIOD_H3, 1);
|
| 221 |
+
|
| 222 |
+
// ---------------- BUY ----------------
|
| 223 |
+
if(type == POSITION_TYPE_BUY)
|
| 224 |
+
{
|
| 225 |
+
if(close > open && low > currentSL)
|
| 226 |
+
trade.PositionModify(TradeSymbol, low, 0.0);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
// ---------------- SELL ----------------
|
| 230 |
+
if(type == POSITION_TYPE_SELL)
|
| 231 |
+
{
|
| 232 |
+
if(close < open && high < currentSL)
|
| 233 |
+
trade.PositionModify(TradeSymbol, high, 0.0);
|
| 234 |
+
}
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
// ============================================================
|
| 238 |
+
// RISK-BASED LOT CALCULATION
|
| 239 |
+
// ============================================================
|
| 240 |
+
double CalculateRiskVolume(double entry, double stop)
|
| 241 |
+
{
|
| 242 |
+
double distance = MathAbs(entry - stop);
|
| 243 |
+
if(distance <= 0)
|
| 244 |
+
return 0;
|
| 245 |
+
|
| 246 |
+
int spread_points = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_SPREAD);
|
| 247 |
+
double spread = spread_points * SymbolInfoDouble(TradeSymbol, SYMBOL_POINT);
|
| 248 |
+
if(distance < spread * 10)
|
| 249 |
+
return 0;
|
| 250 |
+
|
| 251 |
+
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
| 252 |
+
double riskAmt = balance * (RiskPercent / 100.0);
|
| 253 |
+
|
| 254 |
+
double tickSize = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_SIZE);
|
| 255 |
+
double tickValue = SymbolInfoDouble(TradeSymbol, SYMBOL_TRADE_TICK_VALUE);
|
| 256 |
+
|
| 257 |
+
double costPerLot = (distance / tickSize) * tickValue;
|
| 258 |
+
if(costPerLot <= 0)
|
| 259 |
+
return 0;
|
| 260 |
+
|
| 261 |
+
double volume = riskAmt / costPerLot;
|
| 262 |
+
|
| 263 |
+
double minLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MIN);
|
| 264 |
+
double maxLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_MAX);
|
| 265 |
+
double stepLot = SymbolInfoDouble(TradeSymbol, SYMBOL_VOLUME_STEP);
|
| 266 |
+
|
| 267 |
+
volume = MathFloor(volume / stepLot) * stepLot;
|
| 268 |
+
volume = MathMax(volume, minLot);
|
| 269 |
+
volume = MathMin(volume, maxLot);
|
| 270 |
+
|
| 271 |
+
return volume;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
// ============================================================
|
| 275 |
+
// DAILY RESET OF FLAGS
|
| 276 |
+
// ============================================================
|
| 277 |
+
void ResetFlags()
|
| 278 |
+
{
|
| 279 |
+
static datetime lastResetTime = 0;
|
| 280 |
+
datetime now = TimeCurrent();
|
| 281 |
+
MqlDateTime t;
|
| 282 |
+
TimeToStruct(now, t);
|
| 283 |
+
|
| 284 |
+
if(t.hour == 0 && lastResetTime < now - 3600)
|
| 285 |
+
{
|
| 286 |
+
originalEntryDone = false;
|
| 287 |
+
originalEntryLoss = false;
|
| 288 |
+
reverseEntryDone = false;
|
| 289 |
+
initialSL = 0.0;
|
| 290 |
+
originalEntryType = -1;
|
| 291 |
+
originalTicket = 0;
|
| 292 |
+
lastResetTime = now;
|
| 293 |
+
}
|
| 294 |
+
}
|
MQL5 Folder/Revised 0-3/revised from very begining.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|