├── README.md ├── LICENSE └── TradeInfo.mq4 /README.md: -------------------------------------------------------------------------------- 1 | # Trade Info 2 | > Trade Information Indicator for MetaTrader 4 3 | 4 | IceFX’s TradeInfo is a utility indicator which displays the most important information of the current account and position. 5 | 6 | [![](http://www.icefx.eu/wp-content/uploads/tradeinfo_main-1024x661.png)](https://github.com/icefx/tradeinfo) 7 | 8 | ## Displayed information: 9 | 10 | * Information about the current account (Balance, Equity, Free Margin) 11 | * Current spread, current drawdown (DD), planned profit, expected losses, etc. 12 | * Number of open position(s), volume (LOT), profit 13 | * Today’s and yesterday’s range 14 | * Daily maximum drawdown info 15 | * Remaining time to the next candle 16 | * Last day profit information (with integrated IceFX ProfitInfo indicator) 17 | * Risk-based LOT of information for open new position(s) 18 | * Show daily and monthly average profit 19 | * MagicNumber filter 20 | * Comment filter 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ice FX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /TradeInfo.mq4: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| TradeInfo.mq4 | 3 | //| Copyright © 2016, Ice FX | 4 | //| http://www.icefx.eu | 5 | //+------------------------------------------------------------------+ 6 | #property copyright "Copyright © 2016, Ice FX " 7 | #property link "http://www.icefx.eu" 8 | #property version "1.98" 9 | #property strict 10 | 11 | #property indicator_separate_window 12 | #property indicator_buffers 0 13 | 14 | input bool ShowProfitInfo = TRUE; 15 | input bool ShowTodayRanges = TRUE; 16 | input bool ShowRiskInfo = FALSE; 17 | input bool ShowAccountOrderInfo = TRUE; 18 | input int RiskStopLoss = 0; 19 | input string RiskLevels = "1,5,10,20,40,50,60,80,100"; 20 | 21 | input bool OnlyAttachedSymbol = FALSE; 22 | input int MagicNumber = -1; 23 | input string CommentFilter = ""; 24 | input string StartDateFilter = ""; 25 | input int FontSize = 8; 26 | input bool WhiteMode = False; 27 | 28 | int windowIndex = 0; 29 | string preCurrSign = ""; 30 | string postCurrSign = ""; 31 | double pip_multiplier = 1.0; 32 | int daySeconds = 86400; 33 | 34 | double MaxDD = 0, 35 | MaxDDp = 0, 36 | CurrentDD = 0, 37 | CurrentDDp = 0; 38 | 39 | datetime maxDDDay; 40 | datetime startDateFilter = 0; 41 | datetime LastDrawProfitInfo = 0; 42 | 43 | string IndiName = "TradeInfo v1.9.8"; 44 | 45 | /******************* Version history ******************************** 46 | 47 | v1.9.8 - 2016.03.13 48 | -------------------- 49 | - fixed 2-digits XAU 50 | 51 | v1.9.7 - 2016.03.07 52 | -------------------- 53 | - support 2-digits CFDs 54 | 55 | v1.9.6 - 2015.12.30 56 | -------------------- 57 | - show lots in profit info 58 | 59 | v1.9.5 - 2015.05.28 60 | -------------------- 61 | - Number round problem fixed 62 | - Customizable risk levels. The value is a comma-separated string without percent sign. E.G.: 1,2,5,10,15 63 | 64 | v1.9.4 - 2014.08.27 65 | -------------------- 66 | - White background mode 67 | 68 | v1.9.2 - 2013.11.13 69 | -------------------- 70 | - Some percentage bug fixed 71 | 72 | v1.9.1 - 2013.11.04 73 | -------------------- 74 | - Some bug fixed 75 | 76 | v1.9.0 - 2013.10.17 77 | -------------------- 78 | - Added Estimated profit and max losses in pips 79 | - StartDateFilter: beállítható a profitszámítás kezdõ idõpontja 80 | - ShowRiskInfo default értéke false 81 | - Show daily and monthly average gain 82 | - ProfitInfo refresh only every 10 seconds 83 | 84 | 85 | v1.8.4 - 2013.08.15 86 | -------------------- 87 | - Added Daily Max DrawDown info 88 | 89 | 90 | v1.8.3 - 2013.07.11 91 | -------------------- 92 | - Added Leverage and Swap info 93 | 94 | 95 | v1.8.2 - 2013.07.11 96 | -------------------- 97 | - Fixed some bug in pip calculation logic 98 | 99 | 100 | v1.8.1 - 2013.07.09 101 | -------------------- 102 | - Fixed some bug in pip calculation logic 103 | 104 | 105 | v1.8.0 - 2013.06.27 106 | -------------------- 107 | - Added this week, last week, this month, last month range 108 | 109 | ***********************************************************************/ 110 | 111 | //+------------------------------------------------------------------+ 112 | int init() { 113 | //+------------------------------------------------------------------+ 114 | IndicatorShortName(IndiName); 115 | //DeleteAllObject(); 116 | 117 | SetPipMultiplier(Symbol()); 118 | 119 | setCurrency(); 120 | 121 | // Load today max DD from global 122 | maxDDDay = getGlobalVar("TRADEINFO_DD_DAY", 0); 123 | if (maxDDDay >= iTime(Symbol(), PERIOD_D1, 0)) 124 | { 125 | MaxDD = getGlobalVar("TRADEINFO_MAXDD", 0); 126 | MaxDDp = getGlobalVar("TRADEINFO_MAXDDP", 0); 127 | } else { 128 | 129 | maxDDDay = iTime(Symbol(), PERIOD_D1, 0); 130 | MaxDD = 0; 131 | MaxDDp = 0; 132 | } 133 | 134 | if (StartDateFilter != "") 135 | startDateFilter = StrToTime(StartDateFilter); 136 | 137 | 138 | return(0); 139 | } 140 | 141 | //+------------------------------------------------------------------+ 142 | int start() { 143 | //+------------------------------------------------------------------+ 144 | DoWork(); 145 | 146 | return(0); 147 | } 148 | 149 | //+------------------------------------------------------------------+ 150 | void DoWork() { 151 | //+------------------------------------------------------------------+ 152 | windowIndex = WindowFind(IndiName); 153 | 154 | CalculateDailyDrawDown(); 155 | 156 | if (ShowAccountOrderInfo) DrawAccountInfo(); 157 | if (ShowAccountOrderInfo) DrawCurrentTrades(); 158 | if (ShowTodayRanges) DrawTodayRange(); 159 | if (ShowProfitInfo) DrawProfitHistory(); 160 | if (ShowRiskInfo) DrawRiskInfo(); 161 | DrawCopyright(); 162 | } 163 | 164 | //+------------------------------------------------------------------+ 165 | int deinit() { 166 | //+------------------------------------------------------------------+ 167 | DeleteAllObject(); 168 | 169 | return(0); 170 | } 171 | 172 | //+------------------------------------------------------------------+ 173 | void CalculateDailyDrawDown() { 174 | //+------------------------------------------------------------------+ 175 | double balance = AccountBalance(); 176 | 177 | if (balance != 0) 178 | { 179 | CurrentDD = 0.0 - ( AccountMargin() + (AccountBalance() - AccountEquity())); 180 | CurrentDDp = MathDiv(CurrentDD, balance) * 100.0; 181 | 182 | if (CurrentDD < MaxDD || iTime(Symbol(), PERIOD_D1, 0) > maxDDDay) 183 | { 184 | MaxDD = CurrentDD; 185 | MaxDDp = CurrentDDp; 186 | maxDDDay = iTime(Symbol(), PERIOD_D1, 0); 187 | 188 | // Save to Global 189 | setGlobalVar("TRADEINFO_MAXDD", MaxDD); 190 | setGlobalVar("TRADEINFO_MAXDDP", MaxDDp); 191 | setGlobalVar("TRADEINFO_DD_DAY", maxDDDay); 192 | } 193 | 194 | } 195 | } 196 | 197 | //+------------------------------------------------------------------+ 198 | double ND(double value, int decimal = -1) { 199 | //+------------------------------------------------------------------+ 200 | if (decimal == -1) 201 | decimal = Digits(); 202 | 203 | return (NormalizeDouble(value, decimal)); 204 | } 205 | 206 | //+------------------------------------------------------------------+ 207 | string CutAt(string& str, string sep) { 208 | //+------------------------------------------------------------------+ 209 | string res = ""; 210 | 211 | int index = StringFind(str, sep, 0); 212 | if (index != -1) 213 | { 214 | if (index > 0) res = StringSubstr(str, 0, index); 215 | str = StringSubstr(str, index + StringLen(sep)); 216 | } else { 217 | res = str; 218 | str = ""; 219 | } 220 | return(res); 221 | } 222 | 223 | //+------------------------------------------------------------------+ 224 | color levelColors[10] = {Lime, SpringGreen, SpringGreen, LawnGreen, Gold, Gold, DarkSalmon, Tomato, Tomato, FireBrick}; 225 | //+------------------------------------------------------------------+ 226 | 227 | //+------------------------------------------------------------------+ 228 | void DrawRiskInfo() { 229 | //+------------------------------------------------------------------+ 230 | SetPipMultiplier(Symbol()); 231 | 232 | if (RiskStopLoss > 0) 233 | DrawText(1, 0, 0, "Order Risk (SL=" + RiskStopLoss + ")", WhiteMode?Black:White, FontSize); 234 | else 235 | DrawText(1, 0, 0, "Order Risk", WhiteMode?Black:White, FontSize); 236 | 237 | DrawText(1, 1, 0, "-------------------", WhiteMode?Black:White, FontSize); 238 | 239 | string levels = RiskLevels; 240 | int i = 0; 241 | 242 | while (StringLen(levels) > 0) 243 | { 244 | string c = StringTrimLeft(StringTrimRight(CutAt(levels, ","))); 245 | double value = StringToDouble(c); 246 | 247 | if (value != EMPTY_VALUE) { 248 | 249 | color clr = levelColors[ArraySize(levelColors) - 1]; 250 | if ( i < ArraySize(levelColors)) 251 | clr = levelColors[i]; 252 | 253 | DrawText(1, i + 2, 0, StringConcatenate(value, "%: ", DTS(MM(value), 2) + " lot"), clr, FontSize); 254 | i++; 255 | 256 | } 257 | } 258 | } 259 | 260 | //+------------------------------------------------------------------+ 261 | void DrawAccountInfo() { 262 | //+------------------------------------------------------------------+ 263 | SetPipMultiplier(Symbol()); 264 | 265 | int row = 1; 266 | string text; 267 | int colWidth1 = 200; 268 | color c = WhiteMode?DarkBlue:LightCyan; 269 | text = StringConcatenate("Balance: ", MTS(AccountBalance())); 270 | DrawText(0, row, 0, text, c, FontSize); 271 | 272 | double eqPercent = 0; 273 | if (AccountBalance() > 0) 274 | eqPercent = MathDiv(AccountEquity(), AccountBalance() * 100.0); 275 | 276 | text = StringConcatenate("Equity: ", MTS(AccountEquity()), " (", DTS(eqPercent, 2), "%)"); 277 | DrawText(0, row, colWidth1, text, c, FontSize); 278 | row++; 279 | double marginLevel = 0; 280 | 281 | if (AccountMargin() > 0) marginLevel = MathDiv(AccountEquity(), AccountMargin() * 100.0); 282 | text = StringConcatenate("Margin: ", DTS(AccountMargin(), 2), " (", DTS(marginLevel, 2), "%)"); 283 | DrawText(0, row, 0, text, c, FontSize); 284 | 285 | if (AccountFreeMargin() < 0) 286 | c = Red; 287 | text = StringConcatenate("Free margin: ", DTS(AccountFreeMargin(), 2)); 288 | DrawText(0, row, colWidth1, text, c, FontSize); 289 | row++; 290 | c = WhiteMode?DarkBlue:LightCyan; 291 | 292 | text = StringConcatenate("Leverage: 1:", AccountLeverage()); 293 | DrawText(0, row, 0, text, c, FontSize); 294 | 295 | text = StringConcatenate("Swap Long: ", MTS(MarketInfo(Symbol(), MODE_SWAPLONG), 2), " Short: ", MTS(MarketInfo(Symbol(), MODE_SWAPSHORT), 2)); 296 | DrawText(0, row, colWidth1, text, c, FontSize); 297 | row++; 298 | 299 | DrawText(0, row, 0, "------------------------------------------------------------------", Gray, FontSize); 300 | } 301 | 302 | //+------------------------------------------------------------------+ 303 | bool IsValidOrder() { 304 | //+------------------------------------------------------------------+ 305 | if (!OnlyAttachedSymbol || OrderSymbol() == Symbol()) 306 | if ( MagicNumber == -1 || MagicNumber == OrderMagicNumber() ) 307 | if (CommentFilter == "" || StringFind(OrderComment(), CommentFilter) != -1) 308 | return(true); 309 | 310 | return(false); 311 | } 312 | 313 | //+------------------------------------------------------------------+ 314 | void DrawCurrentTrades() { 315 | //+------------------------------------------------------------------+ 316 | int buyCount, sellCount = 0; 317 | double buyProfit, sellProfit, buyLot, sellLot, buyPip, sellPip = 0; 318 | double slPip, tpPip; 319 | double allTPPips, allSLPips = 0; 320 | double maxLoss, maxProfit = 0; 321 | color c = White; 322 | string text = ""; 323 | int colWidth1 = 200; 324 | 325 | for (int i = OrdersTotal() - 1; i >= 0; i--) 326 | if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 327 | if ( IsValidOrder() ) 328 | { 329 | slPip = 0; 330 | tpPip = 0; 331 | if (OrderType() == OP_BUY) { 332 | buyCount++; 333 | buyProfit += OrderProfit() + OrderSwap() + OrderCommission(); 334 | buyLot += OrderLots(); 335 | buyPip += point2pip(MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice(), OrderSymbol()); 336 | 337 | if (OrderStopLoss() > 0.0) slPip = point2pip(OrderOpenPrice() - OrderStopLoss(), OrderSymbol()); 338 | if (OrderTakeProfit() > 0.0) tpPip = point2pip(OrderTakeProfit() - OrderOpenPrice(), OrderSymbol()); 339 | 340 | } else if (OrderType() == OP_SELL) { 341 | sellCount++; 342 | sellProfit += OrderProfit() + OrderSwap() + OrderCommission(); 343 | sellLot += OrderLots(); 344 | sellPip += point2pip(OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_BID), OrderSymbol()); 345 | 346 | if (OrderStopLoss() > 0.0) slPip = point2pip(OrderStopLoss() - OrderOpenPrice(), OrderSymbol()); 347 | if (OrderTakeProfit() > 0.0) tpPip = point2pip(OrderOpenPrice() - OrderTakeProfit(), OrderSymbol()); 348 | } 349 | if (slPip != 0) { 350 | maxLoss -= pip2money(slPip, OrderLots(), OrderSymbol()); 351 | allSLPips -= slPip; 352 | } 353 | 354 | if (tpPip != 0) { 355 | maxProfit += pip2money(tpPip, OrderLots(), OrderSymbol()) + OrderSwap() + OrderCommission(); 356 | allTPPips += tpPip; 357 | } 358 | 359 | } 360 | 361 | SetPipMultiplier(Symbol()); 362 | 363 | int row = 5; 364 | 365 | //Spread 366 | double spread = MathDiv(MarketInfo(Symbol(), MODE_SPREAD), pip_multiplier); 367 | if (spread < 3) c = WhiteMode?DarkGreen:LawnGreen; else c = Crimson; 368 | text = StringConcatenate("Spread: ", DTS(spread, 2)); 369 | DrawText(0, row, 0, text, c, FontSize); 370 | 371 | //Drawdown 372 | if (CurrentDD < 0) c = WhiteMode?Red:LightPink; else if (CurrentDD == 0.0) c = WhiteMode?Black:White; else c = WhiteMode?DarkGreen:LawnGreen; 373 | text = StringConcatenate("Current DD: ", DTS(CurrentDD, 2), " (" + DTS(CurrentDDp, 2), "%)"); 374 | DrawText(0, row, colWidth1, text, c, FontSize); 375 | row++; 376 | 377 | //Max daily Drawdown 378 | if (MaxDD < 0) c = WhiteMode?Red:LightPink; else if (MaxDD == 0.0) c = WhiteMode?Black:White; else c = WhiteMode?DarkGreen:LawnGreen; 379 | text = StringConcatenate("Daily Max DD: ", DTS(MaxDD, 2), " (" + DTS(MaxDDp, 2), "%)"); 380 | DrawText(0, row, colWidth1, text, c, FontSize); 381 | row++; 382 | 383 | 384 | //Max loss + profit 385 | if (maxProfit < 0) c = FireBrick; else if (maxProfit > 0) c = WhiteMode?DarkGreen:LawnGreen; else c = WhiteMode?Black:White; 386 | text = StringConcatenate("Est. profit: ", MTS(maxProfit), " (", DTS(allTPPips, 1), " pips)"); 387 | DrawText(0, row, 0, text, c, FontSize); 388 | 389 | if (maxLoss < 0) c = Red; else if (maxLoss > 0) c = WhiteMode?DarkGreen:LawnGreen; else c = WhiteMode?Black:White; 390 | double maxLossp = 0; if (AccountBalance() > 0) maxLossp = MathDiv(maxLoss, AccountBalance() * 100); 391 | text = StringConcatenate("Max loss: ", MTS(maxLoss), " (", DTS(allSLPips, 1), " pips) (", DTS(maxLossp, 2), "%)"); 392 | DrawText(0, row, colWidth1, text, c, FontSize); 393 | row++; 394 | 395 | DrawText(0, row, 0, "------------------------------------------------------------------", Gray, FontSize); 396 | row++; 397 | 398 | //Order counts 399 | c = WhiteMode?DimGray:Gainsboro; 400 | text = StringConcatenate("Long: ", buyCount); 401 | DrawText(0, row, 0, text, c, FontSize); 402 | text = StringConcatenate("Short: ", sellCount); 403 | DrawText(0, row + 1, 0, text, c, FontSize); 404 | 405 | DrawText(0, row + 2, 0, "------------------------------------------------------------------", Gray, FontSize); 406 | text = StringConcatenate("Total: ", buyCount + sellCount); 407 | DrawText(0, row + 3, 0, text, c, FontSize); 408 | 409 | // Order lots 410 | text = StringConcatenate("LOT: ", DTS(buyLot, 2)); 411 | DrawText(0, row, 65, text, c, FontSize); 412 | text = StringConcatenate("LOT: ", DTS(sellLot, 2)); 413 | DrawText(0, row + 1, 65, text, c, FontSize); 414 | text = StringConcatenate("LOT: ", DTS(buyLot + sellLot, 2)); 415 | DrawText(0, row + 3, 65, text, c, FontSize); 416 | 417 | // Order profits 418 | if (buyProfit < 0) c = Crimson; else if (buyProfit == 0.0) c = WhiteMode?DimGray:Gainsboro; else c = WhiteMode?DarkGreen:LawnGreen; 419 | text = StringConcatenate("Profit: ", MTS(buyProfit), " (", DTS(buyPip, 1), " pips)"); 420 | DrawText(0, row, colWidth1, text, c, FontSize); 421 | 422 | 423 | if (sellProfit < 0) c = Crimson; else if (sellProfit == 0.0) c = WhiteMode?DimGray:Gainsboro; else c = WhiteMode?DarkGreen:LawnGreen; 424 | text = StringConcatenate("Profit: ", MTS(sellProfit), " (", DTS(sellPip, 1), " pips)"); 425 | DrawText(0, row + 1, colWidth1, text, c, FontSize); 426 | 427 | if (buyProfit + sellProfit < 0) c = Crimson; else if (buyProfit + sellProfit == 0.0) c = WhiteMode?DimGray:Gainsboro; else c = WhiteMode?DarkGreen:LawnGreen; 428 | text = StringConcatenate("Profit: ", MTS(buyProfit + sellProfit), " (", DTS(buyPip + sellPip, 1), " pips)"); 429 | DrawText(0, row + 3, colWidth1, text, c, FontSize); 430 | } 431 | 432 | //+------------------------------------------------------------------+ 433 | void DrawProfitHistory() { 434 | //+------------------------------------------------------------------+ 435 | if (LastDrawProfitInfo > TimeCurrent() - 10) return; 436 | LastDrawProfitInfo = TimeCurrent(); 437 | 438 | datetime day, today, now, prevDay; 439 | 440 | int xOffset = 150; 441 | if (!ShowRiskInfo) xOffset = 5; 442 | 443 | DrawText(1, 0, xOffset + 260, "DATE", Gray, FontSize); 444 | DrawText(1, 0, xOffset + 210, "PIPS", Gray, FontSize); 445 | DrawText(1, 0, xOffset + 130, "PROFIT", Gray, FontSize); 446 | DrawText(1, 0, xOffset + 60, "GAIN %", Gray, FontSize); 447 | DrawText(1, 0, xOffset , "LOT", Gray, FontSize); 448 | DrawText(1, 1, xOffset , "====================================", Gray, FontSize); 449 | 450 | now = TimeCurrent(); 451 | today = StrToTime(TimeToStr(now, TIME_DATE)); 452 | 453 | DrawDayHistoryLine(xOffset, today, now, 2, "Today"); 454 | 455 | day = today; prevDay = GetPreviousDay(day - daySeconds); 456 | DrawDayHistoryLine(xOffset, prevDay, day, 3, "Yesterday"); 457 | 458 | day = prevDay; prevDay = GetPreviousDay(day - daySeconds); 459 | DrawDayHistoryLine(xOffset, prevDay, day, 4); 460 | 461 | day = prevDay; prevDay = GetPreviousDay(day - daySeconds); 462 | DrawDayHistoryLine(xOffset, prevDay, day, 5); 463 | 464 | day = prevDay; prevDay = GetPreviousDay(day - daySeconds); 465 | DrawDayHistoryLine(xOffset, prevDay, day, 6); 466 | 467 | day = DateOfMonday(); 468 | DrawDayHistoryLine(xOffset, day, now, 7, "Week"); 469 | 470 | day = StrToTime(Year()+"."+Month()+".01"); 471 | DrawDayHistoryLine(xOffset, day, now, 8, "Month"); 472 | 473 | day = StrToTime(Year()+".01.01"); 474 | DrawDayHistoryLine(xOffset, day, now, 9, "Year"); 475 | 476 | DrawText(1, 10, xOffset, "-------------------------------------------------------------------", Gray, FontSize); 477 | 478 | // Daily & Monthly profit 479 | if (AccountBalance() != 0.0) 480 | { 481 | double pips, profit, lots = 0; 482 | datetime firstOrderTime = GetHistoryInfoFromDate(day, now, pips, profit, lots); 483 | if (now - firstOrderTime != 0) 484 | { 485 | int oneDay = 86400; //int oneMonth = oneDay * 30.4; 486 | double daily = MathDiv(MathDiv(profit, MathDiv(now - firstOrderTime, oneDay)), (AccountBalance() - profit)) * 100.0; 487 | double monthly = daily * 30.4; 488 | 489 | DrawText(1, 11, xOffset, StringConcatenate("Monthly: ", DTS(monthly, 2), "%"), ColorOnSign(monthly), FontSize); 490 | DrawText(1, 11, xOffset + 150, StringConcatenate("Daily: ", DTS(daily, 2), "%"), ColorOnSign(daily), FontSize); 491 | } 492 | } 493 | 494 | DrawText(1, 12, xOffset, "====================================", Gray, FontSize); 495 | } 496 | 497 | //+------------------------------------------------------------------+ 498 | double MathDiv(double a, double b) { 499 | //+------------------------------------------------------------------+ 500 | if (b != 0.0) 501 | return(a/b); 502 | 503 | return(0.0); 504 | } 505 | 506 | //+------------------------------------------------------------------+ 507 | void DrawDayHistoryLine(int xOffset, datetime prevDay, datetime day, int row, string header = "") { 508 | //+------------------------------------------------------------------+ 509 | if (header == "") header = TimeToStr(prevDay, TIME_DATE); 510 | 511 | double pips, profit, percent, lots = 0.0; 512 | string text; 513 | 514 | GetHistoryInfoFromDate(prevDay, day, pips, profit, lots); 515 | double profitp = 0; 516 | if (AccountBalance() > 0) profitp = MathDiv(profit, (AccountBalance() - profit)) * 100.0; 517 | 518 | text = StringConcatenate(header, ": "); 519 | DrawText(1, row, xOffset + 260, text, WhiteMode?DimGray:Gray, FontSize); 520 | 521 | text = DTS(pips, 1); 522 | DrawText(1, row, xOffset + 210, text, ColorOnSign(pips), FontSize); 523 | 524 | text = MTS(profit); 525 | DrawText(1, row, xOffset + 120, text, ColorOnSign(profit), FontSize); 526 | 527 | text = StringConcatenate(DTS(profitp, 2), "%"); 528 | DrawText(1, row, xOffset + 60, text, ColorOnSign(profitp), FontSize); 529 | 530 | text = DTS(lots, 2); 531 | DrawText(1, row, xOffset, text, ColorOnSign(profit), FontSize); 532 | } 533 | 534 | //+------------------------------------------------------------------+ 535 | void DrawTodayRange() { 536 | //+------------------------------------------------------------------+ 537 | string text; 538 | 539 | SetPipMultiplier(Symbol()); 540 | 541 | double todayPips = point2pip(iHigh(NULL, PERIOD_D1, 0) - iLow(NULL, PERIOD_D1, 0)); 542 | double yesterdayPips = point2pip(iHigh(NULL, PERIOD_D1, 1) - iLow(NULL, PERIOD_D1, 1)); 543 | 544 | double thisWeekPips = point2pip(iHigh(NULL, PERIOD_W1, 0) - iLow(NULL, PERIOD_W1, 0)); 545 | double lastWeekPips = point2pip(iHigh(NULL, PERIOD_W1, 1) - iLow(NULL, PERIOD_W1, 1)); 546 | 547 | double thisMonthPips = point2pip(iHigh(NULL, PERIOD_MN1, 0) - iLow(NULL, PERIOD_MN1, 0)); 548 | double lastMonthPips = point2pip(iHigh(NULL, PERIOD_MN1, 1) - iLow(NULL, PERIOD_MN1, 1)); 549 | 550 | int colWidth2 = 500; 551 | int colWidth3 = 620; 552 | int row = 1; 553 | color c = C'141,176,241'; 554 | DrawText(0, row, colWidth2, "Today range:", c, FontSize); DrawText(0, row, colWidth3, StringConcatenate(DTS(todayPips, 1), " pips"), c, FontSize); 555 | DrawText(0, row + 1, colWidth2, "Yesterday range:", c, FontSize); DrawText(0, row + 1, colWidth3, StringConcatenate(DTS(yesterdayPips, 1), " pips"), c, FontSize); 556 | row += 3; 557 | 558 | c = C'103,150,237'; 559 | DrawText(0, row, colWidth2, "This week range:", c, FontSize); DrawText(0, row, colWidth3, StringConcatenate(DTS(thisWeekPips, 1), " pips"), c, FontSize); 560 | DrawText(0, row + 1, colWidth2, "Last week range:", c, FontSize); DrawText(0, row + 1, colWidth3, StringConcatenate(DTS(lastWeekPips, 1), " pips"), c, FontSize); 561 | row += 3; 562 | 563 | c = C'65,123,233'; 564 | DrawText(0, row, colWidth2, "This month range:", c, FontSize); DrawText(0, row, colWidth3, StringConcatenate(DTS(thisMonthPips, 1), " pips"), c, FontSize); 565 | DrawText(0, row + 1, colWidth2, "Last month range:", c, FontSize); DrawText(0, row + 1, colWidth3, StringConcatenate(DTS(lastMonthPips, 1), " pips"), c, FontSize); 566 | row += 3; 567 | 568 | 569 | datetime nextCandleTime = (Period() * 60) - (TimeCurrent() - iTime(NULL, 0, 0)); 570 | 571 | c = WhiteMode?Orange:Bisque; 572 | DrawText(0, row, colWidth2, "Next candle:", c, FontSize); DrawText(0, row, colWidth3, TimeToStr(nextCandleTime, TIME_SECONDS), c, FontSize); 573 | } 574 | 575 | //+------------------------------------------------------------------+ 576 | void DrawCopyright() { 577 | //+------------------------------------------------------------------+ 578 | string text = StringConcatenate(IndiName, " - Created by Ice FX - www.icefx.eu"); 579 | DrawText(3, 0, 0, text, DimGray, 7); 580 | } 581 | 582 | //+------------------------------------------------------------------+ 583 | datetime GetHistoryInfoFromDate(datetime prevDay, datetime day, double &pips, double &profit, double &lots) { 584 | //+------------------------------------------------------------------+ 585 | datetime res = day; 586 | int i, k = OrdersHistoryTotal(); 587 | pips = 0; 588 | profit = 0; 589 | lots = 0; 590 | 591 | for (i = 0; i < k; i++) { 592 | if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { 593 | if ( IsValidOrder() ) { 594 | if (OrderType()==OP_BUY || OrderType()==OP_SELL) { 595 | if (day >= OrderCloseTime() && OrderCloseTime() >= prevDay && OrderCloseTime() > startDateFilter) { 596 | profit += OrderProfit() + OrderCommission() + OrderSwap(); 597 | 598 | if (OrderType() == OP_BUY) { 599 | pips += point2pip(OrderClosePrice() - OrderOpenPrice(), OrderSymbol()); 600 | } 601 | if (OrderType() == OP_SELL) { 602 | pips += point2pip(OrderOpenPrice() - OrderClosePrice(), OrderSymbol()); 603 | } 604 | lots += OrderLots(); 605 | 606 | if (OrderCloseTime() < res) res = OrderCloseTime(); 607 | } 608 | } 609 | } 610 | } 611 | } 612 | return(res); 613 | } 614 | 615 | //+------------------------------------------------------------------+ 616 | datetime GetPreviousDay(datetime curDay) { 617 | //+------------------------------------------------------------------+ 618 | datetime prevDay = curDay; 619 | 620 | while (TimeDayOfWeek(prevDay) < 1 || TimeDayOfWeek(prevDay) > 5) prevDay -= daySeconds; 621 | return(prevDay); 622 | } 623 | 624 | //+------------------------------------------------------------------+ 625 | datetime DateOfMonday(int no = 0) { 626 | //+------------------------------------------------------------------+ 627 | datetime dt = StrToTime(TimeToStr(TimeCurrent(), TIME_DATE)); 628 | 629 | while (TimeDayOfWeek(dt) != 1) dt -= daySeconds; 630 | dt += no * 7 * daySeconds; 631 | 632 | return(dt); 633 | } 634 | 635 | color ColorOnSign(double value) { 636 | color lcColor = WhiteMode?DimGray:Gray; 637 | 638 | if (value > 0) lcColor = WhiteMode?DarkGreen:Green; 639 | if (value < 0) lcColor = FireBrick; 640 | 641 | return(lcColor); 642 | } 643 | 644 | //+------------------------------------------------------------------+ 645 | double MM(double Risk) { 646 | //+------------------------------------------------------------------+ 647 | double SL = RiskStopLoss; 648 | double NewLOT = 0; 649 | 650 | string Symb = Symbol(); // Symb default value 651 | double One_Lot = MarketInfo(Symb,MODE_MARGINREQUIRED); // margin for 1 LOT 652 | double Min_Lot = MarketInfo(Symb,MODE_MINLOT); // Minimum LOT 653 | double Max_Lot = MarketInfo(Symb,MODE_MAXLOT); // Maximum LOT 654 | double Step = MarketInfo(Symb,MODE_LOTSTEP); // Lot step 655 | double Free = AccountFreeMargin(); // Free margin 656 | //------------------------------------------------------------------------------- 657 | if (SL > 0) // If set StopLoss 658 | { 659 | double RiskAmount = AccountEquity() * (Risk / 100); // Calc risk in money 660 | double tickValue = MarketInfo(Symb, MODE_TICKVALUE) * pip_multiplier; // Get how many pips 1 unit price 661 | 662 | if (tickValue * SL != 0) NewLOT = RiskAmount / (tickValue * SL); // Divide Risk price with SL price 663 | if (Step > 0) NewLOT = MathFloor(NewLOT / Step) * Step; //Round // Round LOT to step 664 | } 665 | //------------------------------------------------------------------------------- 666 | else // Dynamic LOT calculation 667 | { 668 | if (Risk > 100) // If greater then 100 669 | Risk = 100; // then 100% 670 | if (Risk == 0) // If 0 671 | NewLOT = Min_Lot; // then minimal LOT 672 | else 673 | if (Step > 0 && One_Lot > 0) 674 | NewLOT = MathFloor(Free * Risk / 100 / One_Lot / Step) * Step; // Calc by Risk and round to step 675 | } 676 | //------------------------------------------------------------------------------- 677 | if (NewLOT < Min_Lot) // If smaller than minimum 678 | NewLOT = Min_Lot; // set to minimum LOT 679 | if (NewLOT > Max_Lot) // If greater than maximum 680 | NewLOT = Max_Lot; // set to maximum LOT 681 | //------------------------------------------------------------------------------- 682 | double margin = NewLOT * One_Lot; // Calc the required margin for LOT 683 | if (margin > AccountFreeMargin()) // If greater than the free 684 | { // Message, alert, ...etczenet, alert....stb. 685 | //string msg = "You have not enough money! Free margin: " + DTS(AccountFreeMargin(), 2) + ", Require: " + DTS(margin, 2); 686 | //Log.Warning(msg); 687 | //Print(msg); 688 | //Alert(msg); 689 | return(0); // Return with 0. Skip the order open 690 | } 691 | return(NewLOT); 692 | } 693 | 694 | //+------------------------------------------------------------------+ 695 | void setCurrency() { 696 | //+------------------------------------------------------------------+ 697 | string currSign = AccountCurrency(); 698 | if (currSign == "USD") { 699 | preCurrSign = "$"; 700 | postCurrSign = postCurrSign; 701 | } else if (currSign == "EUR") { 702 | preCurrSign = "€"; 703 | postCurrSign = postCurrSign; 704 | } else { 705 | preCurrSign = ""; 706 | postCurrSign = postCurrSign; 707 | } 708 | } 709 | 710 | //+------------------------------------------------------------------+ 711 | string MTS(double value, int decimal = 2) { 712 | //+------------------------------------------------------------------+ 713 | return(StringConcatenate(preCurrSign, DTS(value, decimal), postCurrSign)); 714 | } 715 | 716 | //+------------------------------------------------------------------+ 717 | string DTS(double value, int decimal = 0) { return(DoubleToStr(value, decimal)); } 718 | //+------------------------------------------------------------------+ 719 | 720 | //+------------------------------------------------------------------+ 721 | double point2pip(double point, string Symb = "") { 722 | //+------------------------------------------------------------------+ 723 | if (Symb == "") Symb = Symbol(); 724 | 725 | SetPipMultiplier(Symb); 726 | 727 | return(MathDiv(MathDiv(point, MarketInfo(Symb, MODE_POINT)), pip_multiplier)); 728 | } 729 | 730 | //+------------------------------------------------------------------+ 731 | double pip2money(double pip, double lot, string Symb) { 732 | //+------------------------------------------------------------------+ 733 | if (Symb == "") Symb = Symbol(); 734 | 735 | SetPipMultiplier(Symb); 736 | 737 | double tickSize = MarketInfo(Symb, MODE_TICKSIZE); 738 | if (tickSize != 0) 739 | { 740 | double onePipValue = MarketInfo(Symb, MODE_TICKVALUE) * (MarketInfo(Symb, MODE_POINT) / tickSize); 741 | return((pip * pip_multiplier) * onePipValue * lot); 742 | } else return(0); 743 | } 744 | 745 | //+------------------------------------------------------------------+ 746 | double SetPipMultiplier(string Symb, bool simple = false) { 747 | //+------------------------------------------------------------------+ 748 | pip_multiplier = 1; 749 | int digit = MarketInfo(Symb, MODE_DIGITS); 750 | 751 | if (simple) 752 | { 753 | if (digit % 4 != 0) pip_multiplier = 10; 754 | 755 | } else { 756 | if (digit == 5 || 757 | (digit == 3 && StringFind(Symb, "JPY") > -1) || // If 3 digits and currency is JPY 758 | (digit == 2 && StringFind(Symb, "XAU") > -1) || // If 2 digits and currency is gold 759 | (digit == 2 && StringFind(Symb, "GOLD") > -1) || // If 2 digits and currency is gold 760 | (digit == 3 && StringFind(Symb, "XAG") > -1) || // If 3 digits and currency is silver 761 | (digit == 3 && StringFind(Symb, "SILVER") > -1) || // If 3 digits and currency is silver 762 | (digit == 1)) // If 1 digit (CFDs) 763 | pip_multiplier = 10; 764 | else if (digit == 6 || 765 | (digit == 4 && StringFind(Symb, "JPY") > -1) || // If 4 digits and currency is JPY 766 | (digit == 3 && StringFind(Symb, "XAU") > -1) || // If 3 digits and currency is gold 767 | (digit == 3 && StringFind(Symb, "GOLD") > -1) || // If 3 digits and currency is gold 768 | (digit == 4 && StringFind(Symb, "XAG") > -1) || // If 4 digits and currency is silver 769 | (digit == 4 && StringFind(Symb, "SILVER") > -1) || // If 4 digits and currency is silver 770 | (digit == 2)) // If 2 digit (CFDs) 771 | pip_multiplier = 100; 772 | } 773 | //Print("PipMultiplier: ", pip_multiplier, ", Digits: ", Digits); 774 | return(pip_multiplier); 775 | } 776 | 777 | //+------------------------------------------------------------------+ 778 | void DrawText(int corner, int row, int xOffset, string text, color c, int size = 7) { 779 | //+------------------------------------------------------------------+ 780 | string objName = "TradeInfo_" + DTS(corner) + "_" + DTS(xOffset) + "_" + DTS(row); 781 | if (ObjectFind(objName) != 0) { 782 | ObjectCreate(objName, OBJ_LABEL, windowIndex, 0, 0); 783 | ObjectSet(objName, OBJPROP_CORNER, corner); 784 | ObjectSet(objName, OBJPROP_SELECTABLE, 0); 785 | ObjectSet(objName, OBJPROP_HIDDEN, 1); 786 | } 787 | 788 | ObjectSetText(objName, text, size, "Verdana", c); 789 | ObjectSet(objName, OBJPROP_XDISTANCE, 6 + xOffset); 790 | ObjectSet(objName, OBJPROP_YDISTANCE, 6 + row * (size + 6)); 791 | ObjectSet(objName, OBJPROP_BACK, false); 792 | } 793 | 794 | //+------------------------------------------------------------------+ 795 | double getGlobalVar(string name, double defaultValue = EMPTY_VALUE) { 796 | //+------------------------------------------------------------------+ 797 | if (GlobalVariableCheck(name)) 798 | return (GlobalVariableGet(name)); 799 | else 800 | return (defaultValue); 801 | } 802 | 803 | //+------------------------------------------------------------------+ 804 | string setGlobalVar(string name, double value = EMPTY_VALUE) { 805 | //+------------------------------------------------------------------+ 806 | if (value == EMPTY_VALUE) 807 | GlobalVariableDel(name); 808 | else 809 | GlobalVariableSet(name, value); 810 | 811 | return(name); 812 | } 813 | 814 | //+------------------------------------------------------------------+ 815 | void DeleteAllObject() { 816 | //+------------------------------------------------------------------+ 817 | for(int i = ObjectsTotal() - 1; i >= 0; i--) 818 | if(StringFind(ObjectName(i), "TradeInfo_", 0) >= 0) 819 | ObjectDelete(ObjectName(i)); 820 | 821 | } 822 | 823 | --------------------------------------------------------------------------------